diff --git a/backtester/engine/backtest_test.go b/backtester/engine/backtest_test.go index 5a0f8c9f18e..a8ba5b193da 100644 --- a/backtester/engine/backtest_test.go +++ b/backtester/engine/backtest_test.go @@ -418,7 +418,7 @@ func TestReset(t *testing.T) { func TestFullCycle(t *testing.T) { t.Parallel() - ex := testExchange + e := testExchange cp := currency.NewBTCUSDT() a := asset.Spot tt := time.Now() @@ -431,7 +431,7 @@ func TestFullCycle(t *testing.T) { }, &risk.Risk{}, decimal.Zero) assert.NoError(t, err) - fx := &binance.Binance{} + fx := &binance.Exchange{} fx.Name = testExchange err = port.SetCurrencySettingsMap(&exchange.Settings{Exchange: fx, Asset: a, Pair: cp}) assert.NoError(t, err) @@ -439,10 +439,10 @@ func TestFullCycle(t *testing.T) { f, err := funding.SetupFundingManager(&engine.ExchangeManager{}, false, true, false) assert.NoError(t, err) - b, err := funding.CreateItem(ex, a, cp.Base, decimal.Zero, decimal.Zero) + b, err := funding.CreateItem(e, a, cp.Base, decimal.Zero, decimal.Zero) assert.NoError(t, err) - quote, err := funding.CreateItem(ex, a, cp.Quote, decimal.NewFromInt(1337), decimal.Zero) + quote, err := funding.CreateItem(e, a, cp.Quote, decimal.NewFromInt(1337), decimal.Zero) assert.NoError(t, err) pair, err := funding.CreatePair(b, quote) @@ -467,7 +467,7 @@ func TestFullCycle(t *testing.T) { bt.DataHolder = data.NewHandlerHolder() k := &kline.DataFromKline{ Item: &gctkline.Item{ - Exchange: ex, + Exchange: e, Pair: cp, Asset: a, Interval: gctkline.FifteenMin, @@ -502,7 +502,7 @@ func TestFullCycle(t *testing.T) { err = k.Load() assert.NoError(t, err) - err = bt.DataHolder.SetDataForCurrency(ex, a, cp, k) + err = bt.DataHolder.SetDataForCurrency(e, a, cp, k) assert.NoError(t, err) bt.MetaData.DateLoaded = time.Now() @@ -536,7 +536,7 @@ func TestStop(t *testing.T) { func TestFullCycleMulti(t *testing.T) { t.Parallel() - ex := testExchange + e := testExchange cp := currency.NewBTCUSDT() a := asset.Spot tt := time.Now() @@ -550,16 +550,16 @@ func TestFullCycleMulti(t *testing.T) { }, &risk.Risk{}, decimal.Zero) assert.NoError(t, err) - err = port.SetCurrencySettingsMap(&exchange.Settings{Exchange: &binance.Binance{}, Asset: a, Pair: cp}) + err = port.SetCurrencySettingsMap(&exchange.Settings{Exchange: &binance.Exchange{}, Asset: a, Pair: cp}) assert.NoError(t, err) f, err := funding.SetupFundingManager(&engine.ExchangeManager{}, false, true, false) assert.NoError(t, err) - b, err := funding.CreateItem(ex, a, cp.Base, decimal.Zero, decimal.Zero) + b, err := funding.CreateItem(e, a, cp.Base, decimal.Zero, decimal.Zero) assert.NoError(t, err) - quote, err := funding.CreateItem(ex, a, cp.Quote, decimal.NewFromInt(1337), decimal.Zero) + quote, err := funding.CreateItem(e, a, cp.Quote, decimal.NewFromInt(1337), decimal.Zero) assert.NoError(t, err) pair, err := funding.CreatePair(b, quote) @@ -586,7 +586,7 @@ func TestFullCycleMulti(t *testing.T) { bt.DataHolder = data.NewHandlerHolder() k := &kline.DataFromKline{ Item: &gctkline.Item{ - Exchange: ex, + Exchange: e, Pair: cp, Asset: a, Interval: gctkline.FifteenMin, @@ -621,7 +621,7 @@ func TestFullCycleMulti(t *testing.T) { err = k.Load() assert.NoError(t, err) - err = bt.DataHolder.SetDataForCurrency(ex, a, cp, k) + err = bt.DataHolder.SetDataForCurrency(e, a, cp, k) assert.NoError(t, err) err = bt.Run() @@ -762,7 +762,7 @@ func TestUpdateStatsForDataEvent(t *testing.T) { require.NoError(t, err, "CreateCollateral must not error") bt.Funding = f - exch := &binance.Binance{} + exch := &binance.Exchange{} exch.Name = testExchange ev.Time = time.Now() fl := &fill.Fill{ @@ -831,7 +831,7 @@ func TestProcessSignalEvent(t *testing.T) { require.NoError(t, err, "CreateCollateral must not error") bt.Funding = f - exch := &binance.Binance{} + exch := &binance.Exchange{} exch.Name = testExchange bt.Exchange.SetExchangeAssetCurrencySettings(a, cp, &exchange.Settings{ Exchange: exch, @@ -889,7 +889,7 @@ func TestProcessOrderEvent(t *testing.T) { require.NoError(t, err, "CreateCollateral must not error") bt.Funding = f - exch := &binance.Binance{} + exch := &binance.Exchange{} exch.Name = testExchange err = pt.SetCurrencySettingsMap(&exchange.Settings{ Exchange: exch, @@ -1204,7 +1204,7 @@ func TestCloseAllPositions(t *testing.T) { dc.funding = bt.Funding cp := currency.NewBTCUSD() dc.sourcesToCheck = append(dc.sourcesToCheck, &liveDataSourceDataHandler{ - exchange: &binance.Binance{}, + exchange: &binance.Exchange{}, exchangeName: testExchange, asset: asset.Spot, pair: cp, @@ -1285,7 +1285,7 @@ func TestRunLive(t *testing.T) { } // AppendDataSource(exchange gctexchange.IBotExchange, interval gctkline.Interval, asset asset.Asset, pair, underlyingPair currency.Pair, dataType int64) error setup := &liveDataSourceSetup{ - exchange: &binance.Binance{}, + exchange: &binance.Exchange{}, interval: i.Interval, asset: i.Asset, pair: i.Pair, @@ -1373,7 +1373,7 @@ func TestSetExchangeCredentials(t *testing.T) { assert.ErrorIs(t, err, gctcommon.ErrNilPointer) cfg := &config.Config{} - f := &binanceus.Binanceus{} + f := &binanceus.Exchange{} f.SetDefaults() b := f.GetBase() err = setExchangeCredentials(cfg, b) @@ -1416,7 +1416,7 @@ func TestGetFees(t *testing.T) { _, _, err := getFees(t.Context(), nil, currency.EMPTYPAIR) assert.ErrorIs(t, err, gctcommon.ErrNilPointer) - f := &binance.Binance{} + f := &binance.Exchange{} f.SetDefaults() _, _, err = getFees(t.Context(), f, currency.EMPTYPAIR) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) diff --git a/backtester/engine/live_test.go b/backtester/engine/live_test.go index 7de05d258e3..2a3f54c6547 100644 --- a/backtester/engine/live_test.go +++ b/backtester/engine/live_test.go @@ -219,7 +219,7 @@ func TestAppendDataSource(t *testing.T) { err = dataHandler.AppendDataSource(setup) assert.ErrorIs(t, err, gctcommon.ErrNilPointer) - setup.exchange = &binance.Binance{} + setup.exchange = &binance.Exchange{} err = dataHandler.AppendDataSource(setup) assert.ErrorIs(t, err, common.ErrInvalidDataType) @@ -264,7 +264,7 @@ func TestFetchLatestData(t *testing.T) { _, err = dataHandler.FetchLatestData() require.NoError(t, err) cp := currency.NewBTCUSDT() - f := &binanceus.Binanceus{} + f := &binanceus.Exchange{} f.SetDefaults() fb := f.GetBase() require.NoError(t, fb.CurrencyPairs.SetAssetEnabled(asset.Spot, true), "SetAssetEnabled must not error") @@ -322,7 +322,7 @@ func TestLoadCandleData(t *testing.T) { _, err := l.loadCandleData(time.Now()) assert.ErrorIs(t, err, gctcommon.ErrNilPointer) - exch := &binanceus.Binanceus{} + exch := &binanceus.Exchange{} exch.SetDefaults() cp := currency.NewBTCUSDT().Format( currency.PairFormat{ @@ -367,7 +367,7 @@ func TestSetDataForClosingAllPositions(t *testing.T) { dataHandler.started = 1 cp := currency.NewBTCUSDT() - f := &binanceus.Binanceus{} + f := &binanceus.Exchange{} f.SetDefaults() fb := f.GetBase() err := fb.CurrencyPairs.StorePairs(asset.Spot, currency.Pairs{cp}, true) diff --git a/backtester/eventhandlers/exchange/exchange_test.go b/backtester/eventhandlers/exchange/exchange_test.go index f54d6419802..e3cf629883a 100644 --- a/backtester/eventhandlers/exchange/exchange_test.go +++ b/backtester/eventhandlers/exchange/exchange_test.go @@ -125,7 +125,7 @@ func TestSetCurrency(t *testing.T) { if len(e.CurrencySettings) != 0 { t.Error("expected 0") } - f := &binance.Binance{} + f := &binance.Exchange{} f.Name = testExchange cs := &Settings{ Exchange: f, @@ -240,7 +240,7 @@ func TestExecuteOrder(t *testing.T) { require.NoError(t, exchB.CurrencyPairs.SetAssetEnabled(a, true), "SetAssetEnabled must not error") _, err = exch.UpdateOrderbook(t.Context(), p, a) require.NoError(t, err, "UpdateOrderbook must not error") - f := &binanceus.Binanceus{} + f := &binanceus.Exchange{} f.Name = testExchange cs := Settings{ Exchange: f, @@ -359,7 +359,7 @@ func TestExecuteOrderBuySellSizeLimit(t *testing.T) { limits, err := exch.GetOrderExecutionLimits(a, p) require.NoError(t, err, "GetOrderExecutionLimits must not error") - f := &btcmarkets.BTCMarkets{} + f := &btcmarkets.Exchange{} f.Name = testExchange cs := Settings{ Exchange: f, diff --git a/backtester/eventhandlers/exchange/slippage/slippage_test.go b/backtester/eventhandlers/exchange/slippage/slippage_test.go index 179e0fee835..f250e8711f5 100644 --- a/backtester/eventhandlers/exchange/slippage/slippage_test.go +++ b/backtester/eventhandlers/exchange/slippage/slippage_test.go @@ -21,7 +21,7 @@ func TestRandomSlippage(t *testing.T) { func TestCalculateSlippageByOrderbook(t *testing.T) { t.Parallel() - b := bitstamp.Bitstamp{} + b := bitstamp.Exchange{} b.SetDefaults() cp := currency.NewBTCUSD() diff --git a/backtester/eventhandlers/portfolio/portfolio_test.go b/backtester/eventhandlers/portfolio/portfolio_test.go index c733641cf32..cf195e99bc6 100644 --- a/backtester/eventhandlers/portfolio/portfolio_test.go +++ b/backtester/eventhandlers/portfolio/portfolio_test.go @@ -79,7 +79,7 @@ func TestSetupCurrencySettingsMap(t *testing.T) { err = p.SetCurrencySettingsMap(&exchange.Settings{}) assert.ErrorIs(t, err, errExchangeUnset) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff}) assert.ErrorIs(t, err, errAssetUnset) @@ -103,7 +103,7 @@ func TestSetHoldings(t *testing.T) { err = p.SetHoldingsForTimestamp(&holdings.Holding{Timestamp: tt}) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -141,7 +141,7 @@ func TestGetLatestHoldingsForAllCurrencies(t *testing.T) { }) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -193,7 +193,7 @@ func TestViewHoldingAtTimePeriod(t *testing.T) { _, err := p.ViewHoldingAtTimePeriod(s) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -265,7 +265,7 @@ func TestUpdate(t *testing.T) { }) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -286,7 +286,7 @@ func TestGetComplianceManager(t *testing.T) { _, err := p.getComplianceManager("", asset.Empty, currency.EMPTYPAIR) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -311,7 +311,7 @@ func TestAddComplianceSnapshot(t *testing.T) { }) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -352,7 +352,7 @@ func TestOnFill(t *testing.T) { _, err = p.OnFill(f, nil) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSDT()}) assert.NoError(t, err) @@ -423,7 +423,7 @@ func TestOnSignal(t *testing.T) { _, err = p.OnSignal(s, &exchange.Settings{}, funds) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewBTCUSD()}) assert.NoError(t, err) @@ -572,7 +572,7 @@ func TestGetSnapshotAtTime(t *testing.T) { assert.ErrorIs(t, err, errNoPortfolioSettings) cp := currency.NewPair(currency.XRP, currency.DOGE) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: cp}) assert.NoError(t, err) @@ -628,7 +628,7 @@ func TestGetLatestSnapshot(t *testing.T) { assert.ErrorIs(t, err, errNoPortfolioSettings) cp := currency.NewPair(currency.XRP, currency.DOGE) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Spot, Pair: currency.NewPair(currency.XRP, currency.DOGE)}) assert.NoError(t, err) @@ -692,7 +692,7 @@ func TestCalculatePNL(t *testing.T) { err := p.UpdatePNL(ev, decimal.Zero) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset) - exch := &binance.Binance{} + exch := &binance.Exchange{} exch.Name = testExchange a := asset.Futures pair, err := currency.NewPairFromStrings("BTC", "1231") @@ -854,7 +854,7 @@ func TestTrackFuturesOrder(t *testing.T) { }, collat) assert.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = od.Exchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Futures, Pair: cp}) assert.ErrorIs(t, err, gctcommon.ErrNotYetImplemented) @@ -931,7 +931,7 @@ func TestGetPositions(t *testing.T) { AssetType: asset.Futures, }, } - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: ev.AssetType, Pair: ev.Pair()}) assert.ErrorIs(t, err, gctcommon.ErrNotYetImplemented) @@ -953,7 +953,7 @@ func TestGetLatestPNLForEvent(t *testing.T) { AssetType: asset.Futures, }, } - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: ev.AssetType, Pair: ev.Pair()}) assert.ErrorIs(t, err, gctcommon.ErrNotYetImplemented) @@ -1019,7 +1019,7 @@ func TestGetFuturesSettingsFromEvent(t *testing.T) { _, err = p.getFuturesSettingsFromEvent(ev) require.ErrorIs(t, err, errNoPortfolioSettings) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: ev.AssetType, Pair: ev.Pair()}) assert.ErrorIs(t, err, gctcommon.ErrNotYetImplemented) @@ -1230,7 +1230,7 @@ func TestCreateLiquidationOrdersForExchange(t *testing.T) { _, err = p.CreateLiquidationOrdersForExchange(ev, funds) require.NoError(t, err) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.Name = testExchange cp := currency.NewBTCUSDT() err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: ff, Asset: asset.Futures, Pair: cp}) @@ -1353,7 +1353,7 @@ func TestCheckLiquidationStatus(t *testing.T) { ev.AssetType = asset.Futures ev.Exchange = testExchange ev.CurrencyPair = pair - exch := &binance.Binance{} + exch := &binance.Exchange{} exch.Name = ev.Exchange err = p.SetCurrencySettingsMap(&exchange.Settings{Exchange: exch, Asset: asset.Futures, Pair: pair}) assert.ErrorIs(t, err, gctcommon.ErrNotYetImplemented) @@ -1426,7 +1426,7 @@ func TestSetHoldingsForEvent(t *testing.T) { Time: tt, }, } - f := &binance.Binance{} + f := &binance.Exchange{} f.SetDefaults() err = p.SetCurrencySettingsMap(&exchange.Settings{ Exchange: f, diff --git a/backtester/eventhandlers/portfolio/risk/risk.go b/backtester/eventhandlers/portfolio/risk/risk.go index fb6e71b3440..60a05622a5e 100644 --- a/backtester/eventhandlers/portfolio/risk/risk.go +++ b/backtester/eventhandlers/portfolio/risk/risk.go @@ -23,17 +23,17 @@ func (r *Risk) EvaluateOrder(o order.Event, latestHoldings []holdings.Holding, s if !ok { return nil, fmt.Errorf("%w expected order event", common.ErrInvalidDataType) } - ex := o.GetExchange() + e := o.GetExchange() a := o.GetAssetType() p := o.Pair().Format(currency.EMPTYFORMAT) lookup, ok := r.CurrencySettings[key.ExchangePairAsset{ - Exchange: ex, + Exchange: e, Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, }] if !ok { - return nil, fmt.Errorf("%v %v %v %w", ex, a, p, errNoCurrencySettings) + return nil, fmt.Errorf("%v %v %v %w", e, a, p, errNoCurrencySettings) } if o.IsLeveraged() { @@ -52,7 +52,7 @@ func (r *Risk) EvaluateOrder(o order.Event, latestHoldings []holdings.Holding, s if len(latestHoldings) > 1 { ratio := assessHoldingsRatio(o.Pair(), latestHoldings) if lookup.MaximumHoldingRatio.GreaterThan(decimal.Zero) && !ratio.Equal(decimal.NewFromInt(1)) && ratio.GreaterThan(lookup.MaximumHoldingRatio) { - return nil, fmt.Errorf("order would exceed maximum holding ratio of %v to %v for %v %v %v. %w", lookup.MaximumHoldingRatio, ratio, ex, a, p, errCannotPlaceLeverageOrder) + return nil, fmt.Errorf("order would exceed maximum holding ratio of %v to %v for %v %v %v. %w", lookup.MaximumHoldingRatio, ratio, e, a, p, errCannotPlaceLeverageOrder) } } return retOrder, nil diff --git a/backtester/eventhandlers/portfolio/size/size_test.go b/backtester/eventhandlers/portfolio/size/size_test.go index acdd5f28469..0877041708c 100644 --- a/backtester/eventhandlers/portfolio/size/size_test.go +++ b/backtester/eventhandlers/portfolio/size/size_test.go @@ -228,7 +228,7 @@ func TestSizeOrder(t *testing.T) { MatchesOrderAmount: true, ClosePrice: decimal.NewFromInt(1337), } - exch := binance.Binance{} + exch := binance.Exchange{} // TODO adjust when Binance futures wrappers are implemented cs.Exchange = &exch _, _, err = s.SizeOrder(o, decimal.NewFromInt(1337), cs) diff --git a/backtester/eventhandlers/statistics/statistics.go b/backtester/eventhandlers/statistics/statistics.go index f47d5434c56..76bd7108540 100644 --- a/backtester/eventhandlers/statistics/statistics.go +++ b/backtester/eventhandlers/statistics/statistics.go @@ -58,14 +58,14 @@ func (s *Statistic) SetEventForOffset(ev common.Event) error { if ev.GetBase() == nil { return fmt.Errorf("%w event base", common.ErrNilEvent) } - ex := ev.GetExchange() + e := ev.GetExchange() a := ev.GetAssetType() p := ev.Pair() if s.ExchangeAssetPairStatistics == nil { s.ExchangeAssetPairStatistics = make(map[key.ExchangePairAsset]*CurrencyPairStatistic) } mapKey := key.ExchangePairAsset{ - Exchange: ex, + Exchange: e, Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, @@ -73,7 +73,7 @@ func (s *Statistic) SetEventForOffset(ev common.Event) error { stats, ok := s.ExchangeAssetPairStatistics[mapKey] if !ok { stats = &CurrencyPairStatistic{ - Exchange: ex, + Exchange: e, Asset: a, Currency: p, UnderlyingPair: ev.GetUnderlyingPair(), diff --git a/backtester/funding/funding_test.go b/backtester/funding/funding_test.go index 9223fbcccd1..df62f655957 100644 --- a/backtester/funding/funding_test.go +++ b/backtester/funding/funding_test.go @@ -758,7 +758,7 @@ func TestUpdateFundingFromLiveData(t *testing.T) { err = f.UpdateFundingFromLiveData(false) assert.NoError(t, err) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.SetDefaults() err = f.exchangeManager.Add(ff) require.NoError(t, err) @@ -793,7 +793,7 @@ func TestUpdateAllCollateral(t *testing.T) { err = f.UpdateAllCollateral(false, false) assert.NoError(t, err) - ff := &binance.Binance{} + ff := &binance.Exchange{} ff.SetDefaults() err = f.exchangeManager.Add(ff) require.NoError(t, err) diff --git a/cmd/exchange_template/exchange_template.go b/cmd/exchange_template/exchange_template.go index 0a21c0c1b0b..c4d5de5cc37 100644 --- a/cmd/exchange_template/exchange_template.go +++ b/cmd/exchange_template/exchange_template.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "path/filepath" + "slices" "strings" "github.com/thrasher-corp/gocryptotrader/common" @@ -28,22 +29,19 @@ const ( type exchange struct { Name string CapitalName string - Variable string REST bool WS bool - FIX bool } var errInvalidExchangeName = errors.New("invalid exchange name") func main() { var newExchangeName string - var websocketSupport, restSupport, fixSupport bool + var websocketSupport, restSupport bool flag.StringVar(&newExchangeName, "name", "", "the exchange name") flag.BoolVar(&websocketSupport, "ws", false, "whether the exchange supports websocket") flag.BoolVar(&restSupport, "rest", false, "whether the exchange supports REST") - flag.BoolVar(&fixSupport, "fix", false, "whether the exchange supports FIX") flag.Parse() @@ -62,8 +60,8 @@ func main() { } newExchangeName = strings.ToLower(newExchangeName) - if !websocketSupport && !restSupport && !fixSupport { - log.Println("At least one protocol must be specified (rest/ws or fix)") + if !websocketSupport && !restSupport { + log.Println("At least one protocol must be specified (rest/ws)") flag.Usage() return } @@ -71,7 +69,6 @@ func main() { fmt.Println("Exchange Name: ", newExchangeName) fmt.Println("Websocket Supported: ", websocketSupport) fmt.Println("REST Supported: ", restSupport) - fmt.Println("FIX Supported: ", fixSupport) fmt.Println() fmt.Println("Please check if everything is correct and then type y to continue or n to cancel...") @@ -89,7 +86,6 @@ func main() { Name: newExchangeName, REST: restSupport, WS: websocketSupport, - FIX: fixSupport, } exchangeDirectory := filepath.Join(targetPath, exch.Name) configTestFile := config.GetConfig() @@ -104,15 +100,6 @@ func main() { if err != nil { log.Fatal(err) } - - fmt.Println("GoCryptoTrader: Exchange templating tool service complete") - fmt.Println("When the exchange code implementation has been completed (REST/Websocket/wrappers and tests), please add the exchange to engine/exchange.go") - fmt.Println("Add the exchange config settings to config_example.json (it will automatically be added to testdata/configtest.json)") - fmt.Println("Increment the available exchanges counter in config/config_test.go") - fmt.Println("Add the exchange name to exchanges/support.go") - fmt.Println("Ensure go test ./... -race passes") - fmt.Println("Open a pull request") - fmt.Println("If help is needed, please post a message in Slack.") } func checkExchangeName(exchName string) error { @@ -147,7 +134,6 @@ func makeExchange(exchangeDirectory string, configTestFile *config.Config, exch fmt.Printf("Output directory: %s\n", exchangeDirectory) exch.CapitalName = cases.Title(language.English).String(exch.Name) - exch.Variable = exch.Name[0:2] newExchConfig := &config.Exchange{} newExchConfig.Name = exch.CapitalName newExchConfig.Enabled = true @@ -173,31 +159,38 @@ func makeExchange(exchangeDirectory string, configTestFile *config.Config, exch { Name: "readme", Filename: "README.md", - TemplateFile: "readme_file.tmpl", + TemplateFile: "readme.tmpl", }, { - Name: "main", - Filename: "main_file.tmpl", - FilePostfix: ".go", - TemplateFile: "main_file.tmpl", + Name: "rest", + Filename: "rest.go", + TemplateFile: "rest.tmpl", }, { Name: "test", Filename: "test_file.tmpl", FilePostfix: "_test.go", - TemplateFile: "test_file.tmpl", + TemplateFile: "test.tmpl", }, { - Name: "type", - Filename: "type_file.tmpl", - FilePostfix: "_types.go", - TemplateFile: "type_file.tmpl", + Name: "types", + Filename: "types.go", + TemplateFile: "types.tmpl", }, { Name: "wrapper", - Filename: "wrapper_file.tmpl", - FilePostfix: "_wrapper.go", - TemplateFile: "wrapper_file.tmpl", + Filename: "wrapper.go", + TemplateFile: "wrapper.tmpl", + }, + { + Name: "subscriptions", + Filename: "subscriptions.go", + TemplateFile: "subscriptions.tmpl", + }, + { + Name: "websocket", + Filename: "websocket.go", + TemplateFile: "websocket.tmpl", }, } @@ -209,6 +202,9 @@ func makeExchange(exchangeDirectory string, configTestFile *config.Config, exch } filename := outputFiles[x].Filename + if !exch.WS && slices.Contains([]string{"websocket", "subscriptions"}, outputFiles[x].Name) { + continue + } if outputFiles[x].FilePostfix != "" { filename = exch.Name + outputFiles[x].FilePostfix } diff --git a/cmd/exchange_template/exchange_template_test.go b/cmd/exchange_template/exchange_template_test.go index 61b8fd785e2..01a01f2dd88 100644 --- a/cmd/exchange_template/exchange_template_test.go +++ b/cmd/exchange_template/exchange_template_test.go @@ -5,12 +5,15 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/thrasher-corp/gocryptotrader/common/file" "github.com/thrasher-corp/gocryptotrader/config" ) func TestCheckExchangeName(t *testing.T) { - tester := []struct { + t.Parallel() + for _, tt := range []struct { Name string ErrExpected error }{ @@ -36,12 +39,16 @@ func TestCheckExchangeName(t *testing.T) { { Name: "testexch", }, - } - - for x := range tester { - if r := checkExchangeName(tester[x].Name); r != tester[x].ErrExpected { - t.Errorf("test: %d unexpected result", x) - } + } { + t.Run(tt.Name, func(t *testing.T) { + t.Parallel() + err := checkExchangeName(tt.Name) + if tt.ErrExpected == nil { + assert.NoError(t, err) + } else { + assert.Equal(t, tt.ErrExpected, err) + } + }) } } @@ -56,7 +63,7 @@ func TestNewExchangeAndSaveConfig(t *testing.T) { } }) - exchCfg, err := makeExchange( + _, err := makeExchange( testExchangeDir, cfg, &exchange{ @@ -65,18 +72,28 @@ func TestNewExchangeAndSaveConfig(t *testing.T) { WS: true, }, ) - if err != nil { - t.Fatal(err) - } + assert.NoError(t, err) + + err = os.RemoveAll(testExchangeDir) + require.NoErrorf(t, err, "RemoveAll failed: %s, manual deletion of test directory required", err) + + exchCfg, err := makeExchange( + testExchangeDir, + cfg, + &exchange{ + Name: testExchangeName, + REST: true, + WS: false, + }, + ) + require.NoError(t, err) cfgData, err := os.ReadFile(exchangeConfigPath) - if err != nil { - t.Fatal(err) - } - if err = saveConfig(testExchangeDir, cfg, exchCfg); err != nil { - t.Error(err) - } - if err = os.WriteFile(exchangeConfigPath, cfgData, file.DefaultPermissionOctal); err != nil { - t.Error(err) - } + require.NoError(t, err, "os.ReadFile must not error") + + err = saveConfig(testExchangeDir, cfg, exchCfg) + require.NoError(t, err, "saveConfig must not error") + + err = os.WriteFile(exchangeConfigPath, cfgData, file.DefaultPermissionOctal) + require.NoError(t, err, "os.WriteFile must not error") } diff --git a/cmd/exchange_template/main_file.tmpl b/cmd/exchange_template/main_file.tmpl deleted file mode 100644 index ef86003af80..00000000000 --- a/cmd/exchange_template/main_file.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -{{define "main"}} -package {{.Name}} - -import ( - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" -) - -// {{.CapitalName}} is the overarching type across this package -type {{.CapitalName}} struct { - exchange.Base -} - -const ( - {{.Name}}APIURL = "" - {{.Name}}APIVersion = "" - - // Public endpoints - - // Authenticated endpoints -) - -// Start implementing public and private exchange API funcs below - -{{end}} diff --git a/cmd/exchange_template/readme_file.tmpl b/cmd/exchange_template/readme.tmpl similarity index 79% rename from cmd/exchange_template/readme_file.tmpl rename to cmd/exchange_template/readme.tmpl index 6bbbed4719e..89cb6c40007 100644 --- a/cmd/exchange_template/readme_file.tmpl +++ b/cmd/exchange_template/readme.tmpl @@ -13,19 +13,10 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra {{if .REST}}+ REST Support {{end}} {{if .WS}}+ Websocket Support {{end}} -{{if .FIX}}+ FIX Support {{end}} + Can be used as a package ## Notes + Please add notes here with any production issues + Please provide link to exchange website and API documentation - -## Contributors - -+ Please add your information - -|User|Github|Contribution| -|--|--|--| -|AliasGoesHere|https://github.com/AliasGoesHere |WHAT-YOU-DID| {{end}} diff --git a/cmd/exchange_template/rest.tmpl b/cmd/exchange_template/rest.tmpl new file mode 100644 index 00000000000..858aa0fcbb3 --- /dev/null +++ b/cmd/exchange_template/rest.tmpl @@ -0,0 +1,51 @@ +{{define "rest"}} +package {{.Name}} + +import ( + "context" + "net/http" + + exchange "github.com/thrasher-corp/gocryptotrader/exchanges" + "github.com/thrasher-corp/gocryptotrader/exchanges/request" +) + +// Exchange implements exchange.IBotExchange and contains additional specific API methods for interacting with {{.CapitalName}} +type Exchange struct { + exchange.Base +} + +const ( + apiURL = "" + apiVersion = "" + + // Public endpoints + + // Authenticated endpoints +) + +// SendHTTPRequest sends an unauthenticated HTTP request +func (e *Exchange) SendHTTPRequest(ctx context.Context, path string, result any) error { + // This is used to generate the *http.Request, used in conjunction with the + // generate functionality below. + item := &request.Item{ + Method: http.MethodGet, + Path: path, + Result: result, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, + } + + // Request function that closes over the above request.Item values, which + // executes on every attempt after rate limiting. + generate := func() (*request.Item, error) { return item, nil } + + endpoint := request.Unset // Used in conjunction with the rate limiting + // system defined in the exchange package to slow down outbound requests + // depending on each individual endpoint. + return e.SendPayload(ctx, endpoint, generate, request.UnauthenticatedRequest) +} + +// Start implementing public and private exchange API funcs below +// Private endpoints can be implemented in a separate file with a _private.go suffix for ease of access and simplicity. +{{end}} \ No newline at end of file diff --git a/cmd/exchange_template/subscriptions.tmpl b/cmd/exchange_template/subscriptions.tmpl new file mode 100644 index 00000000000..38f295c6a1a --- /dev/null +++ b/cmd/exchange_template/subscriptions.tmpl @@ -0,0 +1,14 @@ +{{define "subscriptions"}} +package {{.Name}} + +import ( + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" + "github.com/thrasher-corp/gocryptotrader/exchanges/subscription" +) + +var defaultSubscriptions = subscription.List{ + {Enabled: true, Asset: asset.All, Channel: subscription.TickerChannel}, + {Enabled: true, Asset: asset.All, Channel: subscription.OrderbookChannel, Interval: kline.HundredMilliseconds}, +} +{{end}} \ No newline at end of file diff --git a/cmd/exchange_template/test.tmpl b/cmd/exchange_template/test.tmpl new file mode 100644 index 00000000000..a80cfc6f9a2 --- /dev/null +++ b/cmd/exchange_template/test.tmpl @@ -0,0 +1,39 @@ +{{define "test"}} +package {{.Name}} + +import ( + "log" + "os" + "testing" + + testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange" +) + +// Please supply your own keys here to do authenticated endpoint testing +const ( + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false +) + +var e *Exchange + +func TestMain(m *testing.M) { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { + log.Fatal(err) + } + + if apiKey != "" && apiSecret != "" { + e.API.AuthenticatedSupport = true + {{ if .WS }} e.API.AuthenticatedWebsocketSupport = true {{ end }} + e.SetCredentials(apiKey, apiSecret, "", "", "", "") + {{ if .WS }} e.Websocket.SetCanUseAuthenticatedEndpoints(true) {{ end }} + } + + os.Exit(m.Run()) +} + + +// Implement tests for API endpoints below +{{end}} diff --git a/cmd/exchange_template/test_file.tmpl b/cmd/exchange_template/test_file.tmpl deleted file mode 100644 index 3a2abd3d27d..00000000000 --- a/cmd/exchange_template/test_file.tmpl +++ /dev/null @@ -1,57 +0,0 @@ -{{define "test"}} -package {{.Name}} - -import ( - "log" - "os" - "testing" - - "github.com/thrasher-corp/gocryptotrader/config" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" -) - -// Please supply your own keys here to do authenticated endpoint testing -const ( - apiKey = "" - apiSecret = "" - canManipulateRealOrders = false -) - -var {{.Variable}} = &{{.CapitalName}}{} - -func TestMain(m *testing.M) { - {{.Variable}}.SetDefaults() - cfg := config.GetConfig() - err := cfg.LoadConfig("../../testdata/configtest.json", true) - if err != nil { - log.Fatal(err) - } - - exchCfg, err := cfg.GetExchangeConfig("{{.CapitalName}}") - if err != nil { - log.Fatal(err) - } - - exchCfg.API.AuthenticatedSupport = true - {{ if .WS }} exchCfg.API.AuthenticatedWebsocketSupport = true {{ end }} - exchCfg.API.Credentials.Key = apiKey - exchCfg.API.Credentials.Secret = apiSecret - - err = {{.Variable}}.Setup(exchCfg) - if err != nil { - log.Fatal(err) - } - - os.Exit(m.Run()) -} - -// Ensures that this exchange package is compatible with IBotExchange -func TestInterface(t *testing.T) { - var e exchange.IBotExchange - if e = new({{.CapitalName}}); e == nil { - t.Fatal("unable to allocate exchange") - } -} - -// Implement tests for API endpoints below -{{end}} diff --git a/cmd/exchange_template/type_file.tmpl b/cmd/exchange_template/type_file.tmpl deleted file mode 100644 index b0b96101ec2..00000000000 --- a/cmd/exchange_template/type_file.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{define "type"}} -package {{.Name}} -{{end}} diff --git a/cmd/exchange_template/types.tmpl b/cmd/exchange_template/types.tmpl new file mode 100644 index 00000000000..2709ab6927a --- /dev/null +++ b/cmd/exchange_template/types.tmpl @@ -0,0 +1,8 @@ +{{define "types"}} +package {{.Name}} +/* For efficiency, a JSON to Golang converter can be used: https://mholt.github.io/json-to-go/ +However, great care must be taken as to the values which are autogenerated. The JSON converter tool will default to whatever type it detects, +but ultimately conversions to a more useful variable type would be better. For example, price and quantity on some exchange API's provide these as strings. Internally, +it would be better if they're converted to the more useful float64 var type. +*/ +{{end}} \ No newline at end of file diff --git a/cmd/exchange_template/websocket.tmpl b/cmd/exchange_template/websocket.tmpl new file mode 100644 index 00000000000..108c8818a4c --- /dev/null +++ b/cmd/exchange_template/websocket.tmpl @@ -0,0 +1,78 @@ +{{define "websocket"}} +package {{.Name}} + +import ( + "fmt" + "context" + "net/http" + + gws "github.com/gorilla/websocket" + "github.com/thrasher-corp/gocryptotrader/exchange/websocket" + "github.com/thrasher-corp/gocryptotrader/exchanges/subscription" +) + +const ( + wsAPIURL = "" +) + +// WsConnect creates a new websocket connection. +func (e *Exchange) WsConnect() error { + ctx := context.TODO() + if !e.Websocket.IsEnabled() || !e.IsEnabled() { + return websocket.ErrWebsocketNotEnabled + } + dialer := gws.Dialer{ + HandshakeTimeout: e.Config.HTTPTimeout, + Proxy: http.ProxyFromEnvironment, + } + + if e.Websocket.CanUseAuthenticatedEndpoints() { + // Add WebSocket authentication logic here. + } + + if err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}); err != nil { + return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", e.Name, err) + } + + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) + return nil +} + +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) +} + +// Subscribe sends websocket messages to receive data for a list of channels +func (e *Exchange) Subscribe(_ subscription.List) error { + // ctx := context.TODO() + return nil +} + +// Unsubscribe sends websocket messages to stop receiving data for a list of channels +func (e *Exchange) Unsubscribe(_ subscription.List) error { + // ctx := context.TODO() + return nil +} + +// wsReadData receives and passes on websocket messages for processing +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() + for { + resp := e.Websocket.Conn.ReadMessage() + if resp.Raw == nil { + return + } + if err := e.wsHandleData(ctx, resp.Raw); err != nil { + // e.Websocket.DataHandler <- err + } + } +} + +// wsHandleData processes a websocket incoming data. +func (e *Exchange) wsHandleData(ctx context.Context, respData []byte) error { + // Implement message parsing and handling logic here. + return nil +} + +{{end}} \ No newline at end of file diff --git a/cmd/exchange_template/wrapper.tmpl b/cmd/exchange_template/wrapper.tmpl new file mode 100644 index 00000000000..b47b6959ad6 --- /dev/null +++ b/cmd/exchange_template/wrapper.tmpl @@ -0,0 +1,530 @@ +{{define "wrapper"}} +package {{.Name}} + +import ( + "context" + "time" + + "github.com/thrasher-corp/gocryptotrader/common" + "github.com/thrasher-corp/gocryptotrader/common/key" + "github.com/thrasher-corp/gocryptotrader/config" + "github.com/thrasher-corp/gocryptotrader/currency" + "github.com/thrasher-corp/gocryptotrader/exchange/websocket" + exchange "github.com/thrasher-corp/gocryptotrader/exchanges" + "github.com/thrasher-corp/gocryptotrader/exchanges/account" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/deposit" + "github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate" + "github.com/thrasher-corp/gocryptotrader/exchanges/futures" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" + "github.com/thrasher-corp/gocryptotrader/exchanges/margin" + "github.com/thrasher-corp/gocryptotrader/exchanges/order" + "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/trade" + "github.com/thrasher-corp/gocryptotrader/log" + "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" +) + +// SetDefaults sets the basic defaults for {{.CapitalName}} +func (e *Exchange) SetDefaults() { + e.Name = "{{.CapitalName}}" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + + // If using only one pair format for request and configuration, across all supported asset types either SPOT and FUTURES etc. You can use the example below: + // Request format denotes what the pair as a string will be, when you send a request to an exchange. + requestFmt := ¤cy.PairFormat{/*Set pair request formatting details here for e.g.*/ Uppercase: true, Delimiter: ":"} + // Config format denotes how the currency pair should be represented as a string, including the delimiter between base and quote currency, + // when saved to the config.json file. + configFmt := ¤cy.PairFormat{/*Set pair request formatting details here*/} + if err := e.SetGlobalPairsManager(requestFmt, configFmt, /*multiple assets can be set here using the asset package ie asset.Spot*/); err != nil { + log.Errorln(log.ExchangeSys, err) + } + + // If assets require multiple differences in formatting for request and + // configuration, another exchange method can be used e.g. futures + // contracts require a dash as a delimiter rather than an underscore. You + // can use this example below: + + fmt1 := currency.PairStore{ + AssetEnabled: true, + RequestFormat: ¤cy.PairFormat{Uppercase: true}, + ConfigFormat: ¤cy.PairFormat{Uppercase: true}, + } + + fmt2 := currency.PairStore{ + AssetEnabled: true, + RequestFormat: ¤cy.PairFormat{Uppercase: true}, + ConfigFormat: ¤cy.PairFormat{Uppercase: true, Delimiter: ":"}, + } + + if err := e.SetAssetPairStore(asset.Spot, fmt1); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, asset.Spot, err) + } + if err := e.SetAssetPairStore(asset.Margin, fmt2); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, asset.Margin, err) + } + + // Fill out the capabilities/features that the exchange supports + e.Features = exchange.Features{ + Supports: exchange.FeaturesSupported{ + {{ if .REST }} REST: true, {{ end }} + {{ if .WS }} Websocket: true, {{ end }} + {{ if .REST }} + RESTCapabilities: protocol.Features{ + TickerFetching: true, + OrderbookFetching: true, + KlineFetching: true, + TradeFetching: true, + GetOrders: true, + AccountInfo: true, + AuthenticatedEndpoints: true, + }, + {{ end }} + {{ if .WS }} + WebsocketCapabilities: protocol.Features{ + TickerFetching: true, + OrderbookFetching: true, + KlineFetching: true, + TradeFetching: true, + Subscribe: true, + Unsubscribe: true, + AuthenticatedEndpoints: true, + }, + {{ end }} + WithdrawPermissions: exchange.AutoWithdrawCrypto | + exchange.AutoWithdrawFiat, + Kline: kline.ExchangeCapabilitiesSupported{ + Intervals: false, + }, + }, + + Enabled: exchange.FeaturesEnabled{ + AutoPairUpdates: true, + // Kline: kline.ExchangeCapabilitiesEnabled{ + // Intervals: kline.DeployExchangeIntervals( + // kline.IntervalCapacity{Interval: kline.OneMin}, + // ), + // GlobalResultLimit: 2000, + // }, + }, + {{ if .WS }} Subscriptions: defaultSubscriptions,{{ end }} + } + // TODO: SET THE EXCHANGES RATE LIMIT HERE + var err error + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) + if err != nil { + log.Errorln(log.ExchangeSys, err) + } + + // TODO: SET THE URLs HERE + e.API.Endpoints = e.NewEndpoints() + if err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + exchange.RestSpot: apiURL, + {{ if .WS }} exchange.WebsocketSpot: wsAPIURL,{{ end }} + }); err != nil { + log.Errorln(log.ExchangeSys, err) + } + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit +} + +// Setup takes in the supplied exchange configuration details and sets params +func (e *Exchange) Setup(exch *config.Exchange) error { + if err := exch.Validate(); err != nil { + return err + } + if !exch.Enabled { + e.SetEnabled(false) + return nil + } + if err := e.SetupDefaults(exch); err != nil { + return err + } + + /* + wsRunningEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) + if err != nil { + return err + } + + // If websocket is not supported, remove these websocket sections + if err := e.Websocket.Setup( + &websocket.ManagerSetup{ + ExchangeConfig: exch, + DefaultURL: wsAPIURL, + RunningURL: wsRunningEndpoint, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, + }); err != nil { + return err + } + + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + URL: e.Websocket.GetWebsocketURL(), + ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, + ResponseMaxLimit: exch.WebsocketResponseMaxLimit, + }) + */ + return nil +} + +// FetchTradablePairs returns a list of the exchanges tradable pairs +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + // Implement fetching the exchange available pairs if supported + return nil, nil +} + +// UpdateTradablePairs updates the exchanges available pairs and stores them in the exchanges config +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assetTypes := e.GetAssetTypes(false) + for x := range assetTypes { + pairs, err := e.FetchTradablePairs(ctx, assetTypes[x]) + if err != nil { + return err + } + + err = e.UpdatePairs(pairs, assetTypes[x], false, forceUpdate) + if err != nil { + return err + } + } + return nil +} + +// UpdateTicker updates and returns the ticker for a currency pair +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { + // TODO: Replace this example code with exchange specific implementation + /* + tick, err := e.GetTickers() + if err != nil { + return nil, err + } + for y := range tick { + cp, err := currency.NewPairFromString(tick[y].Symbol) + if err != nil { + return nil, err + } + err = ticker.ProcessTicker(&ticker.Price{ + Last: tick[y].LastPrice, + High: tick[y].HighPrice, + Low: tick[y].LowPrice, + Bid: tick[y].BidPrice, + Ask: tick[y].AskPrice, + Volume: tick[y].Volume, + QuoteVolume: tick[y].QuoteVolume, + Open: tick[y].OpenPrice, + Close: tick[y].PrevClosePrice, + Pair: cp, + ExchangeName: e.Name, + AssetType: assetType, + }) + if err != nil { + return nil, err + } + } + */ + return ticker.GetTicker(e.Name, p, assetType) +} + +// UpdateTickers updates all currency pairs of a given asset type +func (e *Exchange) UpdateTickers(ctx context.Context, assetType asset.Item) error { + // TODO: Replace this example code with exchange specific implementation + /* + tick, err := e.GetTickers() + if err != nil { + return err + } + for y := range tick { + cp, err := currency.NewPairFromString(tick[y].Symbol) + if err != nil { + return err + } + err = ticker.ProcessTicker(&ticker.Price{ + Last: tick[y].LastPrice, + High: tick[y].HighPrice, + Low: tick[y].LowPrice, + Bid: tick[y].BidPrice, + Ask: tick[y].AskPrice, + Volume: tick[y].Volume, + QuoteVolume: tick[y].QuoteVolume, + Open: tick[y].OpenPrice, + Close: tick[y].PrevClosePrice, + Pair: cp, + ExchangeName: e.Name, + AssetType: assetType, + }) + if err != nil { + return err + } + } + */ + return common.ErrNotYetImplemented +} + +// UpdateOrderbook updates and returns the orderbook for a currency pair +func (e *Exchange) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { + var err error + pair, err = e.FormatExchangeCurrency(pair, assetType) + if err != nil { + return nil, err + } + // TODO: Replace this example code with exchange specific implementation + /* + ob, err := e.GetOrderBook(pair.String(), 1000) + if err != nil { + return nil, err + } + */ + book := &orderbook.Book{ + Exchange: e.Name, + Pair: pair, + Asset: assetType, + ValidateOrderbook: e.ValidateOrderbook, + } + /* + book.Bids = make([]orderbook.Level, len(ob.Bids)) + for x := range ob.Bids { + book.Bids[x] = orderbook.Level{ + Amount: ob.Bids[x].Quantity, + Price: ob.Bids[x].Price, + } + } + + book.Asks = make([]orderbook.Level, len(ob.Asks)) + for x := range ob.Asks { + book.Asks[x] = orderbook.Level{ + Amount: ob.Asks[x].Quantity, + Price: ob.Asks[x].Price, + } + } + */ + if err := book.Process(); err != nil { + return book, err + } + + return orderbook.Get(e.Name, pair, assetType) +} + +// UpdateAccountInfo retrieves balances for all enabled currencies +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { + // If fetching requires more than one asset type please set + // HasAssetTypeAccountSegregation to true in RESTCapabilities above. + return account.Holdings{}, common.ErrNotYetImplemented +} + +// GetAccountFundingHistory returns funding history, deposits and withdrawals +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { + return nil, common.ErrNotYetImplemented +} + +// GetWithdrawalsHistory returns previous withdrawals data +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { + return nil, common.ErrNotYetImplemented +} + +// GetRecentTrades returns the most recent trades for a currency and asset +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return nil, common.ErrNotYetImplemented +} + +// GetHistoricTrades returns historic trade data within the timeframe provided +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { + return nil, common.ErrNotYetImplemented +} + +// GetServerTime returns the current exchange server time. +func (e *Exchange) GetServerTime(ctx context.Context, a asset.Item) (time.Time, error) { + return time.Time{}, common.ErrNotYetImplemented +} + +// SubmitOrder submits a new order +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { + return nil, err + } + /* TODO: When an order has been submitted you can use this helpful constructor to + return. Please add any additional order details to the + order.SubmitResponse if you think they are applicable. + resp, err := s.DeriveSubmitResponse(newOrderID) + if err != nil { + return nil, err + } + resp.Date = exampleTime // e.g. If this is supplied by the exchanges API. + return resp, nil + */ + return nil, common.ErrNotYetImplemented +} + +// ModifyOrder will allow changing of orderbook placements and limit to market conversions +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { + if err := action.Validate(); err != nil { + return nil, err + } + // TODO: When an order has been modified you can use this helpful constructor to + // return. Please add any additional order details to the + // order.ModifyResponse if you think they are applicable. + // resp, err := action.DeriveModifyResponse() + // if err != nil { + // return nil, err + // } + // resp.OrderID = maybeANewOrderID // e.g. If this is supplied by the exchanges API. + return nil, common.ErrNotYetImplemented +} + +// CancelOrder cancels an order by its corresponding ID number +func (e *Exchange) CancelOrder(ctx context.Context, ord *order.Cancel) error { + // if err := ord.Validate(ord.StandardCancel()); err != nil { + // return err + // } + return common.ErrNotYetImplemented +} + +// CancelBatchOrders cancels orders by their corresponding ID numbers +func (e *Exchange) CancelBatchOrders(ctx context.Context, orders []order.Cancel) (*order.CancelBatchResponse, error) { + return nil, common.ErrNotYetImplemented +} + +// CancelAllOrders cancels all orders associated with a currency pair +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { + // if err := orderCancellation.Validate(); err != nil { + // return order.CancelAllResponse{}, err + // } + return order.CancelAllResponse{}, common.ErrNotYetImplemented +} + +// GetOrderInfo returns order information based on order ID +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { + return nil, common.ErrNotYetImplemented +} + +// GetDepositAddress returns a deposit address for a specified currency +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, accountID string, chain string) (*deposit.Address, error) { + return nil, common.ErrNotYetImplemented +} + +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + return nil, common.ErrNotYetImplemented +} + +// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { + // if err := withdrawRequest.Validate(); err != nil { + // return nil, err + // } + return nil, common.ErrNotYetImplemented +} + +// WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted +func (e *Exchange) WithdrawFiatFunds(_ context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { + // if err := withdrawRequest.Validate(); err != nil { + // return nil, err + // } + return nil, common.ErrNotYetImplemented +} + +// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { + // if err := withdrawRequest.Validate(); err != nil { + // return nil, err + // } + return nil, common.ErrNotYetImplemented +} + +// GetActiveOrders retrieves any orders that are active/open +func (e *Exchange) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { + // if err := getOrdersRequest.Validate(); err != nil { + // return nil, err + // } + return nil, common.ErrNotYetImplemented +} + +// GetOrderHistory retrieves account order information +// Can Limit response to specific order status +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { + // if err := getOrdersRequest.Validate(); err != nil { + // return nil, err + // } + return nil, common.ErrNotYetImplemented +} + +// GetFeeByType returns an estimate of fee based on the type of transaction +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { + return 0, common.ErrNotYetImplemented +} + +// ValidateAPICredentials validates current credentials used for wrapper +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) +} + +// GetHistoricCandles returns candles between a time period for a set time interval +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + return nil, common.ErrNotYetImplemented +} + +// GetHistoricCandlesExtended returns candles between a time period for a set time interval +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + return nil, common.ErrNotYetImplemented +} + +// GetLeverage gets the account's initial leverage for the asset type and pair +func (e *Exchange) GetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ order.Side) (float64, error) { + return -1, common.ErrNotYetImplemented +} + +// GetFuturesContractDetails returns all contracts from the exchange by asset type +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { + return nil, common.ErrNotYetImplemented +} + +// GetLatestFundingRates returns the latest funding rates data +func (e *Exchange) GetLatestFundingRates(_ context.Context, _ *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { + return nil, common.ErrNotYetImplemented +} + +// GetHistoricalFundingRates returns funding rates for a given asset and currency for a time period +func (e *Exchange) GetHistoricalFundingRates(_ context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { + if r == nil { + return nil, common.ErrNilPointer + } + return nil, common.ErrNotYetImplemented +} + +// GetOpenInterest returns the open interest rate for a given asset pair +func (e *Exchange) GetOpenInterest(_ context.Context, _ ...key.PairAsset) ([]futures.OpenInterest, error) { + return nil, common.ErrNotYetImplemented +} + +// GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) + if err != nil { + return "", err + } + return "", common.ErrNotYetImplemented +} + +// UpdateOrderExecutionLimits updates order execution limits +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { + return common.ErrNotYetImplemented +} + +// SetLeverage sets the account's initial leverage for the asset type and pair +func (e *Exchange) SetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ float64, _ order.Side) error { + return common.ErrNotYetImplemented +} + +{{end}} \ No newline at end of file diff --git a/cmd/exchange_template/wrapper_file.tmpl b/cmd/exchange_template/wrapper_file.tmpl deleted file mode 100644 index ee54d65da03..00000000000 --- a/cmd/exchange_template/wrapper_file.tmpl +++ /dev/null @@ -1,473 +0,0 @@ -{{define "wrapper"}} -package {{.Name}} - -import ( - "context" - "time" - - "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/account" - "github.com/thrasher-corp/gocryptotrader/exchanges/asset" - "github.com/thrasher-corp/gocryptotrader/exchanges/deposit" - "github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate" - "github.com/thrasher-corp/gocryptotrader/exchanges/futures" - "github.com/thrasher-corp/gocryptotrader/exchanges/kline" - "github.com/thrasher-corp/gocryptotrader/exchanges/order" - "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/trade" - "github.com/thrasher-corp/gocryptotrader/exchange/websocket" - "github.com/thrasher-corp/gocryptotrader/log" - "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" -) - -// SetDefaults sets the basic defaults for {{.CapitalName}} -func ({{.Variable}} *{{.CapitalName}}) SetDefaults() { - {{.Variable}}.Name = "{{.CapitalName}}" - {{.Variable}}.Enabled = true - {{.Variable}}.Verbose = true - {{.Variable}}.API.CredentialsValidator.RequiresKey = true - {{.Variable}}.API.CredentialsValidator.RequiresSecret = true - - // If using only one pair format for request and configuration, across all - // supported asset types either SPOT and FUTURES etc. You can use the - // example below: - - // Request format denotes what the pair as a string will be, when you send - // a request to an exchange. - requestFmt := ¤cy.PairFormat{/*Set pair request formatting details here for e.g.*/ Uppercase: true, Delimiter: ":"} - // Config format denotes what the pair as a string will be, when saved to - // the config.json file. - configFmt := ¤cy.PairFormat{/*Set pair request formatting details here*/} - err := {{.Variable}}.SetGlobalPairsManager(requestFmt, configFmt, /*multiple assets can be set here using the asset package ie asset.Spot*/) - if err != nil { - log.Errorln(log.ExchangeSys, err) - } - - // If assets require multiple differences in formatting for request and - // configuration, another exchange method can be be used e.g. futures - // contracts require a dash as a delimiter rather than an underscore. You - // can use this example below: - - fmt1 := currency.PairStore{ - AssetEnabled: true, - RequestFormat: ¤cy.PairFormat{Uppercase: true}, - ConfigFormat: ¤cy.PairFormat{Uppercase: true}, - } - - fmt2 := currency.PairStore{ - AssetEnabled: true, - RequestFormat: ¤cy.PairFormat{Uppercase: true}, - ConfigFormat: ¤cy.PairFormat{Uppercase: true, Delimiter: ":"}, - } - - err = {{.Variable}}.SetAssetPairStore(asset.Spot, fmt1) - if err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", {{.Variable}}.Name, asset.Spot, err) - } - err = {{.Variable}}.SetAssetPairStore(asset.Margin, fmt2) - if err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", {{.Variable}}.Name, asset.Margin, err) - } - - // Fill out the capabilities/features that the exchange supports - {{.Variable}}.Features = exchange.Features{ - Supports: exchange.FeaturesSupported{ - {{ if .REST }} REST: true, {{ end }} - {{ if .WS }} Websocket: true, {{ end }} - RESTCapabilities: protocol.Features{ - TickerFetching: true, - OrderbookFetching: true, - }, - WebsocketCapabilities: protocol.Features{ - TickerFetching: true, - OrderbookFetching: true, - }, - WithdrawPermissions: exchange.AutoWithdrawCrypto | - exchange.AutoWithdrawFiat, - }, - Enabled: exchange.FeaturesEnabled{ - AutoPairUpdates: true, - }, - } - // NOTE: SET THE EXCHANGES RATE LIMIT HERE - {{.Variable}}.Requester, err = request.New({{.Variable}}.Name, - common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) - if err != nil { - log.Errorln(log.ExchangeSys, err) - } - - // NOTE: SET THE URLs HERE - {{.Variable}}.API.Endpoints = {{.Variable}}.NewEndpoints() - {{.Variable}}.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ - exchange.RestSpot: {{.Name}}APIURL, - // exchange.WebsocketSpot: {{.Name}}WSAPIURL, - }) - {{.Variable}}.Websocket = websocket.NewManager() - {{.Variable}}.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - {{.Variable}}.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - {{.Variable}}.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit -} - -// Setup takes in the supplied exchange configuration details and sets params -func ({{.Variable}} *{{.CapitalName}}) Setup(exch *config.Exchange) error { - err := exch.Validate() - if err != nil { - return err - } - if !exch.Enabled { - {{.Variable}}.SetEnabled(false) - return nil - } - err = {{.Variable}}.SetupDefaults(exch) - if err != nil { - return err - } - - /* - wsRunningEndpoint, err := {{.Variable}}.API.Endpoints.GetURL(exchange.WebsocketSpot) - if err != nil { - return err - } - - // If websocket is supported, please fill out the following - - err = {{.Variable}}.Websocket.Setup( - &websocket.ManagerSetup{ - ExchangeConfig: exch, - DefaultURL: {{.Name}}WSAPIURL, - RunningURL: wsRunningEndpoint, - Connector: {{.Variable}}.WsConnect, - Subscriber: {{.Variable}}.Subscribe, - UnSubscriber: {{.Variable}}.Unsubscribe, - Features: &{{.Variable}}.Features.Supports.WebsocketCapabilities, - }) - if err != nil { - return err - } - - {{.Variable}}.WebsocketConn = &websocket.WebsocketConnection{ - ExchangeName: {{.Variable}}.Name, - URL: {{.Variable}}.Websocket.GetWebsocketURL(), - ProxyURL: {{.Variable}}.Websocket.GetProxyAddress(), - Verbose: {{.Variable}}.Verbose, - ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, - ResponseMaxLimit: exch.WebsocketResponseMaxLimit, - } - */ - return nil -} - -// FetchTradablePairs returns a list of the exchanges tradable pairs -func ({{.Variable}} *{{.CapitalName}}) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - // Implement fetching the exchange available pairs if supported - return nil, nil -} - -// UpdateTradablePairs updates the exchanges available pairs and stores -// them in the exchanges config -func ({{.Variable}} *{{.CapitalName}}) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assetTypes := {{.Variable}}.GetAssetTypes(false) - for x := range assetTypes { - pairs, err := {{.Variable}}.FetchTradablePairs(ctx, assetTypes[x]) - if err != nil { - return err - } - - err = {{.Variable}}.UpdatePairs(pairs, assetTypes[x], false, forceUpdate) - if err != nil { - return err - } - } - return nil -} - - -// UpdateTicker updates and returns the ticker for a currency pair -func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { - // NOTE: EXAMPLE FOR GETTING TICKER PRICE - /* - tickerPrice := new(ticker.Price) - tick, err := {{.Variable}}.GetTicker(p.String()) - if err != nil { - return tickerPrice, err - } - tickerPrice = &ticker.Price{ - High: tick.High, - Low: tick.Low, - Bid: tick.Bid, - Ask: tick.Ask, - Open: tick.Open, - Close: tick.Close, - Pair: p, - } - err = ticker.ProcessTicker({{.Variable}}.Name, tickerPrice, assetType) - if err != nil { - return tickerPrice, err - } - */ - return ticker.GetTicker({{.Variable}}.Name, p, assetType) -} - -// UpdateTickers updates all currency pairs of a given asset type -func ({{.Variable}} *{{.CapitalName}}) UpdateTickers(ctx context.Context, assetType asset.Item) error { - // NOTE: EXAMPLE FOR GETTING TICKER PRICE - /* - tick, err := {{.Variable}}.GetTickers() - if err != nil { - return err - } - for y := range tick { - cp, err := currency.NewPairFromString(tick[y].Symbol) - if err != nil { - return err - } - err = ticker.ProcessTicker(&ticker.Price{ - Last: tick[y].LastPrice, - High: tick[y].HighPrice, - Low: tick[y].LowPrice, - Bid: tick[y].BidPrice, - Ask: tick[y].AskPrice, - Volume: tick[y].Volume, - QuoteVolume: tick[y].QuoteVolume, - Open: tick[y].OpenPrice, - Close: tick[y].PrevClosePrice, - Pair: cp, - ExchangeName: b.Name, - AssetType: assetType, - }) - if err != nil { - return err - } - } - */ - return nil -} - -// UpdateOrderbook updates and returns the orderbook for a currency pair -func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { - book := &orderbook.Book{ - Exchange: {{.Variable}}.Name, - Pair: pair, - Asset: assetType, - ValidateOrderbook: {{.Variable}}.ValidateOrderbook, - } - - // NOTE: UPDATE ORDERBOOK EXAMPLE - /* - orderbookNew, err := {{.Variable}}.GetOrderBook(exchange.FormatExchangeCurrency({{.Variable}}.Name, p).String(), 1000) - if err != nil { - return book, err - } - - book.Bids = make([]orderbook.Level, len(orderbookNew.Bids)) - for x := range orderbookNew.Bids { - book.Bids[x] = orderbook.Level{ - Amount: orderbookNew.Bids[x].Quantity, - Price: orderbookNew.Bids[x].Price, - } - } - - book.Asks = make([]orderbook.Level, len(orderbookNew.Asks)) - for x := range orderbookNew.Asks { - book.Asks[x] = orderbook.Level{ - Amount: orderBookNew.Asks[x].Quantity, - Price: orderBookNew.Asks[x].Price, - } - } - */ - - err := book.Process() - if err != nil { - return book, err - } - - return orderbook.Get({{.Variable}}.Name, pair, assetType) -} - -// UpdateAccountInfo retrieves balances for all enabled currencies -func ({{.Variable}} *{{.CapitalName}}) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { - // If fetching requires more than one asset type please set - // HasAssetTypeAccountSegregation to true in RESTCapabilities above. - return account.Holdings{}, common.ErrNotYetImplemented -} - -// GetFundingHistory returns funding history, deposits and -// withdrawals -func ({{.Variable}} *{{.CapitalName}}) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { - return nil, common.ErrNotYetImplemented -} - -// GetWithdrawalsHistory returns previous withdrawals data -func ({{.Variable}} *{{.CapitalName}}) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { - return nil, common.ErrNotYetImplemented -} - -// GetRecentTrades returns the most recent trades for a currency and asset -func ({{.Variable}} *{{.CapitalName}}) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return nil, common.ErrNotYetImplemented -} - -// GetHistoricTrades returns historic trade data within the timeframe provided -func ({{.Variable}} *{{.CapitalName}}) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { - return nil, common.ErrNotYetImplemented -} - - -// GetServerTime returns the current exchange server time. -func ({{.Variable}} *{{.CapitalName}}) GetServerTime(ctx context.Context, a asset.Item) (time.Time, error) { - return time.Time{}, common.ErrNotYetImplemented -} - - -// SubmitOrder submits a new order -func ({{.Variable}} *{{.CapitalName}}) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate({{.Variable}}.GetTradingRequirements()); err != nil { - return nil, err - } - // When an order has been submitted you can use this helpful constructor to - // return. Please add any additional order details to the - // order.SubmitResponse if you think they are applicable. - // resp, err := s.DeriveSubmitResponse( /*newOrderID*/) - // if err != nil { - // return nil, nil - // } - // resp.Date = exampleTime // e.g. If this is supplied by the exchanges API. - // return resp, nil - return nil, common.ErrNotYetImplemented -} - -// ModifyOrder will allow of changing orderbook placement and limit to -// market conversion -func ({{.Variable}} *{{.CapitalName}}) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { - if err := action.Validate(); err != nil { - return nil, err - } - // When an order has been modified you can use this helpful constructor to - // return. Please add any additional order details to the - // order.ModifyResponse if you think they are applicable. - // resp, err := action.DeriveModifyResponse() - // if err != nil { - // return nil, nil - // } - // resp.OrderID = maybeANewOrderID // e.g. If this is supplied by the exchanges API. - return nil, common.ErrNotYetImplemented -} - -// CancelOrder cancels an order by its corresponding ID number -func ({{.Variable}} *{{.CapitalName}}) CancelOrder(ctx context.Context, ord *order.Cancel) error { - // if err := ord.Validate(ord.StandardCancel()); err != nil { - // return err - // } - return common.ErrNotYetImplemented -} - -// CancelBatchOrders cancels orders by their corresponding ID numbers -func ({{.Variable}} *{{.CapitalName}}) CancelBatchOrders(ctx context.Context, orders []order.Cancel) (*order.CancelBatchResponse, error) { - return nil, common.ErrNotYetImplemented -} - -// CancelAllOrders cancels all orders associated with a currency pair -func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { - // if err := orderCancellation.Validate(); err != nil { - // return err - // } - return order.CancelAllResponse{}, common.ErrNotYetImplemented -} - -// GetOrderInfo returns order information based on order ID -func ({{.Variable}} *{{.CapitalName}}) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { - return nil, common.ErrNotYetImplemented -} - -// GetDepositAddress returns a deposit address for a specified currency -func ({{.Variable}} *{{.CapitalName}}) GetDepositAddress(ctx context.Context, c currency.Code, accountID string, chain string) (*deposit.Address, error) { - return nil, common.ErrNotYetImplemented -} - -// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is -// submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { - // if err := withdrawRequest.Validate(); err != nil { - // return nil, err - // } - return nil, common.ErrNotYetImplemented -} - -// WithdrawFiatFunds returns a withdrawal ID when a withdrawal is -// submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { - // if err := withdrawRequest.Validate(); err != nil { - // return nil, err - // } - return nil, common.ErrNotYetImplemented -} - -// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is -// submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { - // if err := withdrawRequest.Validate(); err != nil { - // return nil, err - // } - return nil, common.ErrNotYetImplemented -} - -// GetActiveOrders retrieves any orders that are active/open -func ({{.Variable}} *{{.CapitalName}}) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { - // if err := getOrdersRequest.Validate(); err != nil { - // return nil, err - // } - return nil, common.ErrNotYetImplemented -} - -// GetOrderHistory retrieves account order information -// Can Limit response to specific order status -func ({{.Variable}} *{{.CapitalName}}) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { - // if err := getOrdersRequest.Validate(); err != nil { - // return nil, err - // } - return nil, common.ErrNotYetImplemented -} - -// GetFeeByType returns an estimate of fee based on the type of transaction -func ({{.Variable}} *{{.CapitalName}}) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { - return 0, common.ErrNotYetImplemented -} - -// ValidateAPICredentials validates current credentials used for wrapper -func ({{.Variable}} *{{.CapitalName}}) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := {{.Variable}}.UpdateAccountInfo(ctx, assetType) - return {{.Variable}}.CheckTransientError(err) -} - -// GetHistoricCandles returns candles between a time period for a set time interval -func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - return nil, common.ErrNotYetImplemented -} - -// GetHistoricCandlesExtended returns candles between a time period for a set time interval -func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - return nil, common.ErrNotYetImplemented -} - -// GetFuturesContractDetails returns all contracts from the exchange by asset type -func ({{.Variable}} *{{.CapitalName}}) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { - return nil, common.ErrNotYetImplemented -} - -// GetLatestFundingRates returns the latest funding rates data -func ({{.Variable}} *{{.CapitalName}}) GetLatestFundingRates(_ context.Context, _ *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { - return nil, common.ErrNotYetImplemented -} - -// UpdateOrderExecutionLimits updates order execution limits -func ({{.Variable}} *{{.CapitalName}}) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { - return common.ErrNotYetImplemented -} - -{{end}} diff --git a/cmd/portfolio/portfolio.go b/cmd/portfolio/portfolio.go index 65ac71e8921..783005938ed 100644 --- a/cmd/portfolio/portfolio.go +++ b/cmd/portfolio/portfolio.go @@ -126,7 +126,7 @@ func main() { pf.Subtotal = y.Balance } } else { - bf := bitfinex.Bitfinex{} + bf := bitfinex.Exchange{} bf.SetDefaults() bf.Verbose = false pair := "t" + y.Coin.String() + currency.USD.String() diff --git a/docs/ADD_NEW_EXCHANGE.md b/docs/ADD_NEW_EXCHANGE.md index 49e1d040568..b7001118b41 100644 --- a/docs/ADD_NEW_EXCHANGE.md +++ b/docs/ADD_NEW_EXCHANGE.md @@ -18,7 +18,7 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader ## How to add a new exchange -This document is from a perspective of adding a new exchange called FTX to the codebase: +This document is from a perspective of adding a new exchange called Binance to the codebase: ### Run the [exchange templating tool](../cmd/exchange_template/) which will create a base exchange package based on the features the exchange supports @@ -29,7 +29,7 @@ Using Go Modules you now clone this repository **outside** your GOPATH ```bash git clone https://github.com/thrasher-corp/gocryptotrader.git cd gocryptotrader/cmd/exchange_template -go run exchange_template.go -name FTX -ws -rest +go run exchange_template.go -name Binance -ws -rest ``` #### Windows @@ -37,106 +37,41 @@ go run exchange_template.go -name FTX -ws -rest ```bash git clone https://github.com/thrasher-corp/gocryptotrader.git cd gocryptotrader\cmd\exchange_template -go run exchange_template.go -name FTX -ws -rest +go run exchange_template.go -name Binance -ws -rest ``` ### Add exchange struct to [config_example.json](../config_example.json), [configtest.json](../testdata/configtest.json): Find out which asset types are supported by the exchange and add them to the pairs struct (spot is enabled by default) -#### If main config path is unknown the following function can be used: +If main config path is unknown the following function can be used: ```go config.GetDefaultFilePath() ``` ```js { - "name": "FTX", + "name": "Binance", "enabled": true, "verbose": false, - "httpTimeout": 15000000000, - "websocketResponseCheckTimeout": 30000000, - "websocketResponseMaxLimit": 7000000000, - "websocketTrafficTimeout": 30000000000, - "websocketOrderbookBufferLimit": 5, - "baseCurrencies": "USD", "currencyPairs": { + "bypassConfigFormatUpgrades": false, + "requestFormat": { + "uppercase": true + }, + "configFormat": { + "uppercase": true, + "delimiter": "-" + }, + "useGlobalFormat": true, "pairs": { - "futures": { - "assetEnabled": true, - "enabled": "BTC-PERP", - "available": "BTC-PERP", - "requestFormat": { - "uppercase": true, - "delimiter": "-" - }, - "configFormat": { - "uppercase": true, - "delimiter": "-" - } - }, "spot": { "assetEnabled": true, - "enabled": "BTC/USD", - "available": "BTC/USD", - "requestFormat": { - "uppercase": true, - "delimiter": "/" - }, - "configFormat": { - "uppercase": true, - "delimiter": "/" - } + "enabled": "BTC-USDT", + "available": "BTC-USDT,BNB-BTC,NEO-BTC,QTUM-ETH,ETH-BTC" } } }, - "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" - }, - "credentialsValidator": { - "requiresKey": true, - "requiresSecret": true - } - }, - "features": { - "supports": { - "restAPI": true, - "restCapabilities": { - "tickerBatching": true, - "autoPairUpdates": true - }, - "websocketAPI": true, - "websocketCapabilities": {} - }, - "enabled": { - "autoPairUpdates": true, - "websocketAPI": false - } - }, - "bankAccounts": [ - { - "enabled": false, - "bankName": "", - "bankAddress": "", - "bankPostalCode": "", - "bankPostalCity": "", - "bankCountry": "", - "accountName": "", - "accountNumber": "", - "swiftCode": "", - "iban": "", - "supportedCurrencies": "" - } - ] }, ``` @@ -148,7 +83,7 @@ Check to make sure that the command does not override the NTP client and encrypt go build && gocryptotrader.exe --config=config_example.json ``` -### Add the currency pair format structs in ftx_wrapper.go: +### Add the currency pair format structs in wrapper.go: #### Futures currency support: @@ -178,18 +113,18 @@ Similar to the configs, spot support is inbuilt but other asset types will need }, } - err := f.SetAssetPairStore(asset.Spot, spot) + err := e.SetAssetPairStore(asset.Spot, spot) if err != nil { log.Errorf(log.ExchangeSys, "%s error storing `spot` default asset formats: %s", bi.Name, err) } - err = f.SetAssetPairStore(asset.Futures, futures) + err = e.SetAssetPairStore(asset.Futures, futures) if err != nil { log.Errorf(log.ExchangeSys, "%s error storing `futures` default asset formats: %s", bi.Name, err) } ``` -### Document the addition of the new exchange (FTX exchange is used as an example below): +### Document the addition of the new exchange (Binance exchange is used as an example below): Yes means supported, No means not yet implemented and NA means protocol unsupported @@ -198,7 +133,7 @@ Yes means supported, No means not yet implemented and NA means protocol unsuppor | Exchange | REST API | Streaming API | FIX API | |----------|------|-----------|-----| | Alphapoint | Yes | Yes | NA | -| Binance| Yes | Yes | NA | +| Binance| Yes | Yes | NA | // <-------- new exchange | Bitfinex | Yes | Yes | NA | | Bitflyer | Yes | No | NA | | Bithumb | Yes | NA | NA | @@ -210,7 +145,6 @@ Yes means supported, No means not yet implemented and NA means protocol unsuppor | COINUT | Yes | Yes | NA | | Deribit | Yes | Yes | NA | | Exmo | Yes | NA | NA | -| FTX | Yes | Yes | No | // <-------- new exchange | CoinbasePro | Yes | Yes | No| | GateIO | Yes | Yes | NA | | Gemini | Yes | Yes | No | @@ -227,7 +161,7 @@ Yes means supported, No means not yet implemented and NA means protocol unsuppor #### Add exchange to the list of [supported exchanges](../exchanges/support.go): ```go var Exchanges = []string{ - "binance", + "binance", // <-------- new exchange "bitfinex", "bitflyer", "bithumb", @@ -240,7 +174,6 @@ var Exchanges = []string{ "coinut", "deribit", "exmo", - "ftx", // <-------- new exchange "gateio", "gemini", "hitbtc", @@ -260,7 +193,7 @@ var Exchanges = []string{ - Replace names and variables as shown: ```go -{{define "exchanges exmo" -}} // exmo -> ftx +{{define "exchanges exmo" -}} // exmo -> binance {{template "header" .}} ## Exmo Exchange @@ -270,11 +203,11 @@ var Exchanges = []string{ ``` ```go -var e exchange.IBotExchange // We name the exchange.IBotExchange variable after the first character of the exchange, eg f for FTX. e -> f +var e exchange.IBotExchange for i := range bot.Exchanges { - if bot.Exchanges[i].GetName() == "Exmo" { // Exmo -> FTX - e = bot.Exchanges[i] // e -> f + if bot.Exchanges[i].GetName() == "Exmo" { // Exmo -> Binance + e = bot.Exchanges[i] } } @@ -303,22 +236,36 @@ go run documentation.go This will generate a readme file for the exchange which can be found in the new exchange's folder +### Code Consistency Guidelines + +1. Exchange API function parameters and structs should default to using unsigned integers (e.g., uint64) instead of int or int64. Using int can be problematic since we target different architectures, and its size varies between 32-bit and 64-bit systems (e.g., Some people run GCT on 32-bit Raspiberry Pi's). Explicitly using uint64 ensures consistency and prevents issues like negative values where they don’t make sense. Additionally, many common strconv functions (e.g., FormatUint) default to uint64, making it a more natural choice over uint32, despite the potential memory savings. + +2. Exchange parameters for start and end times should use time.Time instead of int64 UNIX timestamps. Even if an exchange requires a UNIX timestamp, we should convert it within the function to maintain consistency and readability. + +3. Time usage within Exchange API requests and responses should default to UTC. There is an existing PR for this, but further work is needed to enforce UTC across all exchanges before merging. + +4. TestMain in exchanges must avoid API calls to keep test footprint as minimal as possible unless there's a good case as to why it was done + +5. Excessive exchange API method params should use structs + +6. Test deduplication should be the default approach for exchanges, image provided as an example diff + ### Create functions supported by the exchange: #### Requester functions: ```go // SendHTTPRequest sends an unauthenticated HTTP request -func (f *FTX) SendHTTPRequest(ctx context.Context, path string, result any) error { +func (e *Exchange) SendHTTPRequest(ctx context.Context, path string, result any) error { // This is used to generate the *http.Request, used in conjunction with the // generate functionality below. item := &request.Item{ Method: http.MethodGet, Path: path, Result: result, - Verbose: f.Verbose, - HTTPDebugging: f.HTTPDebugging, - HTTPRecording: f.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } // Request function that closes over the above request.Item values, which @@ -328,13 +275,13 @@ func (f *FTX) SendHTTPRequest(ctx context.Context, path string, result any) erro endpoint := request.Unset // Used in conjunction with the rate limiting // system defined in the exchange package to slow down outbound requests // depending on each individual endpoint. - return f.SendPayload(ctx, endpoint, generate) + return e.SendPayload(ctx, endpoint, generate, request.UnauthenticatedRequest) } ``` -#### Unauthenticated Functions: +#### Public Functions: -https://docs.ftx.com/#get-markets +https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-endpoints Create a type struct in types.go for the response type shown on the documentation website: @@ -342,134 +289,155 @@ For efficiency, a JSON to Golang converter can be used: https://mholt.github.io/ However, great care must be taken as to the values which are autogenerated. The JSON converter tool will default to whatever type it detects, but ultimately conversions to a more useful variable type would be better. For example, price and quantity on some exchange API's provide these as strings. Internally, it would be better if they're converted to the more useful float64 var type. ```go -// MarketData stores market data -type MarketData struct { - Name string `json:"name"` - BaseCurrency string `json:"baseCurrency"` - QuoteCurrency string `json:"quoteCurrency"` - MarketType string `json:"type"` - Underlying string `json:"underlying"` - Enabled bool `json:"enabled"` - Ask float64 `json:"ask"` - Bid float64 `json:"bid"` - Last float64 `json:"last"` - PriceIncrement float64 `json:"priceIncrement"` - SizeIncrement float64 `json:"sizeIncrement"` +// ExchangeInfo holds the full exchange information type +type ExchangeInfo struct { + Code int `json:"code"` + Msg string `json:"msg"` + Timezone string `json:"timezone"` + ServerTime types.Time `json:"serverTime"` + RateLimits []*struct { + RateLimitType string `json:"rateLimitType"` + Interval string `json:"interval"` + Limit int `json:"limit"` + } `json:"rateLimits"` + ExchangeFilters any `json:"exchangeFilters"` + Symbols []*struct { + Symbol string `json:"symbol"` + Status string `json:"status"` + BaseAsset string `json:"baseAsset"` + BaseAssetPrecision int `json:"baseAssetPrecision"` + QuoteAsset string `json:"quoteAsset"` + QuotePrecision int `json:"quotePrecision"` + OrderTypes []string `json:"orderTypes"` + IcebergAllowed bool `json:"icebergAllowed"` + OCOAllowed bool `json:"ocoAllowed"` + QuoteOrderQtyMarketAllowed bool `json:"quoteOrderQtyMarketAllowed"` + IsSpotTradingAllowed bool `json:"isSpotTradingAllowed"` + IsMarginTradingAllowed bool `json:"isMarginTradingAllowed"` + Filters []*filterData `json:"filters"` + Permissions []string `json:"permissions"` + PermissionSets [][]string `json:"permissionSets"` + } `json:"symbols"` } ``` -Create new consts to define endpoint strings, they are created at the top of ftx.go file: +Create new consts to define endpoint strings, they are created at the top of rest.go file: ```go const ( - ftxAPIURL = "https://ftx.com/api" + apiURL = "https://api.binance.com" // Public endpoints - getMarkets = "/markets" - getMarket = "/markets/" - getOrderbook = "/markets/%s/orderbook?depth=%s" - getTrades = "/markets/%s/trades?" - getHistoricalData = "/markets/%s/candles?" - getFutures = "/futures" - getFuture = "/futures/" - getFutureStats = "/futures/%s/stats" - getFundingRates = "/funding_rates" - getAllWallegetAllWalletBalances = "/wallet/all_balances" + exchangeInfo = "/api/v3/exchangeInfo" + orderBookDepth = "/api/v3/depth" + recentTrades = "/api/v3/trades" + aggregatedTrades = "/api/v3/aggTrades" + candleStick = "/api/v3/klines" + orderEndpoint = "/api/v3/order" +) ``` -Create a get function in ftx.go file and unmarshall the data in the created type: +Create a get function in rest.go file and unmarshall the data in the created type: ```go -// GetMarkets gets market data -func (f *FTX) GetMarkets(ctx context.Context) (Markets, error) { - var resp Markets - return resp, f.SendHTTPRequest(ctx, ftxAPIURL+getMarkets, &resp) +// GetExchangeInfo returns exchange information. Check types for more +// information +func (e *Exchange) GetExchangeInfo(ctx context.Context) (*ExchangeInfo, error) { + var resp *ExchangeInfo + return resp, e.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, exchangeInfo, spotExchangeInfo, &resp) } ``` -Create a test function in ftx_test.go to see if the data is received and unmarshalled correctly +Create a test function in binance_test.go to see if the data is received and unmarshalled correctly ```go -const( - spotPair = "FTT/BTC" -) - -func TestGetMarket(t *testing.T) { +func TestGetExchangeInfo(t *testing.T) { t.Parallel() // adding t.Parallel() is preferred as it allows tests to run simultaneously, speeding up package test time - f.Verbose = true // used for more detailed output - a, err := f.GetMarket(context.Background(), spotPair) // spotPair is just a const so it can be reused in other tests too - t.Log(a) - if err != nil { - t.Error(err) - } + e.Verbose = true // used for more detailed output + result, err := e.GetExchangeInfo(context.Background()) + require.NoError(t, err) + t.Log(result) + assert.NotNil(t, result) } ``` -Verbose can be set to true to see the data received if there are errors unmarshalling -Once testing is done remove verbose, variable a and t.Log(a) since they produce unnecessary output when GCT is run +Set Verbose to true to view received data during unmarshalling errors. +After testing, remove Verbose, the result variable, and t.Log(result), or replace the log with assert.NotNil(t, result) to avoid unnecessary output when running GCT. ```go -_, err := f.GetMarket(context.Background(), spotPair) + result, err := e.GetExchangeInfo(context.Background()) + require.NoError(t, err) + assert.NotNil(t, result) ``` Ensure each endpoint is implemented and has an associated test to improve test coverage and increase confidence #### Authenticated functions: -Authenticated request function is created based on the way the exchange documentation specifies: https://docs.ftx.com/#authentication +Authenticated request function is created based on the way the exchange documentation specifies: https://developers.binance.com/docs/binance-spot-api-docs/rest-api/endpoint-security-type ```go // SendAuthHTTPRequest sends an authenticated request -func (f *FTX) SendAuthHTTPRequest(ctx context.Context, method, path string, data, result any) error { -// A potential example below of closing over authenticated variables which may -// be required to regenerate on every request between each attempt after rate -// limiting. This is for when signatures are based on timestamps/nonces that are -// within time receive windows. NOTE: This is not always necessary and the above -// SendHTTPRequest example will suffice. +func (e *Exchange) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error { + // A potential example below of closing over authenticated variables which may + // be required to regenerate on every request between each attempt after rate + // limiting. This is for when signatures are based on timestamps/nonces that are + // within time receive windows. NOTE: This is not always necessary and the above + // SendHTTPRequest example will suffice. // Fetches credentials, this can either use a context set credential or if // not found, will default to the config.json exchange specific credentials. - creds, err := f.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - generate := func() (*request.Item, error) { - ts := strconv.FormatInt(time.Now().UnixMilli(), 10) - var body io.Reader - var hmac, payload []byte - var err error - if data != nil { - payload, err = json.Marshal(data) - if err != nil { - return err - } - body = bytes.NewBuffer(payload) - sigPayload := ts + method + "/api" + path + string(payload) - hmac = crypto.GetHMAC(crypto.HashSHA256, []byte(sigPayload), []byte(creds.Secret)) - } else { - sigPayload := ts + method + "/api" + path - hmac = crypto.GetHMAC(crypto.HashSHA256, []byte(sigPayload), []byte(creds.Secret)) + endpointPath, err := e.API.Endpoints.GetURL(ePath) + if err != nil { + return err + } + + if params == nil { + params = url.Values{} + } + + if params.Get("recvWindow") == "" { + params.Set("recvWindow", strconv.FormatInt(defaultRecvWindow.Milliseconds(), 10)) + } + + interim := json.RawMessage{} + err = e.SendPayload(ctx, f, func() (*request.Item, error) { + params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) + hmacSigned, err := crypto.GetHMAC(crypto.HashSHA256, []byte(params.Encode()), []byte(creds.Secret)) + if err != nil { + return nil, err } headers := make(map[string]string) - headers["FTX-KEY"] = creds.Key - headers["FTX-SIGN"] = crypto.HexEncodeToString(hmac) - headers["FTX-TS"] = ts - headers["Content-Type"] = "application/json" - - // This is used to generate the *http.Request. - item := &request.Item{ + headers["X-MBX-APIKEY"] = creds.Key + fullPath := common.EncodeURLValues(endpointPath+path, params) + "&signature=" + hex.EncodeToString(hmacSigned) + return &request.Item{ Method: method, - Path: ftxAPIURL + path, + Path: fullPath, Headers: headers, - Body: body, - Result: result, - Verbose: f.Verbose, - HTTPDebugging: f.HTTPDebugging, - HTTPRecording: f.HTTPRecording, - } - return item, nil + Result: &interim, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, + }, nil }, request.AuthenticatedRequest) - - endpoint := request.Unset // Used in conjunction with the rate limiting - // system defined in the exchange package to slow down outbound requests - // depending on each individual endpoint. - - return f.SendPayload(ctx, endpoint, generate) + if err != nil { + return err + } + errCap := struct { + Success bool `json:"success"` + Message string `json:"msg"` + Code int64 `json:"code"` + }{} + + if err := json.Unmarshal(interim, &errCap); err == nil { + if !errCap.Success && errCap.Message != "" && errCap.Code != 200 { + return errors.New(errCap.Message) + } + } + if result == nil { + return nil + } + return json.Unmarshal(interim, result) } ``` @@ -479,105 +447,130 @@ HTTP Mocking framework can also be added for the exchange. For reference, please Create authenticated functions and test along the way similar to the functions above: -https://docs.ftx.com/#get-account-information: +https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints: ```go -// GetAccountInfo gets account info -func (f *FTX) GetAccountInfo(ctx context.Context) (AccountData, error) { - var resp AccountData - return resp, f.SendAuthHTTPRequest(ctx, http.MethodGet, getAccountInfo, nil, &resp) +// GetAccount returns binance user accounts +func (e *Exchange) GetAccount(ctx context.Context) (*Account, error) { + type response struct { + Response + Account + } + + var resp response + return &resp.Account, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, accountInfo, url.Values{}, spotAccountInformationRate, &resp) } ``` Get Request params for authenticated requests are sent through url.Values{}: -https://docs.ftx.com/#get-withdrawal-history: +https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints: ```go -// GetTriggerOrderHistory gets trigger orders that are currently open -func (f *FTX) GetTriggerOrderHistory(ctx context.Context, marketName string, startTime, endTime time.Time, side, orderType, limit string) (TriggerOrderHistory, error) { - var resp TriggerOrderHistory +// QueryOrder returns information on a past order +func (e *Exchange) QueryOrder(ctx context.Context, symbol currency.Pair, origClientOrderID string, orderID int64) (*OrderResponse, error) { params := url.Values{} - if marketName != "" { - params.Set("market", marketName) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) + if err != nil { + return resp, err } - if !startTime.IsZero() && !endTime.IsZero() { - params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) - params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) - if startTime.After(endTime) { - return resp, errors.New("startTime cannot be after endTime") - } + params.Set("symbol", symbolValue) + if origClientOrderID != "" { + params.Set("origClientOrderId", origClientOrderID) } - if side != "" { - params.Set("side", side) + if orderID != 0 { + params.Set("orderId", strconv.FormatInt(orderID, 10)) } - if orderType != "" { - params.Set("type", orderType) + + var resp *OrderResponse + if err := e.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, orderEndpoint, + params, spotOrderQueryRate, + &resp); err != nil { + return resp, err } - if limit != "" { - params.Set("limit", limit) + + if resp.Code != 0 { + return resp, errors.New(resp.Msg) } - return resp, f.SendAuthHTTPRequest(ctx, http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp) + return resp, nil } ``` -https://docs.ftx.com/#place-order +https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints Structs for unmarshalling the data are made exactly the same way as the previous functions. ```go -type OrderData struct { - CreatedAt time.Time `json:"createdAt"` - FilledSize float64 `json:"filledSize"` - Future string `json:"future"` - ID int64 `json:"id"` - Market string `json:"market"` - Price float64 `json:"price"` - AvgFillPrice float64 `json:"avgFillPrice"` - RemainingSize float64 `json:"remainingSize"` - Side string `json:"side"` - Size float64 `json:"size"` - Status string `json:"status"` - OrderType string `json:"type"` - ReduceOnly bool `json:"reduceOnly"` - IOC bool `json:"ioc"` - PostOnly bool `json:"postOnly"` - ClientID string `json:"clientId"` -} - -// PlaceOrder stores data of placed orders -type PlaceOrder struct { - Success bool `json:"success"` - Result OrderData `json:"result"` +// OrderResponse is the return structured response from the exchange +type OrderResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Symbol string `json:"symbol"` + OrderID int64 `json:"orderId"` + ClientOrderID string `json:"clientOrderId"` + TransactionTime types.Time `json:"transactTime"` + Price float64 `json:"price,string"` + OrigQty float64 `json:"origQty,string"` + ExecutedQty float64 `json:"executedQty,string"` + CumulativeQuoteQty float64 `json:"cummulativeQuoteQty,string"` + Status string `json:"status"` + TimeInForce string `json:"timeInForce"` + Type string `json:"type"` + Side string `json:"side"` + Fills []struct { + Price float64 `json:"price,string"` + Qty float64 `json:"qty,string"` + Commission float64 `json:"commission,string"` + CommissionAsset string `json:"commissionAsset"` + } `json:"fills"` } ``` -For `POST` or `DELETE` requests, params are sent through a map[string]any: +For `POST` or `DELETE` requests, params are sent through a query params: ```go -// Order places an order -func (f *FTX) Order(ctx context.Context, marketName, side, orderType, reduceOnly, ioc, postOnly, clientID string, price, size float64) (PlaceOrder, error) { - req := make(map[string]any) - req["market"] = marketName - req["side"] = side - req["price"] = price - req["type"] = orderType - req["size"] = size - if reduceOnly != "" { - req["reduceOnly"] = reduceOnly +// NewOrder sends a new test order to Binance +func (e *Exchange) NewOrder(ctx context.Context, o *NewOrderRequest) (*OrderResponse, error) { + symbol, err := e.FormatSymbol(o.Symbol, asset.Spot) + if err != nil { + return err + } + params := url.Values{} + params.Set("symbol", symbol) + params.Set("side", o.Side) + params.Set("type", string(o.TradeType)) + if o.QuoteOrderQty > 0 { + params.Set("quoteOrderQty", strconv.FormatFloat(o.QuoteOrderQty, 'f', -1, 64)) + } else { + params.Set("quantity", strconv.FormatFloat(o.Quantity, 'f', -1, 64)) } - if ioc != "" { - req["ioc"] = ioc + if o.TradeType == BinanceRequestParamsOrderLimit { + params.Set("price", strconv.FormatFloat(o.Price, 'f', -1, 64)) } - if postOnly != "" { - req["postOnly"] = postOnly + if o.TimeInForce != "" { + params.Set("timeInForce", o.TimeInForce) } - if clientID != "" { - req["clientID"] = clientID + + if o.NewClientOrderID != "" { + params.Set("newClientOrderId", o.NewClientOrderID) } - var resp PlaceOrder - return resp, f.SendAuthHTTPRequest(ctx, http.MethodPost, placeOrder, req, &resp) + + if o.StopPrice != 0 { + params.Set("stopPrice", strconv.FormatFloat(o.StopPrice, 'f', -1, 64)) + } + + if o.IcebergQty != 0 { + params.Set("icebergQty", strconv.FormatFloat(o.IcebergQty, 'f', -1, 64)) + } + + if o.NewOrderRespType != "" { + params.Set("newOrderRespType", o.NewOrderRespType) + } + var resp *OrderResponse + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, orderEndpoint, params, spotOrderRate, resp) } ``` @@ -591,9 +584,8 @@ Unsupported Example: ```go // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (f *FTX) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { - var resp *withdraw.ExchangeResponse - return resp, common.ErrFunctionNotSupported +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { + return nil, common.ErrFunctionNotSupported } ``` @@ -601,27 +593,51 @@ Supported Examples: ```go // FetchTradablePairs returns a list of the exchanges tradable pairs -func (f *FTX) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !f.SupportsAsset(a) { - return nil, fmt.Errorf("asset type of %s is not supported by %s", a, f.Name) - } - markets, err := f.GetMarkets(ctx) - if err != nil { - return nil, err +// FetchTradablePairs returns a list of the exchanges tradable pairs +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { + return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - var pairs []string + tradingStatus := "TRADING" + var pairs []currency.Pair switch a { - case asset.Spot: - for x := range markets.Result { - if markets.Result[x].MarketType == spotString { - pairs = append(pairs, markets.Result[x].Name) + case asset.Spot, asset.Margin: + info, err := e.GetExchangeInfo(ctx) + if err != nil { + return nil, err + } + pairs = make([]currency.Pair, 0, len(info.Symbols)) + for x := range info.Symbols { + if info.Symbols[x].Status != tradingStatus { + continue + } + pair, err := currency.NewPairFromStrings(info.Symbols[x].BaseAsset, + info.Symbols[x].QuoteAsset) + if err != nil { + return nil, err + } + if a == asset.Spot && info.Symbols[x].IsSpotTradingAllowed { + pairs = append(pairs, pair) + } + if a == asset.Margin && info.Symbols[x].IsMarginTradingAllowed { + pairs = append(pairs, pair) } } - case asset.Futures: - for x := range markets.Result { - if markets.Result[x].MarketType == futuresString { - pairs = append(pairs, markets.Result[x].Name) + case asset.CoinMarginedFutures: + cInfo, err := e.FuturesExchangeInfo(ctx) + if err != nil { + return nil, err + } + pairs = make([]currency.Pair, 0, len(cInfo.Symbols)) + for z := range cInfo.Symbols { + if cInfo.Symbols[z].ContractStatus != tradingStatus { + continue } + pair, err := currency.NewPairFromString(cInfo.Symbols[z].Symbol) + if err != nil { + return nil, err + } + pairs = append(pairs, pair) } } return pairs, nil @@ -633,11 +649,11 @@ Wrapper functions on most exchanges are written in similar ways so other exchang Many helper functions defined in [exchange.go](../exchanges/exchange.go) can be useful when implementing wrapper functions. See examples below: ```go -f.FormatExchangeCurrency(p, a) // Formats the currency pair to the style accepted by the exchange. p is the currency pair & a is the asset type +e.FormatExchangeCurrency(p, a) // Formats the currency pair to the style accepted by the exchange. p is the currency pair & a is the asset type -f.SupportsAsset(a) // Checks if an asset type is supported by the bot +e.SupportsAsset(a) // Checks if an asset type is supported by the bot -f.GetPairAssetType(p) // Returns the asset type of currency pair p +e.GetPairAssetType(p) // Returns the asset type of currency pair p ``` The currency package contains many helper functions to format and process currency pairs. See [currency](../currency/README.md). @@ -646,93 +662,106 @@ The currency package contains many helper functions to format and process curren #### Websocket Setup: -- Set the websocket url in ftx_websocket.go that is provided in the documentation: +- Set the websocket url in websocket.go that is provided in the documentation: ```go - ftxWSURL = "wss://ftx.com/ws/" + binanceDefaultWebsocketURL = "wss://stream.binance.com:9443/stream" ``` #### Complete WsConnect function: ```go -// WsConnect connects to a websocket feed -func (f *FTX) WsConnect() error { - if !f.Websocket.IsEnabled() || !f.IsEnabled() { - return errors.New(wshandler.WebsocketNotEnabled) - } - var dialer websocket.Dialer - err := f.Websocket.Conn.Dial(&dialer, http.Header{}) - if err != nil { - return err - } - // Can set up custom ping handler per websocket connection. - f.Websocket.Conn.SetupPingHandler(wshandler.WebsocketPingHandler{ - MessageType: websocket.PingMessage, - Delay: ftxWebsocketTimer, - }) - if f.Verbose { - log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", f.Name) +// WsConnect initiates a websocket connection +func (e *Exchange) WsConnect() error { + ctx := context.TODO() + if !e.Websocket.IsEnabled() || !e.IsEnabled() { + return websocket.ErrWebsocketNotEnabled } - // This reader routine is called prior to initiating a subscription for - // efficient processing. - go f.wsReadData() - if f.IsWebsocketAuthenticationSupported() { - err = f.WsAuth(context.TODO()) + + var dialer gws.Dialer + dialer.HandshakeTimeout = e.Config.HTTPTimeout + dialer.Proxy = http.ProxyFromEnvironment + var err error + if e.Websocket.CanUseAuthenticatedEndpoints() { + listenKey, err = e.GetWsAuthStreamKey(ctx) if err != nil { - f.Websocket.DataHandler <- err - f.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%v unable to connect to authenticated Websocket. Error: %s", e.Name, err) + } else { + // cleans on failed connection + clean := strings.Split(b.Websocket.GetWebsocketURL(), "?streams=") + authPayload := clean[0] + "?streams=" + listenKey + err = e.Websocket.SetWebsocketURL(authPayload, false, false) + if err != nil { + return err + } } } - // Generates the default subscription set, based off enabled pairs. - subs, err := f.generateSubscriptions() + + err = e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { - return err + return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", e.Name, err) + } + + if e.Websocket.CanUseAuthenticatedEndpoints() { + // Start a goroutine to keep the WebSocket auth key alive + // for accessing authenticated endpoints. + go e.KeepAuthKeyAlive(ctx) } - // Finally subscribes to each individual channel. - return f.Websocket.SubscribeToChannels(subs) + + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + UseGorillaHandler: true, + MessageType: gws.PongMessage, + Delay: pingDelay, + }) + + e.Websocket.Wg.Add(1) + go e.wsReadData() + + e.setupOrderbookManager(ctx) + return nil } ``` -- Create function to generate default subscriptions: +- Create the authentication function based on specifications provided in the documentation: + +https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/authentication-requests ```go -// generateSubscriptions generates default subscription -func (f *FTX) generateSubscriptions() (subscription.List, error) { - var subscriptions subscription.List - subscriptions = append(subscriptions, &subscription.Subscription{ - Channel: wsMarkets, - }) - // Ranges over available channels, pairs and asset types to produce a full - // subscription list. - var channels = []string{wsTicker, wsTrades, wsOrderbook} - assets := f.GetAssetTypes() - for a := range assets { - pairs, err := f.GetEnabledPairs(assets[a]) - if err != nil { - return nil, err - } - for z := range pairs { - newPair := currency.NewPairWithDelimiter(pairs[z].Base.String(), - pairs[z].Quote.String(), - "-") - for x := range channels { - subscriptions = append(subscriptions, - &subscription.Subscription{ - Channel: channels[x], - Pair: currency.Pairs{newPair}, - Asset: assets[a], - }) +// KeepAuthKeyAlive will continuously send messages to +// keep the WS auth key active +func (e *Exchange) KeepAuthKeyAlive(ctx context.Context) { + e.Websocket.Wg.Add(1) + defer e.Websocket.Wg.Done() + ticks := time.NewTicker(time.Minute * 30) + for { + select { + case <-e.Websocket.ShutdownC: + ticks.Stop() + return + case <-ticks.C: + err := e.MaintainWsAuthStreamKey(ctx) + if err != nil { + e.Websocket.DataHandler <- err + log.Warnf(log.ExchangeSys, "%s - Unable to renew auth websocket token, may experience shutdown", e.Name) } } } - // Appends authenticated channels to the subscription list - if f.IsWebsocketAuthenticationSupported() { - var authchan = []string{wsOrders, wsFills} - for x := range authchan { - subscriptions = append(subscriptions, &subscription.Subscription{Channel: authchan[x]}) +} +``` + +- Create function to generate default subscriptions: + +```go +// generateSubscriptions generates default subscription +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + for _, s := range e.Features.Subscriptions { + if s.Asset == asset.Empty { + // Handle backwards compatibility with config without assets, all binance subs are spot + s.Asset = asset.Spot } } - return subscriptions, nil + return e.Features.Subscriptions.ExpandTemplates(b) } ``` @@ -753,16 +782,16 @@ func (f *FTX) generateSubscriptions() (subscription.List, error) { - Create subscribe function with the data provided by the exchange documentation: -https://docs.ftx.com/#request-process +https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/request-format - Create a struct required to subscribe to channels: ```go -// WsSub has the data used to subscribe to a channel -type WsSub struct { - Channel string `json:"channel,omitempty"` - Market string `json:"market,omitempty"` - Operation string `json:"op,omitempty"` +// WsPayload defines the payload through the websocket connection +type WsPayload struct { + ID int64 `json:"id"` + Method string `json:"method"` + Params []string `json:"params"` } ``` @@ -770,7 +799,7 @@ type WsSub struct { ```go // Subscribe sends a websocket message to receive data from the channel -func (f *FTX) Subscribe(channelsToSubscribe subscription.List) error { +func (e *Exchange) Subscribe(channelsToSubscribe subscription.List) error { // For subscriptions we try to batch as much as possible to limit the amount // of connection usage but sometimes this is not supported on the exchange // API. @@ -787,20 +816,20 @@ channels: // Authenticated wsFills && wsOrders or wsMarkets which is a channel subscription for the full set of tradable markets do not need a currency pair association. default: // Ensures our outbound currency pair is formatted correctly, sometimes our configuration format is different from what our request format needs to be. - formattedPair, err := f.FormatExchangeCurrency(channelsToSubscribe[i].Pair, channelsToSubscribe[i].Asset) + formattedPair, err := e.FormatExchangeCurrency(channelsToSubscribe[i].Pair, channelsToSubscribe[i].Asset) if err != nil { errs = append(errs, err) continue channels } sub.Market = formattedPair.String() } - err := f.Websocket.Conn.SendJSONMessage(sub) + err := e.Websocket.Conn.SendJSONMessage(sub) if err != nil { errs = append(errs, err) continue } // When we have a successful subscription, we can alert our internal management system of the success. - f.Websocket.AddSuccessfulSubscriptions(f.Websocket.Conn, channelsToSubscribe[i]) + e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channelsToSubscribe[i]) } return errs } @@ -815,8 +844,8 @@ Run gocryptotrader with the following settings enabled in config "websocketCapabilities": {} }, "enabled": { - "autoPairUpdates": true, - "websocketAPI": true // <- Change this to true if it is false + "autoPairUpdates": true, + "websocketAPI": true // <- Change this to true if it is false ``` #### Handle websocket data: @@ -828,23 +857,23 @@ Run gocryptotrader with the following settings enabled in config ```go // wsReadData gets and passes on websocket messages for processing -func (f *FTX) wsReadData() { - f.Websocket.Wg.Add(1) - defer f.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + e.Websocket.Wg.Add(1) + defer e.Websocket.Wg.Done() for { select { - case <-f.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: return default: - resp := f.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := f.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - f.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } @@ -889,15 +918,16 @@ If a suitable struct does not exist in wshandler, wrapper types are the next pre if err != nil { return err } - f.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: f.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Bid: resultData.Ticker.Bid, Ask: resultData.Ticker.Ask, Last: resultData.Ticker.Last, LastUpdated: timestampFromFloat64(resultData.Ticker.Time), Pair: p, AssetType: a, - } + } + } ``` If neither of those provide a suitable struct to store the data in, the data can just be passed onto wshandler without any further changes: @@ -909,7 +939,7 @@ If neither of those provide a suitable struct to store the data in, the data can if err != nil { return err } - f.Websocket.DataHandler <- resultData.FillsData + e.Websocket.DataHandler <- resultData.FillsData ``` - Data Handling can be tested offline similar to the following example: @@ -917,9 +947,7 @@ If neither of those provide a suitable struct to store the data in, the data can ```go func TestParsingWSOrdersData(t *testing.T) { t.Parallel() - if !areTestAPIKeysSet() { - t.Skip("API keys required but not set, skipping test") - } + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) data := []byte(`{ "channel": "orders", "data": { @@ -940,75 +968,29 @@ func TestParsingWSOrdersData(t *testing.T) { }, "type": "update" }`) - err := f.wsHandleData(data) - if err != nil { - t.Error(err) - } + err := e.wsHandleData(data) + assert.NoError(t, err) } ``` - Create types given in the documentation to unmarshall the streamed data: -https://docs.ftx.com/#fills-2 - -```go -// WsFills stores websocket fills' data -type WsFills struct { - Fee float64 `json:"fee"` - FeeRate float64 `json:"feeRate"` - Future string `json:"future"` - ID int64 `json:"id"` - Liquidity string `json:"liquidity"` - Market string `json:"market"` - OrderID int64 `json:"int64"` - TradeID int64 `json:"tradeID"` - Price float64 `json:"price"` - Side string `json:"side"` - Size float64 `json:"size"` - Time time.Time `json:"time"` - OrderType string `json:"orderType"` -} - -// WsFillsDataStore stores ws fills' data -type WsFillsDataStore struct { - Channel string `json:"channel"` - MessageType string `json:"type"` - FillsData WsFills `json:"fills"` -} -``` - -- Create the authentication function based on specifications provided in the documentation: - -https://docs.ftx.com/#private-channels +https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#trade-streams ```go -// WsAuth sends an authentication message to receive auth data -func (f *FTX) WsAuth(ctx context.Context) error { - // Fetches credentials, this can either use a context set credential or if - // not found, will default to the config.json exchange specific credentials. - // NOTE: Websocket context values are not sufficiently propagated yet, so in - // most circumstances the calling function can call context.TODO() and will - // use default credentials. - creds, err := f.GetCredentials(ctx) - if err != nil { - return err - } - - strNonce := strconv.FormatInt(time.Now().UnixMilli(), 10) - hmac := crypto.GetHMAC( - crypto.HashSHA256, - []byte(strNonce+"websocket_login"), - []byte(creds.Secret), - ) - sign := crypto.HexEncodeToString(hmac) - req := Authenticate{Operation: "login", - Args: AuthenticationData{ - Key: creds.Key, - Sign: sign, - Time: intNonce, - }, - } - return f.Websocket.Conn.SendJSONMessage(req) +// TradeStream holds the trade stream data +type TradeStream struct { + EventType string `json:"e"` + EventTime types.Time `json:"E"` + Symbol string `json:"s"` + TradeID int64 `json:"t"` + Price types.Number `json:"p"` + Quantity types.Number `json:"q"` + BuyerOrderID int64 `json:"b"` + SellerOrderID int64 `json:"a"` + TimeStamp types.Time `json:"T"` + IsBuyerMaker bool `json:"m"` + BestMatchPrice bool `json:"M"` } ``` @@ -1016,7 +998,7 @@ func (f *FTX) WsAuth(ctx context.Context) error { ```go // Unsubscribe sends a websocket message to stop receiving data from the channel -func (f *FTX) Unsubscribe(channelsToUnsubscribe subscription.List) error { +func (e *Exchange) Unsubscribe(channelsToUnsubscribe subscription.List) error { // As with subscribing we want to batch as much as possible, but sometimes this cannot be achieved due to API shortfalls. var errs common.Errors channels: @@ -1027,20 +1009,20 @@ channels: switch channelsToUnsubscribe[i].Channel { case wsFills, wsOrders, wsMarkets: default: - formattedPair, err := f.FormatExchangeCurrency(channelsToUnsubscribe[i].Pair, channelsToUnsubscribe[i].Asset) + formattedPair, err := e.FormatExchangeCurrency(channelsToUnsubscribe[i].Pair, channelsToUnsubscribe[i].Asset) if err != nil { errs = append(errs, err) continue channels } unSub.Market = formattedPair.String() } - err := f.Websocket.Conn.SendJSONMessage(unSub) + err := e.Websocket.Conn.SendJSONMessage(unSub) if err != nil { errs = append(errs, err) continue } // When we have a successful unsubscription, we can alert our internal management system of the success. - f.Websocket.RemoveSubscriptions(f.Websocket.Conn, channelsToUnsubscribe[i]) + e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channelsToUnsubscribe[i]) } if errs != nil { return errs @@ -1055,40 +1037,40 @@ Add websocket functionality if supported to Setup: ```go // Setup takes in the supplied exchange configuration details and sets params -func (f *FTX) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - f.SetEnabled(false) + e.SetEnabled(false) return nil } - err = f.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } // Websocket details setup below - err = f.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, // DefaultURL defines the default endpoint in the event a rollback is // needed via gctcli. - DefaultURL: ftxWSURL, + DefaultURL: binanceWSURL, RunningURL: exch.API.Endpoints.WebsocketURL, // Connector function outlined above. - Connector: f.WsConnect, + Connector: e.WsConnect, // Subscriber function outlined above. - Subscriber: f.Subscribe, + Subscriber: e.Subscribe, // Unsubscriber function outlined above. - UnSubscriber: f.Unsubscribe, + UnSubscriber: e.Unsubscribe, // GenerateSubscriptions function outlined above. - GenerateSubscriptions: f.generateSubscriptions, + GenerateSubscriptions: e.generateSubscriptions, // Defines the capabilities of the websocket outlined in supported // features struct. This allows the websocket connection to be flushed // appropriately if we have a pair/asset enable/disable change. This is // outlined below. - Features: &f.Features.Supports.WebsocketCapabilities, + Features: &e.Features.Supports.WebsocketCapabilities, // Orderbook buffer specific variables for processing orderbook updates // via websocket feed: @@ -1100,19 +1082,19 @@ func (f *FTX) Setup(exch *config.Exchange) error { return err } // Sets up a new connection for the websocket, there are two separate connections denoted by the ConnectionSetup struct auth bool. - return f.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, // RateLimit int64 rudimentary rate limit that sleeps connection in milliseconds before sending designated payload - // Authenticated bool sets if the connection is dedicated for an authenticated websocket stream which can be accessed from the Websocket field variable AuthConn e.g. f.Websocket.AuthConn + // Authenticated bool sets if the connection is dedicated for an authenticated websocket stream which can be accessed from the Websocket field variable AuthConn e.g. e.Websocket.AuthConn }) } ``` -Below are the features supported by FTX API protocol: +Below are the features supported by Binance API protocol: ```go - f.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -1155,8 +1137,8 @@ Initially the functions return nil or common.ErrNotYetImplemented ```go // AuthenticateWebsocket sends an authentication message to the websocket -func (f *FTX) AuthenticateWebsocket(ctx context.Context) error { - return f.WsAuth(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.WsAuth(ctx) } ``` diff --git a/engine/engine_test.go b/engine/engine_test.go index b2e8ab243cf..cbb41cea74e 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -464,8 +464,8 @@ func TestSetupExchanges(t *testing.T) { } e.ExchangeManager = NewExchangeManager() - exchLoader(new(bitstamp.Bitstamp)) - exchLoader(new(bitfinex.Bitfinex)) + exchLoader(new(bitstamp.Exchange)) + exchLoader(new(bitfinex.Exchange)) assert.ElementsMatch(t, []string{"Bitstamp", "Bitfinex"}, e.Config.GetEnabledExchanges()) t.Run("Load specific exchange", func(t *testing.T) { diff --git a/engine/exchange_manager_test.go b/engine/exchange_manager_test.go index 22c322fe77f..b594f909c71 100644 --- a/engine/exchange_manager_test.go +++ b/engine/exchange_manager_test.go @@ -13,7 +13,7 @@ import ( ) type broken struct { - bitfinex.Bitfinex + bitfinex.Exchange } func (b *broken) Shutdown() error { return errExpectedTestError } @@ -39,7 +39,7 @@ func TestExchangeManagerAdd(t *testing.T) { err = m.Add(nil) require.ErrorIs(t, err, errExchangeIsNil) - b := new(bitfinex.Bitfinex) + b := new(bitfinex.Exchange) b.SetDefaults() err = m.Add(b) require.NoError(t, err) @@ -70,7 +70,7 @@ func TestExchangeManagerGetExchanges(t *testing.T) { if len(exchanges) != 0 { t.Error("unexpected value") } - b := new(bitfinex.Bitfinex) + b := new(bitfinex.Exchange) b.SetDefaults() err = m.Add(b) require.NoError(t, err) @@ -98,7 +98,7 @@ func TestExchangeManagerRemoveExchange(t *testing.T) { err = m.RemoveExchange("Bitfinex") require.ErrorIs(t, err, ErrExchangeNotFound) - b := new(bitfinex.Bitfinex) + b := new(bitfinex.Exchange) b.SetDefaults() err = m.Add(b) require.NoError(t, err) @@ -148,7 +148,7 @@ func TestNewExchangeByName(t *testing.T) { } } - load := &bitfinex.Bitfinex{} + load := &bitfinex.Exchange{} load.SetDefaults() err = m.Add(load) diff --git a/engine/helpers.go b/engine/helpers.go index 3b1c12b01b1..3bfde4f6a64 100644 --- a/engine/helpers.go +++ b/engine/helpers.go @@ -967,53 +967,53 @@ func genCert(targetDir string) error { func NewSupportedExchangeByName(name string) (exchange.IBotExchange, error) { switch strings.ToLower(name) { case "binanceus": - return new(binanceus.Binanceus), nil + return new(binanceus.Exchange), nil case "binance": - return new(binance.Binance), nil + return new(binance.Exchange), nil case "bitfinex": - return new(bitfinex.Bitfinex), nil + return new(bitfinex.Exchange), nil case "bitflyer": - return new(bitflyer.Bitflyer), nil + return new(bitflyer.Exchange), nil case "bithumb": - return new(bithumb.Bithumb), nil + return new(bithumb.Exchange), nil case "bitmex": - return new(bitmex.Bitmex), nil + return new(bitmex.Exchange), nil case "bitstamp": - return new(bitstamp.Bitstamp), nil + return new(bitstamp.Exchange), nil case "btc markets": - return new(btcmarkets.BTCMarkets), nil + return new(btcmarkets.Exchange), nil case "btse": - return new(btse.BTSE), nil + return new(btse.Exchange), nil case "bybit": - return new(bybit.Bybit), nil + return new(bybit.Exchange), nil case "coinut": - return new(coinut.COINUT), nil + return new(coinut.Exchange), nil case "deribit": - return new(deribit.Deribit), nil + return new(deribit.Exchange), nil case "exmo": - return new(exmo.EXMO), nil + return new(exmo.Exchange), nil case "coinbasepro": - return new(coinbasepro.CoinbasePro), nil + return new(coinbasepro.Exchange), nil case "gateio": - return new(gateio.Gateio), nil + return new(gateio.Exchange), nil case "gemini": - return new(gemini.Gemini), nil + return new(gemini.Exchange), nil case "hitbtc": - return new(hitbtc.HitBTC), nil + return new(hitbtc.Exchange), nil case "huobi": - return new(huobi.HUOBI), nil + return new(huobi.Exchange), nil case "kraken": - return new(kraken.Kraken), nil + return new(kraken.Exchange), nil case "kucoin": - return new(kucoin.Kucoin), nil + return new(kucoin.Exchange), nil case "lbank": - return new(lbank.Lbank), nil + return new(lbank.Exchange), nil case "okx": - return new(okx.Okx), nil + return new(okx.Exchange), nil case "poloniex": - return new(poloniex.Poloniex), nil + return new(poloniex.Exchange), nil case "yobit": - return new(yobit.Yobit), nil + return new(yobit.Exchange), nil default: return nil, fmt.Errorf("%q, %w", name, ErrExchangeNotFound) } diff --git a/engine/rpcserver_test.go b/engine/rpcserver_test.go index d92eb9d98d9..1b8fcb39689 100644 --- a/engine/rpcserver_test.go +++ b/engine/rpcserver_test.go @@ -1471,7 +1471,7 @@ func TestCheckVars(t *testing.T) { err := checkParams("Binance", e, asset.Spot, currency.NewBTCUSDT()) assert.ErrorIs(t, err, errExchangeNotLoaded, "checkParams should error correctly") - e = &binance.Binance{} + e = &binance.Exchange{} err = checkParams("Binance", e, asset.Spot, currency.NewBTCUSDT()) assert.ErrorIs(t, err, errExchangeNotEnabled, "checkParams should error correctly") diff --git a/engine/withdraw_manager_test.go b/engine/withdraw_manager_test.go index e7535422d49..6b841864db6 100644 --- a/engine/withdraw_manager_test.go +++ b/engine/withdraw_manager_test.go @@ -23,7 +23,7 @@ const ( func withdrawManagerTestHelper(t *testing.T) (*ExchangeManager, *portfolioManager) { t.Helper() em := NewExchangeManager() - b := new(okx.Okx) + b := new(okx.Exchange) cfg, err := exchange.GetDefaultConfig(t.Context(), b) if err != nil { t.Fatal(err) diff --git a/exchanges/alphapoint/alphapoint.go b/exchanges/alphapoint/alphapoint.go index f0cc390f15f..7630d163f6e 100644 --- a/exchanges/alphapoint/alphapoint.go +++ b/exchanges/alphapoint/alphapoint.go @@ -42,20 +42,20 @@ const ( alphapointOrderFee = "GetOrderFee" ) -// Alphapoint is the overarching type across the alphapoint package -type Alphapoint struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Alphapoint +type Exchange struct { exchange.Base WebsocketConn *gws.Conn } // GetTicker returns current ticker information from Alphapoint for a selected // currency pair ie "BTCUSD" -func (a *Alphapoint) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { req := make(map[string]any) req["productPair"] = currencyPair response := Ticker{} - err := a.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointTicker, @@ -76,14 +76,14 @@ func (a *Alphapoint) GetTicker(ctx context.Context, currencyPair string) (Ticker // AlphaPoint Exchange. To begin from the most recent trade, set startIndex to // 0 (default: 0) // Count: specifies the number of trades to return (default: 10) -func (a *Alphapoint) GetTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { +func (e *Exchange) GetTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { req := make(map[string]any) req["ins"] = currencyPair req["startIndex"] = startIndex req["Count"] = count response := Trades{} - err := a.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointTrades, req, &response) if err != nil { return response, err @@ -96,12 +96,12 @@ func (a *Alphapoint) GetTrades(ctx context.Context, currencyPair string, startIn // GetOrderbook fetches the current orderbook for a given currency pair // CurrencyPair - trade pair (ex: “BTCUSD”) -func (a *Alphapoint) GetOrderbook(ctx context.Context, currencyPair string) (Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, currencyPair string) (Orderbook, error) { req := make(map[string]any) req["productPair"] = currencyPair response := Orderbook{} - err := a.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointOrderbook, req, &response) if err != nil { return response, err @@ -113,10 +113,10 @@ func (a *Alphapoint) GetOrderbook(ctx context.Context, currencyPair string) (Ord } // GetProductPairs gets the currency pairs currently traded on alphapoint -func (a *Alphapoint) GetProductPairs(ctx context.Context) (ProductPairs, error) { +func (e *Exchange) GetProductPairs(ctx context.Context) (ProductPairs, error) { response := ProductPairs{} - err := a.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointProductPairs, nil, &response) if err != nil { return response, err @@ -128,10 +128,10 @@ func (a *Alphapoint) GetProductPairs(ctx context.Context) (ProductPairs, error) } // GetProducts gets the currency products currently supported on alphapoint -func (a *Alphapoint) GetProducts(ctx context.Context) (Products, error) { +func (e *Exchange) GetProducts(ctx context.Context) (Products, error) { response := Products{} - err := a.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointProducts, nil, &response) if err != nil { return response, err @@ -148,7 +148,7 @@ func (a *Alphapoint) GetProducts(ctx context.Context) (Products, error) { // Email - Email address // Phone - Phone number (ex: “+12223334444”) // Password - Minimum 8 characters -func (a *Alphapoint) CreateAccount(ctx context.Context, firstName, lastName, email, phone, password string) error { +func (e *Exchange) CreateAccount(ctx context.Context, firstName, lastName, email, phone, password string) error { if len(password) < 8 { return errors.New( "alphapoint Error - Create account - Password must be 8 characters or more", @@ -163,7 +163,7 @@ func (a *Alphapoint) CreateAccount(ctx context.Context, firstName, lastName, ema req["password"] = password response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCreateAccount, req, &response) if err != nil { return fmt.Errorf("unable to create account. Reason: %s", err) @@ -175,10 +175,10 @@ func (a *Alphapoint) CreateAccount(ctx context.Context, firstName, lastName, ema } // GetUserInfo returns current account user information -func (a *Alphapoint) GetUserInfo(ctx context.Context) (UserInfo, error) { +func (e *Exchange) GetUserInfo(ctx context.Context) (UserInfo, error) { response := UserInfo{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointUserInfo, @@ -202,7 +202,7 @@ func (a *Alphapoint) GetUserInfo(ctx context.Context) (UserInfo, error) { // Cell2FAValue - Cell phone number, required for Authentication // Use2FAForWithdraw - “true” or “false” set to true for using 2FA for // withdrawals -func (a *Alphapoint) SetUserInfo(ctx context.Context, firstName, lastName, cell2FACountryCode, cell2FAValue string, useAuthy2FA, use2FAForWithdraw bool) (UserInfoSet, error) { +func (e *Exchange) SetUserInfo(ctx context.Context, firstName, lastName, cell2FACountryCode, cell2FAValue string, useAuthy2FA, use2FAForWithdraw bool) (UserInfoSet, error) { response := UserInfoSet{} userInfoKVPs := []UserInfoKVP{ @@ -235,7 +235,7 @@ func (a *Alphapoint) SetUserInfo(ctx context.Context, firstName, lastName, cell2 req := make(map[string]any) req["userInfoKVP"] = userInfoKVPs - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointUserInfo, @@ -252,10 +252,10 @@ func (a *Alphapoint) SetUserInfo(ctx context.Context, firstName, lastName, cell2 } // GetAccountInformation returns account info -func (a *Alphapoint) GetAccountInformation(ctx context.Context) (AccountInfo, error) { +func (e *Exchange) GetAccountInformation(ctx context.Context) (AccountInfo, error) { response := AccountInfo{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointAccountInfo, @@ -275,14 +275,14 @@ func (a *Alphapoint) GetAccountInformation(ctx context.Context) (AccountInfo, er // CurrencyPair - Instrument code (ex: “BTCUSD”) // StartIndex - Starting index, if less than 0 then start from the beginning // Count - Returns last trade, (Default: 30) -func (a *Alphapoint) GetAccountTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { +func (e *Exchange) GetAccountTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { req := make(map[string]any) req["ins"] = currencyPair req["startIndex"] = startIndex req["count"] = count response := Trades{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointAccountTrades, @@ -299,10 +299,10 @@ func (a *Alphapoint) GetAccountTrades(ctx context.Context, currencyPair string, } // GetDepositAddresses generates a deposit address -func (a *Alphapoint) GetDepositAddresses(ctx context.Context) ([]DepositAddresses, error) { +func (e *Exchange) GetDepositAddresses(ctx context.Context) ([]DepositAddresses, error) { response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointDepositAddresses, @@ -323,7 +323,7 @@ func (a *Alphapoint) GetDepositAddresses(ctx context.Context) ([]DepositAddresse // product - Currency name (ex: “BTC”) // amount - Amount (ex: “.011”) // address - Withdraw address -func (a *Alphapoint) WithdrawCoins(ctx context.Context, symbol, product, address string, amount float64) error { +func (e *Exchange) WithdrawCoins(ctx context.Context, symbol, product, address string, amount float64) error { req := make(map[string]any) req["ins"] = symbol req["product"] = product @@ -331,7 +331,7 @@ func (a *Alphapoint) WithdrawCoins(ctx context.Context, symbol, product, address req["sendToAddress"] = address response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointWithdraw, @@ -347,7 +347,7 @@ func (a *Alphapoint) WithdrawCoins(ctx context.Context, symbol, product, address return nil } -func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderTypeNumber int64) { +func (e *Exchange) convertOrderTypeToOrderTypeNumber(orderType string) (orderTypeNumber int64) { if orderType == order.Market.String() { orderTypeNumber = 1 } @@ -361,8 +361,8 @@ func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderT // orderType - “1” for market orders, “0” for limit orders // quantity - Quantity // price - Price in USD -func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType string, quantity, price float64) (int64, error) { - orderTypeNumber := a.convertOrderTypeToOrderTypeNumber(orderType) +func (e *Exchange) CreateOrder(ctx context.Context, symbol, side, orderType string, quantity, price float64) (int64, error) { + orderTypeNumber := e.convertOrderTypeToOrderTypeNumber(orderType) req := make(map[string]any) req["ins"] = symbol req["side"] = side @@ -371,7 +371,7 @@ func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType st req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCreateOrder, @@ -395,14 +395,14 @@ func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType st // book. A buy order will be modified to the highest bid and a sell order will // be modified to the lowest ask price. “1” means "Execute now", which will // convert a limit order into a market order. -func (a *Alphapoint) ModifyExistingOrder(ctx context.Context, symbol string, orderID, action int64) (int64, error) { +func (e *Exchange) ModifyExistingOrder(ctx context.Context, symbol string, orderID, action int64) (int64, error) { req := make(map[string]any) req["ins"] = symbol req["serverOrderId"] = orderID req["modifyAction"] = action response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointModifyOrder, @@ -421,13 +421,13 @@ func (a *Alphapoint) ModifyExistingOrder(ctx context.Context, symbol string, ord // CancelExistingOrder cancels an order that has not been executed. // symbol - Instrument code (ex: “BTCUSD”) // OrderID - Order id (ex: 1000) -func (a *Alphapoint) CancelExistingOrder(ctx context.Context, orderID int64, omsid string) (int64, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64, omsid string) (int64, error) { req := make(map[string]any) req["OrderId"] = orderID req["OMSId"] = omsid response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCancelOrder, @@ -445,12 +445,12 @@ func (a *Alphapoint) CancelExistingOrder(ctx context.Context, orderID int64, oms // CancelAllExistingOrders cancels all open orders by symbol. // symbol - Instrument code (ex: “BTCUSD”) -func (a *Alphapoint) CancelAllExistingOrders(ctx context.Context, omsid string) error { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context, omsid string) error { req := make(map[string]any) req["OMSId"] = omsid response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCancelAllOrders, @@ -467,10 +467,10 @@ func (a *Alphapoint) CancelAllExistingOrders(ctx context.Context, omsid string) } // GetOrders returns all current open orders -func (a *Alphapoint) GetOrders(ctx context.Context) ([]OpenOrders, error) { +func (e *Exchange) GetOrders(ctx context.Context) ([]OpenOrders, error) { response := OrderInfo{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointOpenOrders, @@ -491,7 +491,7 @@ func (a *Alphapoint) GetOrders(ctx context.Context) ([]OpenOrders, error) { // side - “buy” or “sell” // quantity - Quantity // price - Price in USD -func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quantity, price float64) (float64, error) { +func (e *Exchange) GetOrderFee(ctx context.Context, symbol, side string, quantity, price float64) (float64, error) { req := make(map[string]any) req["ins"] = symbol req["side"] = side @@ -499,7 +499,7 @@ func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quant req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} - err := a.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointOrderFee, @@ -516,8 +516,8 @@ func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quant } // SendHTTPRequest sends an unauthenticated HTTP request -func (a *Alphapoint) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error { - endpoint, err := a.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -535,30 +535,30 @@ func (a *Alphapoint) SendHTTPRequest(ctx context.Context, ep exchange.URL, metho Path: path, Headers: headers, Result: result, - Verbose: a.Verbose, - HTTPDebugging: a.HTTPDebugging, - HTTPRecording: a.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return a.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { item.Body = bytes.NewBuffer(PayloadJSON) return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated request -func (a *Alphapoint) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error { - creds, err := a.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := a.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } - n := a.Requester.GetNonce(nonce.UnixNano) + n := e.Requester.GetNonce(nonce.UnixNano) headers := make(map[string]string) headers["Content-Type"] = "application/json" @@ -586,12 +586,12 @@ func (a *Alphapoint) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchan Headers: headers, Result: result, NonceEnabled: true, - Verbose: a.Verbose, - HTTPDebugging: a.HTTPDebugging, - HTTPRecording: a.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return a.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { item.Body = bytes.NewBuffer(PayloadJSON) return item, nil }, request.AuthenticatedRequest) diff --git a/exchanges/alphapoint/alphapoint_test.go b/exchanges/alphapoint/alphapoint_test.go index 4b29a8cc9da..775999bb4e1 100644 --- a/exchanges/alphapoint/alphapoint_test.go +++ b/exchanges/alphapoint/alphapoint_test.go @@ -22,15 +22,15 @@ const ( canManipulateRealOrders = false ) -var a *Alphapoint +var e = &Exchange{} func TestMain(m *testing.M) { - a = new(Alphapoint) - a.SetDefaults() + e = new(Exchange) + e.SetDefaults() if apiKey != "" && apiSecret != "" { - a.API.AuthenticatedSupport = true - a.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -41,12 +41,12 @@ func TestGetTicker(t *testing.T) { var ticker Ticker var err error if onlineTest { - ticker, err = a.GetTicker(t.Context(), "BTCUSD") + ticker, err = e.GetTicker(t.Context(), "BTCUSD") if err != nil { t.Fatal("Alphapoint GetTicker init error: ", err) } - _, err = a.GetTicker(t.Context(), "wigwham") + _, err = e.GetTicker(t.Context(), "wigwham") if err == nil { t.Error("Alphapoint GetTicker Expected error") } @@ -75,12 +75,12 @@ func TestGetTrades(t *testing.T) { var trades Trades var err error if onlineTest { - trades, err = a.GetTrades(t.Context(), "BTCUSD", 0, 10) + trades, err = e.GetTrades(t.Context(), "BTCUSD", 0, 10) if err != nil { t.Fatalf("Init error: %s", err) } - _, err = a.GetTrades(t.Context(), "wigwham", 0, 10) + _, err = e.GetTrades(t.Context(), "wigwham", 0, 10) if err == nil { t.Fatal("GetTrades Expected error") } @@ -113,12 +113,12 @@ func TestGetOrderbook(t *testing.T) { var orderBook Orderbook var err error if onlineTest { - orderBook, err = a.GetOrderbook(t.Context(), "BTCUSD") + orderBook, err = e.GetOrderbook(t.Context(), "BTCUSD") if err != nil { t.Errorf("Init error: %s", err) } - _, err = a.GetOrderbook(t.Context(), "wigwham") + _, err = e.GetOrderbook(t.Context(), "wigwham") if err == nil { t.Error("GetOrderbook() Expected error") } @@ -156,7 +156,7 @@ func TestGetProductPairs(t *testing.T) { var err error if onlineTest { - products, err = a.GetProductPairs(t.Context()) + products, err = e.GetProductPairs(t.Context()) if err != nil { t.Errorf("Init error: %s", err) } @@ -194,7 +194,7 @@ func TestGetProducts(t *testing.T) { var err error if onlineTest { - products, err = a.GetProducts(t.Context()) + products, err = e.GetProducts(t.Context()) if err != nil { t.Errorf("Init error: %s", err) } @@ -228,19 +228,19 @@ func TestGetProducts(t *testing.T) { func TestCreateAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - err := a.CreateAccount(t.Context(), + err := e.CreateAccount(t.Context(), "test", "account", "something@something.com", "0292383745", "lolcat123") if err != nil { t.Errorf("Init error: %s", err) } - err = a.CreateAccount(t.Context(), + err = e.CreateAccount(t.Context(), "test", "account", "something@something.com", "0292383745", "bla") if err == nil { t.Errorf("CreateAccount() Expected error") } - err = a.CreateAccount(t.Context(), "", "", "", "", "lolcat123") + err = e.CreateAccount(t.Context(), "", "", "", "", "lolcat123") if err == nil { t.Errorf("CreateAccount() Expected error") } @@ -248,9 +248,9 @@ func TestCreateAccount(t *testing.T) { func TestGetUserInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.GetUserInfo(t.Context()) + _, err := e.GetUserInfo(t.Context()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -258,9 +258,9 @@ func TestGetUserInfo(t *testing.T) { func TestSetUserInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.SetUserInfo(t.Context(), + _, err := e.SetUserInfo(t.Context(), "bla", "bla", "1", "meh", true, true) if err == nil { t.Error("GetUserInfo() Expected error") @@ -269,9 +269,9 @@ func TestSetUserInfo(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -279,9 +279,9 @@ func TestGetAccountInfo(t *testing.T) { func TestGetAccountTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.GetAccountTrades(t.Context(), "", 1, 2) + _, err := e.GetAccountTrades(t.Context(), "", 1, 2) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -289,9 +289,9 @@ func TestGetAccountTrades(t *testing.T) { func TestGetDepositAddresses(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.GetDepositAddresses(t.Context()) + _, err := e.GetDepositAddresses(t.Context()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -299,9 +299,9 @@ func TestGetDepositAddresses(t *testing.T) { func TestWithdrawCoins(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - err := a.WithdrawCoins(t.Context(), "", "", "", 0.01) + err := e.WithdrawCoins(t.Context(), "", "", "", 0.01) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -309,9 +309,9 @@ func TestWithdrawCoins(t *testing.T) { func TestCreateOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.CreateOrder(t.Context(), + _, err := e.CreateOrder(t.Context(), "", "", order.Limit.String(), 0.01, 0) if err == nil { t.Error("GetUserInfo() Expected error") @@ -320,9 +320,9 @@ func TestCreateOrder(t *testing.T) { func TestModifyExistingOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.ModifyExistingOrder(t.Context(), "", 1, 1) + _, err := e.ModifyExistingOrder(t.Context(), "", 1, 1) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -330,9 +330,9 @@ func TestModifyExistingOrder(t *testing.T) { func TestCancelAllExistingOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - err := a.CancelAllExistingOrders(t.Context(), "") + err := e.CancelAllExistingOrders(t.Context(), "") if err == nil { t.Error("GetUserInfo() Expected error") } @@ -340,9 +340,9 @@ func TestCancelAllExistingOrders(t *testing.T) { func TestGetOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.GetOrders(t.Context()) + _, err := e.GetOrders(t.Context()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -350,9 +350,9 @@ func TestGetOrders(t *testing.T) { func TestGetOrderFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := a.GetOrderFee(t.Context(), "", "", 1, 1) + _, err := e.GetOrderFee(t.Context(), "", "", 1, 1) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -361,7 +361,7 @@ func TestGetOrderFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := a.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -375,10 +375,10 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := a.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(a) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(a) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -391,10 +391,10 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := a.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(a) && err != nil { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(a) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -404,10 +404,10 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, a, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: a.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "_", Base: currency.BTC, @@ -421,11 +421,11 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := a.SubmitOrder(t.Context(), orderSubmission) - if !sharedtestvalues.AreAPICredentialsSet(a) && err == nil { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(a) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) if response.Status != order.New { @@ -436,7 +436,7 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, a, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.BTC, currency.LTC) orderCancellation := &order.Cancel{ @@ -446,18 +446,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := a.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(a) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(a) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, a, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.BTC, currency.LTC) orderCancellation := &order.Cancel{ @@ -467,11 +467,11 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := a.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(a) && err == nil { + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(a) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } @@ -482,8 +482,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a, canManipulateRealOrders) - _, err := a.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -491,7 +491,7 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - _, err := a.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{}) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not implemented', received %v", err) @@ -500,9 +500,9 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := a.WithdrawFiatFunds(t.Context(), + _, err := e.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) @@ -511,9 +511,9 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, a, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := a.WithdrawFiatFundsToInternationalBank(t.Context(), &withdraw.Request{}) + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdraw.Request{}) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) } @@ -525,7 +525,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = a.GetRecentTrades(t.Context(), currencyPair, asset.Spot) + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Spot) if err != nil && err != common.ErrNotYetImplemented { t.Error(err) } @@ -537,7 +537,7 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = a.GetHistoricTrades(t.Context(), + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrNotYetImplemented { t.Error(err) diff --git a/exchanges/alphapoint/alphapoint_websocket.go b/exchanges/alphapoint/alphapoint_websocket.go index 4a6c7204092..6b686a34335 100644 --- a/exchanges/alphapoint/alphapoint_websocket.go +++ b/exchanges/alphapoint/alphapoint_websocket.go @@ -14,35 +14,35 @@ const ( ) // WebsocketClient starts a new webstocket connection -func (a *Alphapoint) WebsocketClient() { - for a.Enabled { +func (e *Exchange) WebsocketClient() { + for e.Enabled { var dialer gws.Dialer var err error var httpResp *http.Response - endpoint, err := a.API.Endpoints.GetURL(exchange.WebsocketSpot) + endpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { log.Errorln(log.WebsocketMgr, err) } - a.WebsocketConn, httpResp, err = dialer.Dial(endpoint, http.Header{}) + e.WebsocketConn, httpResp, err = dialer.Dial(endpoint, http.Header{}) httpResp.Body.Close() // not used, so safely free the body if err != nil { - log.Errorf(log.ExchangeSys, "%s Unable to connect to Websocket. Error: %s\n", a.Name, err) + log.Errorf(log.ExchangeSys, "%s Unable to connect to Websocket. Error: %s\n", e.Name, err) continue } - if a.Verbose { - log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", a.Name) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", e.Name) } - err = a.WebsocketConn.WriteMessage(gws.TextMessage, []byte(`{"messageType": "logon"}`)) + err = e.WebsocketConn.WriteMessage(gws.TextMessage, []byte(`{"messageType": "logon"}`)) if err != nil { log.Errorln(log.ExchangeSys, err) return } - for a.Enabled { - msgType, resp, err := a.WebsocketConn.ReadMessage() + for e.Enabled { + msgType, resp, err := e.WebsocketConn.ReadMessage() if err != nil { log.Errorln(log.ExchangeSys, err) break @@ -70,7 +70,7 @@ func (a *Alphapoint) WebsocketClient() { } } } - a.WebsocketConn.Close() - log.Debugf(log.ExchangeSys, "%s Websocket client disconnected.", a.Name) + e.WebsocketConn.Close() + log.Debugf(log.ExchangeSys, "%s Websocket client disconnected.", e.Name) } } diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index 584b3732647..32b8bfaebe5 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -27,22 +27,22 @@ import ( ) // SetDefaults sets current default settings -func (a *Alphapoint) SetDefaults() { - a.Name = "Alphapoint" - a.Enabled = true - a.Verbose = true - a.API.Endpoints = a.NewEndpoints() - err := a.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ +func (e *Exchange) SetDefaults() { + e.Name = "Alphapoint" + e.Enabled = true + e.Verbose = true + e.API.Endpoints = e.NewEndpoints() + err := e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: alphapointDefaultAPIURL, exchange.WebsocketSpot: alphapointDefaultWebsocketURL, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - a.API.CredentialsValidator.RequiresKey = true - a.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true - a.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -72,7 +72,7 @@ func (a *Alphapoint) SetDefaults() { }, } - a.Requester, err = request.New(a.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) if err != nil { log.Errorln(log.ExchangeSys, err) @@ -80,32 +80,32 @@ func (a *Alphapoint) SetDefaults() { } // Setup takes in the supplied exchange configuration details and sets params -func (a *Alphapoint) Setup(_ *config.Exchange) error { +func (e *Exchange) Setup(_ *config.Exchange) error { return common.ErrFunctionNotSupported } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (a *Alphapoint) FetchTradablePairs(_ context.Context, _ asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(_ context.Context, _ asset.Item) (currency.Pairs, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (a *Alphapoint) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (a *Alphapoint) UpdateTradablePairs(_ context.Context, _ bool) error { +func (e *Exchange) UpdateTradablePairs(_ context.Context, _ bool) error { return common.ErrFunctionNotSupported } // UpdateAccountInfo retrieves balances for all enabled currencies on the // Alphapoint exchange -func (a *Alphapoint) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = a.Name - acc, err := a.GetAccountInformation(ctx) + response.Exchange = e.Name + acc, err := e.GetAccountInformation(ctx) if err != nil { return response, err } @@ -125,7 +125,7 @@ func (a *Alphapoint) UpdateAccountInfo(ctx context.Context, assetType asset.Item AssetType: assetType, }) - creds, err := a.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -139,19 +139,19 @@ func (a *Alphapoint) UpdateAccountInfo(ctx context.Context, assetType asset.Item } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (a *Alphapoint) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (a *Alphapoint) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := a.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - tick, err := a.GetTicker(ctx, p.String()) + tick, err := e.GetTicker(ctx, p.String()) if err != nil { return nil, err } @@ -164,26 +164,26 @@ func (a *Alphapoint) UpdateTicker(ctx context.Context, p currency.Pair, assetTyp High: tick.High, Volume: tick.Volume, Last: tick.Last, - ExchangeName: a.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { return nil, err } - return ticker.GetTicker(a.Name, p, assetType) + return ticker.GetTicker(e.Name, p, assetType) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := a.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } orderBook := new(orderbook.Book) - orderbookNew, err := a.GetOrderbook(ctx, p.String()) + orderbookNew, err := e.GetOrderbook(ctx, p.String()) if err != nil { return orderBook, err } @@ -205,7 +205,7 @@ func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, asset } orderBook.Pair = p - orderBook.Exchange = a.Name + orderBook.Exchange = e.Name orderBook.Asset = assetType err = orderBook.Process() @@ -213,44 +213,44 @@ func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, asset return orderBook, err } - return orderbook.Get(a.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (a *Alphapoint) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { // https://alphapoint.github.io/slate/#generatetreasuryactivityreport return nil, common.ErrNotYetImplemented } // GetWithdrawalsHistory returns previous withdrawals data -func (a *Alphapoint) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (a *Alphapoint) GetRecentTrades(_ context.Context, _ currency.Pair, _ asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(_ context.Context, _ currency.Pair, _ asset.Item) ([]trade.Data, error) { return nil, common.ErrNotYetImplemented } // GetHistoricTrades returns historic trade data within the timeframe provided -func (a *Alphapoint) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrNotYetImplemented } // SubmitOrder submits a new order and returns a true value when // successfully submitted -func (a *Alphapoint) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(a.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := a.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } - response, err := a.CreateOrder(ctx, + response, err := e.CreateOrder(ctx, fPair.String(), s.Side.String(), s.Type.String(), @@ -264,12 +264,12 @@ func (a *Alphapoint) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (a *Alphapoint) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrNotYetImplemented } // CancelOrder cancels an order by its corresponding ID number -func (a *Alphapoint) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -277,32 +277,32 @@ func (a *Alphapoint) CancelOrder(ctx context.Context, o *order.Cancel) error { if err != nil { return err } - _, err = a.CancelExistingOrder(ctx, orderIDInt, o.AccountID) + _, err = e.CancelExistingOrder(ctx, orderIDInt, o.AccountID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (a *Alphapoint) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders for a given account -func (a *Alphapoint) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } return order.CancelAllResponse{}, - a.CancelAllExistingOrders(ctx, orderCancellation.AccountID) + e.CancelAllExistingOrders(ctx, orderCancellation.AccountID) } // GetOrderInfo returns order information based on order ID -func (a *Alphapoint) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { return nil, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (a *Alphapoint) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - addresses, err := a.GetDepositAddresses(ctx) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + addresses, err := e.GetDepositAddresses(ctx) if err != nil { return nil, err } @@ -319,34 +319,34 @@ func (a *Alphapoint) GetDepositAddress(ctx context.Context, cryptocurrency curre // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (a *Alphapoint) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted -func (a *Alphapoint) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (a *Alphapoint) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // GetFeeByType returns an estimate of fee based on type of transaction -func (a *Alphapoint) GetFeeByType(_ context.Context, _ *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(_ context.Context, _ *exchange.FeeBuilder) (float64, error) { return 0, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open // This function is not concurrency safe due to orderSide/orderType maps -func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := a.GetOrders(ctx) + resp, err := e.GetOrders(ctx) if err != nil { return nil, err } @@ -359,7 +359,7 @@ func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.MultiOrderR } orders = append(orders, order.Detail{ Amount: resp[x].OpenOrders[y].QtyTotal, - Exchange: a.Name, + Exchange: e.Name, ExecutedAmount: resp[x].OpenOrders[y].QtyTotal - resp[x].OpenOrders[y].QtyRemaining, AccountID: strconv.FormatInt(int64(resp[x].OpenOrders[y].AccountID), 10), OrderID: strconv.FormatInt(int64(resp[x].OpenOrders[y].ServerOrderID), 10), @@ -371,19 +371,19 @@ func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.MultiOrderR }) } } - return req.Filter(a.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status // This function is not concurrency safe due to orderSide/orderType maps -func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := a.GetOrders(ctx) + resp, err := e.GetOrders(ctx) if err != nil { return nil, err } @@ -398,7 +398,7 @@ func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.MultiOrderR orders = append(orders, order.Detail{ Amount: resp[x].OpenOrders[y].QtyTotal, AccountID: strconv.FormatInt(int64(resp[x].OpenOrders[y].AccountID), 10), - Exchange: a.Name, + Exchange: e.Name, ExecutedAmount: resp[x].OpenOrders[y].QtyTotal - resp[x].OpenOrders[y].QtyRemaining, OrderID: strconv.FormatInt(int64(resp[x].OpenOrders[y].ServerOrderID), 10), Price: resp[x].OpenOrders[y].Price, @@ -409,38 +409,38 @@ func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.MultiOrderR }) } } - return req.Filter(a.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (a *Alphapoint) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := a.UpdateAccountInfo(ctx, assetType) - return a.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (a *Alphapoint) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrNotYetImplemented } // GetHistoricCandlesExtended returns candles between a time period for a set // time interval -func (a *Alphapoint) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrNotYetImplemented } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (a *Alphapoint) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (a *Alphapoint) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (a *Alphapoint) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index c0c3f72d627..f02426a1530 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -23,8 +23,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/request" ) -// Binance is the overarching type across the Binance package -type Binance struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Binance +type Exchange struct { exchange.Base obm *orderbookManager } @@ -110,9 +110,9 @@ var ( // GetExchangeInfo returns exchange information. Check binance_types for more // information -func (b *Binance) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { +func (e *Exchange) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { var resp ExchangeInfo - return resp, b.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, exchangeInfo, spotExchangeInfo, &resp) } @@ -121,9 +121,9 @@ func (b *Binance) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { // OrderBookDataRequestParams contains the following members // symbol: string of currency pair // limit: returned limit amount -func (b *Binance) GetOrderBook(ctx context.Context, obd OrderBookDataRequestParams) (*OrderBook, error) { +func (e *Exchange) GetOrderBook(ctx context.Context, obd OrderBookDataRequestParams) (*OrderBook, error) { params := url.Values{} - symbol, err := b.FormatSymbol(obd.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(obd.Symbol, asset.Spot) if err != nil { return nil, err } @@ -131,7 +131,7 @@ func (b *Binance) GetOrderBook(ctx context.Context, obd OrderBookDataRequestPara params.Set("limit", strconv.Itoa(obd.Limit)) var resp *OrderBookData - if err := b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(orderBookDepth, params), orderbookLimit(obd.Limit), &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(orderBookDepth, params), orderbookLimit(obd.Limit), &resp); err != nil { return nil, err } @@ -155,9 +155,9 @@ func (b *Binance) GetOrderBook(ctx context.Context, obd OrderBookDataRequestPara // GetMostRecentTrades returns recent trade activity // limit: Up to 500 results returned -func (b *Binance) GetMostRecentTrades(ctx context.Context, rtr RecentTradeRequestParams) ([]RecentTrade, error) { +func (e *Exchange) GetMostRecentTrades(ctx context.Context, rtr RecentTradeRequestParams) ([]RecentTrade, error) { params := url.Values{} - symbol, err := b.FormatSymbol(rtr.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(rtr.Symbol, asset.Spot) if err != nil { return nil, err } @@ -167,7 +167,7 @@ func (b *Binance) GetMostRecentTrades(ctx context.Context, rtr RecentTradeReques path := recentTrades + "?" + params.Encode() var resp []RecentTrade - return resp, b.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } @@ -176,7 +176,7 @@ func (b *Binance) GetMostRecentTrades(ctx context.Context, rtr RecentTradeReques // symbol: string of currency pair // limit: Optional. Default 500; max 1000. // fromID: -func (b *Binance) GetHistoricalTrades(ctx context.Context, symbol string, limit int, fromID int64) ([]HistoricalTrade, error) { +func (e *Exchange) GetHistoricalTrades(ctx context.Context, symbol string, limit int, fromID int64) ([]HistoricalTrade, error) { var resp []HistoricalTrade params := url.Values{} @@ -189,18 +189,18 @@ func (b *Binance) GetHistoricalTrades(ctx context.Context, symbol string, limit path := historicalTrades + "?" + params.Encode() return resp, - b.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + e.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetUserMarginInterestHistory returns margin interest history for the user -func (b *Binance) GetUserMarginInterestHistory(ctx context.Context, assetCurrency currency.Code, isolatedSymbol currency.Pair, startTime, endTime time.Time, currentPage, size int64, archived bool) (*UserMarginInterestHistoryResponse, error) { +func (e *Exchange) GetUserMarginInterestHistory(ctx context.Context, assetCurrency currency.Code, isolatedSymbol currency.Pair, startTime, endTime time.Time, currentPage, size int64, archived bool) (*UserMarginInterestHistoryResponse, error) { params := url.Values{} if !assetCurrency.IsEmpty() { params.Set("asset", assetCurrency.String()) } if !isolatedSymbol.IsEmpty() { - fPair, err := b.FormatSymbol(isolatedSymbol, asset.Margin) + fPair, err := e.FormatSymbol(isolatedSymbol, asset.Margin) if err != nil { return nil, err } @@ -224,14 +224,14 @@ func (b *Binance) GetUserMarginInterestHistory(ctx context.Context, assetCurrenc path := marginInterestHistory + "?" + params.Encode() var resp UserMarginInterestHistoryResponse - return &resp, b.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return &resp, e.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetAggregatedTrades returns aggregated trade activity. // If more than one hour of data is requested or asked limit is not supported by exchange // then the trades are collected with multiple backend requests. // https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list -func (b *Binance) GetAggregatedTrades(ctx context.Context, arg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { +func (e *Exchange) GetAggregatedTrades(ctx context.Context, arg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { params := url.Values{} params.Set("symbol", arg.Symbol.String()) // If the user request is directly not supported by the exchange, we might be able to fulfill it @@ -259,7 +259,7 @@ func (b *Binance) GetAggregatedTrades(ctx context.Context, arg *AggregatedTradeR canBatch := arg.FromID == 0 != arg.StartTime.IsZero() if canBatch { // Split the request into multiple - return b.batchAggregateTrades(ctx, arg, params) + return e.batchAggregateTrades(ctx, arg, params) } // Can't handle this request locally or remotely @@ -268,14 +268,14 @@ func (b *Binance) GetAggregatedTrades(ctx context.Context, arg *AggregatedTradeR } var resp []AggregatedTrade path := aggregatedTrades + "?" + params.Encode() - return resp, b.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // batchAggregateTrades fetches trades in multiple requests // first phase, hourly requests until the first trade (or end time) is reached // second phase, limit requests from previous trade until end time (or limit) is reached -func (b *Binance) batchAggregateTrades(ctx context.Context, arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { +func (e *Exchange) batchAggregateTrades(ctx context.Context, arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { var resp []AggregatedTrade // prepare first request with only first hour and max limit if arg.Limit == 0 || arg.Limit > 1000 { @@ -298,7 +298,7 @@ func (b *Binance) batchAggregateTrades(ctx context.Context, arg *AggregatedTrade params.Set("startTime", strconv.FormatInt(start.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(start.Add(increment).UnixMilli(), 10)) path := aggregatedTrades + "?" + params.Encode() - err := b.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) if err != nil { return resp, fmt.Errorf("%w %v", err, arg.Symbol) @@ -316,7 +316,7 @@ func (b *Binance) batchAggregateTrades(ctx context.Context, arg *AggregatedTrade params.Set("fromId", strconv.FormatInt(fromID, 10)) path := aggregatedTrades + "?" + params.Encode() var additionalTrades []AggregatedTrade - err := b.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, @@ -354,8 +354,8 @@ func (b *Binance) batchAggregateTrades(ctx context.Context, arg *AggregatedTrade // interval: the interval time for the data // startTime: startTime filter for kline data // endTime: endTime filter for the kline data -func (b *Binance) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([]CandleStick, error) { - symbol, err := b.FormatSymbol(arg.Symbol, asset.Spot) +func (e *Exchange) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([]CandleStick, error) { + symbol, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return nil, err } @@ -373,16 +373,16 @@ func (b *Binance) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([ params.Set("endTime", strconv.FormatInt(arg.EndTime.UnixMilli(), 10)) } var resp []CandleStick - return resp, b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(candleStick, params), spotDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(candleStick, params), spotDefaultRate, &resp) } // GetAveragePrice returns current average price for a symbol. // // symbol: string of currency pair -func (b *Binance) GetAveragePrice(ctx context.Context, symbol currency.Pair) (AveragePrice, error) { +func (e *Exchange) GetAveragePrice(ctx context.Context, symbol currency.Pair) (AveragePrice, error) { resp := AveragePrice{} params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -390,20 +390,20 @@ func (b *Binance) GetAveragePrice(ctx context.Context, symbol currency.Pair) (Av path := averagePrice + "?" + params.Encode() - return resp, b.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetPriceChangeStats returns price change statistics for the last 24 hours // // symbol: string of currency pair -func (b *Binance) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) (*PriceChangeStats, error) { +func (e *Exchange) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) (*PriceChangeStats, error) { resp := PriceChangeStats{} params := url.Values{} rateLimit := spotTickerAllRate if !symbol.IsEmpty() { rateLimit = spotTicker1Rate - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -411,11 +411,11 @@ func (b *Binance) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) } path := priceChange + "?" + params.Encode() - return &resp, b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) + return &resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetTickers returns the ticker data for the last 24 hrs -func (b *Binance) GetTickers(ctx context.Context, symbols ...currency.Pair) ([]PriceChangeStats, error) { +func (e *Exchange) GetTickers(ctx context.Context, symbols ...currency.Pair) ([]PriceChangeStats, error) { var resp []PriceChangeStats symbolLength := len(symbols) params := url.Values{} @@ -434,7 +434,7 @@ func (b *Binance) GetTickers(ctx context.Context, symbols ...currency.Pair) ([]P if symbolLength > 0 { symbolValues := make([]string, symbolLength) for i := range symbols { - symbolValue, err := b.FormatSymbol(symbols[i], asset.Spot) + symbolValue, err := e.FormatSymbol(symbols[i], asset.Spot) if err != nil { return resp, err } @@ -443,19 +443,19 @@ func (b *Binance) GetTickers(ctx context.Context, symbols ...currency.Pair) ([]P params.Set("symbols", "["+strings.Join(symbolValues, ",")+"]") path += "?" + params.Encode() } - return resp, b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rl, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rl, &resp) } // GetLatestSpotPrice returns latest spot price of symbol // // symbol: string of currency pair -func (b *Binance) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (SymbolPrice, error) { +func (e *Exchange) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (SymbolPrice, error) { resp := SymbolPrice{} params := url.Values{} rateLimit := spotTickerAllRate if !symbol.IsEmpty() { rateLimit = spotDefaultRate - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -464,19 +464,19 @@ func (b *Binance) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) path := symbolPrice + "?" + params.Encode() return resp, - b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) + e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetBestPrice returns the latest best price for symbol // // symbol: string of currency pair -func (b *Binance) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestPrice, error) { +func (e *Exchange) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestPrice, error) { resp := BestPrice{} params := url.Values{} rateLimit := spotOrderbookTickerAllRate if !symbol.IsEmpty() { rateLimit = spotDefaultRate - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -485,13 +485,13 @@ func (b *Binance) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestP path := bestPrice + "?" + params.Encode() return resp, - b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) + e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // NewOrder sends a new order to Binance -func (b *Binance) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderResponse, error) { +func (e *Exchange) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderResponse, error) { var resp NewOrderResponse - if err := b.newOrder(ctx, orderEndpoint, o, &resp); err != nil { + if err := e.newOrder(ctx, orderEndpoint, o, &resp); err != nil { return resp, err } @@ -503,14 +503,14 @@ func (b *Binance) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderRes } // NewOrderTest sends a new test order to Binance -func (b *Binance) NewOrderTest(ctx context.Context, o *NewOrderRequest) error { +func (e *Exchange) NewOrderTest(ctx context.Context, o *NewOrderRequest) error { var resp NewOrderResponse - return b.newOrder(ctx, newOrderTest, o, &resp) + return e.newOrder(ctx, newOrderTest, o, &resp) } -func (b *Binance) newOrder(ctx context.Context, api string, o *NewOrderRequest, resp *NewOrderResponse) error { +func (e *Exchange) newOrder(ctx context.Context, api string, o *NewOrderRequest, resp *NewOrderResponse) error { params := url.Values{} - symbol, err := b.FormatSymbol(o.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(o.Symbol, asset.Spot) if err != nil { return err } @@ -544,14 +544,14 @@ func (b *Binance) newOrder(ctx context.Context, api string, o *NewOrderRequest, if o.NewOrderRespType != "" { params.Set("newOrderRespType", o.NewOrderRespType) } - return b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, api, params, spotOrderRate, resp) + return e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, api, params, spotOrderRate, resp) } // CancelExistingOrder sends a cancel order to Binance -func (b *Binance) CancelExistingOrder(ctx context.Context, symbol currency.Pair, orderID int64, origClientOrderID string) (CancelOrderResponse, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, symbol currency.Pair, orderID int64, origClientOrderID string) (CancelOrderResponse, error) { var resp CancelOrderResponse - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -565,19 +565,19 @@ func (b *Binance) CancelExistingOrder(ctx context.Context, symbol currency.Pair, if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodDelete, orderEndpoint, params, spotOrderRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodDelete, orderEndpoint, params, spotOrderRate, &resp) } // OpenOrders Current open orders. Get all open orders on a symbol. // Careful when accessing this with no symbol: The number of requests counted // against the rate limiter is significantly higher -func (b *Binance) OpenOrders(ctx context.Context, pair currency.Pair) ([]QueryOrderData, error) { +func (e *Exchange) OpenOrders(ctx context.Context, pair currency.Pair) ([]QueryOrderData, error) { var resp []QueryOrderData params := url.Values{} var p string var err error if !pair.IsEmpty() { - p, err = b.FormatSymbol(pair, asset.Spot) + p, err = e.FormatSymbol(pair, asset.Spot) if err != nil { return nil, err } @@ -587,7 +587,7 @@ func (b *Binance) OpenOrders(ctx context.Context, pair currency.Pair) ([]QueryOr // error params.Set("recvWindow", "10000") } - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, openOrders, @@ -603,11 +603,11 @@ func (b *Binance) OpenOrders(ctx context.Context, pair currency.Pair) ([]QueryOr // AllOrders Get all account orders; active, canceled, or filled. // orderId optional param // limit optional param, default 500; max 500 -func (b *Binance) AllOrders(ctx context.Context, symbol currency.Pair, orderID, limit string) ([]QueryOrderData, error) { +func (e *Exchange) AllOrders(ctx context.Context, symbol currency.Pair, orderID, limit string) ([]QueryOrderData, error) { var resp []QueryOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -618,7 +618,7 @@ func (b *Binance) AllOrders(ctx context.Context, symbol currency.Pair, orderID, if limit != "" { params.Set("limit", limit) } - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, allOrders, @@ -631,11 +631,11 @@ func (b *Binance) AllOrders(ctx context.Context, symbol currency.Pair, orderID, } // QueryOrder returns information on a past order -func (b *Binance) QueryOrder(ctx context.Context, symbol currency.Pair, origClientOrderID string, orderID int64) (QueryOrderData, error) { +func (e *Exchange) QueryOrder(ctx context.Context, symbol currency.Pair, origClientOrderID string, orderID int64) (QueryOrderData, error) { var resp QueryOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -647,7 +647,7 @@ func (b *Binance) QueryOrder(ctx context.Context, symbol currency.Pair, origClie params.Set("orderId", strconv.FormatInt(orderID, 10)) } - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, orderEndpoint, params, spotOrderQueryRate, @@ -662,7 +662,7 @@ func (b *Binance) QueryOrder(ctx context.Context, symbol currency.Pair, origClie } // GetAccount returns binance user accounts -func (b *Binance) GetAccount(ctx context.Context) (*Account, error) { +func (e *Exchange) GetAccount(ctx context.Context) (*Account, error) { type response struct { Response Account @@ -671,7 +671,7 @@ func (b *Binance) GetAccount(ctx context.Context) (*Account, error) { var resp response params := url.Values{} - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, accountInfo, params, spotAccountInformationRate, @@ -687,11 +687,11 @@ func (b *Binance) GetAccount(ctx context.Context) (*Account, error) { } // GetMarginAccount returns account information for margin accounts -func (b *Binance) GetMarginAccount(ctx context.Context) (*MarginAccount, error) { +func (e *Exchange) GetMarginAccount(ctx context.Context) (*MarginAccount, error) { var resp MarginAccount params := url.Values{} - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, marginAccountInfo, params, spotAccountInformationRate, @@ -703,8 +703,8 @@ func (b *Binance) GetMarginAccount(ctx context.Context) (*MarginAccount, error) } // SendHTTPRequest sends an unauthenticated request -func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { - endpointPath, err := b.API.Endpoints.GetURL(ePath) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } @@ -712,25 +712,25 @@ func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path Method: http.MethodGet, Path: endpointPath + path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAPIKeyHTTPRequest is a special API request where the api key is // appended to the headers without a secret -func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { - endpointPath, err := b.API.Endpoints.GetURL(ePath) +func (e *Exchange) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -742,24 +742,24 @@ func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, Path: endpointPath + path, Headers: headers, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) } // SendAuthHTTPRequest sends an authenticated HTTP request -func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpointPath, err := b.API.Endpoints.GetURL(ePath) + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } @@ -773,7 +773,7 @@ func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, m } interim := json.RawMessage{} - err = b.SendPayload(ctx, f, func() (*request.Item, error) { + err = e.SendPayload(ctx, f, func() (*request.Item, error) { params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) hmacSigned, err := crypto.GetHMAC(crypto.HashSHA256, []byte(params.Encode()), []byte(creds.Secret)) if err != nil { @@ -787,9 +787,9 @@ func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, m Path: fullPath, Headers: headers, Result: &interim, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -813,12 +813,12 @@ func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, m } // GetFee returns an estimate of fee based on type of transaction -func (b *Binance) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - multiplier, err := b.getMultiplier(ctx, feeBuilder.IsMaker) + multiplier, err := e.getMultiplier(ctx, feeBuilder.IsMaker) if err != nil { return 0, err } @@ -840,9 +840,9 @@ func getOfflineTradeFee(price, amount float64) float64 { } // getMultiplier retrieves account based taker/maker fees -func (b *Binance) getMultiplier(ctx context.Context, isMaker bool) (float64, error) { +func (e *Exchange) getMultiplier(ctx context.Context, isMaker bool) (float64, error) { var multiplier float64 - account, err := b.GetAccount(ctx) + account, err := e.GetAccount(ctx) if err != nil { return 0, err } @@ -865,9 +865,9 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 { } // GetAllCoinsInfo returns details about all supported coins -func (b *Binance) GetAllCoinsInfo(ctx context.Context) ([]CoinInfo, error) { +func (e *Exchange) GetAllCoinsInfo(ctx context.Context) ([]CoinInfo, error) { var resp []CoinInfo - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, allCoinsInfo, @@ -880,7 +880,7 @@ func (b *Binance) GetAllCoinsInfo(ctx context.Context) ([]CoinInfo, error) { } // WithdrawCrypto sends cryptocurrency to the address of your choosing -func (b *Binance) WithdrawCrypto(ctx context.Context, cryptoAsset, withdrawOrderID, network, address, addressTag, name, amount string, transactionFeeFlag bool) (string, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, cryptoAsset, withdrawOrderID, network, address, addressTag, name, amount string, transactionFeeFlag bool) (string, error) { if cryptoAsset == "" || address == "" || amount == "" { return "", errors.New("asset, address and amount must not be empty") } @@ -908,7 +908,7 @@ func (b *Binance) WithdrawCrypto(ctx context.Context, cryptoAsset, withdrawOrder } var resp WithdrawResponse - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, withdrawEndpoint, @@ -927,7 +927,7 @@ func (b *Binance) WithdrawCrypto(ctx context.Context, cryptoAsset, withdrawOrder // DepositHistory returns the deposit history based on the supplied params // status `param` used as string to prevent default value 0 (for int) interpreting as EmailSent status -func (b *Binance) DepositHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]DepositHistory, error) { +func (e *Exchange) DepositHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]DepositHistory, error) { var response []DepositHistory params := url.Values{} @@ -966,7 +966,7 @@ func (b *Binance) DepositHistory(ctx context.Context, c currency.Code, status st params.Set("limit", strconv.Itoa(limit)) } - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositHistory, @@ -981,7 +981,7 @@ func (b *Binance) DepositHistory(ctx context.Context, c currency.Code, status st // WithdrawHistory gets the status of recent withdrawals // status `param` used as string to prevent default value 0 (for int) interpreting as EmailSent status -func (b *Binance) WithdrawHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]WithdrawStatusResponse, error) { +func (e *Exchange) WithdrawHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]WithdrawStatusResponse, error) { params := url.Values{} if !c.IsEmpty() { params.Set("coin", c.String()) @@ -1019,7 +1019,7 @@ func (b *Binance) WithdrawHistory(ctx context.Context, c currency.Code, status s } var withdrawStatus []WithdrawStatusResponse - if err := b.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, withdrawHistory, @@ -1033,7 +1033,7 @@ func (b *Binance) WithdrawHistory(ctx context.Context, c currency.Code, status s } // GetDepositAddressForCurrency retrieves the wallet address for a given currency -func (b *Binance) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { +func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { params := url.Values{} params.Set("coin", currency) if chain != "" { @@ -1042,17 +1042,17 @@ func (b *Binance) GetDepositAddressForCurrency(ctx context.Context, currency, ch params.Set("recvWindow", "10000") var d DepositAddress return &d, - b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositAddress, params, spotDefaultRate, &d) + e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositAddress, params, spotDefaultRate, &d) } // GetWsAuthStreamKey will retrieve a key to use for authorised WS streaming -func (b *Binance) GetWsAuthStreamKey(ctx context.Context) (string, error) { - endpointPath, err := b.API.Endpoints.GetURL(exchange.RestSpotSupplementary) +func (e *Exchange) GetWsAuthStreamKey(ctx context.Context) (string, error) { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return "", err } - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return "", err } @@ -1065,12 +1065,12 @@ func (b *Binance) GetWsAuthStreamKey(ctx context.Context) (string, error) { Path: endpointPath + userAccountStream, Headers: headers, Result: &resp, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) if err != nil { @@ -1080,17 +1080,17 @@ func (b *Binance) GetWsAuthStreamKey(ctx context.Context) (string, error) { } // MaintainWsAuthStreamKey will keep the key alive -func (b *Binance) MaintainWsAuthStreamKey(ctx context.Context) error { - endpointPath, err := b.API.Endpoints.GetURL(exchange.RestSpotSupplementary) +func (e *Exchange) MaintainWsAuthStreamKey(ctx context.Context) error { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return err } if listenKey == "" { - listenKey, err = b.GetWsAuthStreamKey(ctx) + listenKey, err = e.GetWsAuthStreamKey(ctx) return err } - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1105,23 +1105,23 @@ func (b *Binance) MaintainWsAuthStreamKey(ctx context.Context) error { Method: http.MethodPut, Path: path, Headers: headers, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) } // FetchExchangeLimits fetches order execution limits filtered by asset -func (b *Binance) FetchExchangeLimits(ctx context.Context, a asset.Item) ([]order.MinMaxLevel, error) { +func (e *Exchange) FetchExchangeLimits(ctx context.Context, a asset.Item) ([]order.MinMaxLevel, error) { if a != asset.Spot && a != asset.Margin { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - resp, err := b.GetExchangeInfo(ctx) + resp, err := e.GetExchangeInfo(ctx) if err != nil { return nil, err } @@ -1181,7 +1181,7 @@ func (b *Binance) FetchExchangeLimits(ctx context.Context, a asset.Item) ([]orde } // CryptoLoanIncomeHistory returns crypto loan income history -func (b *Binance) CryptoLoanIncomeHistory(ctx context.Context, curr currency.Code, loanType string, startTime, endTime time.Time, limit int64) ([]CryptoLoansIncomeHistory, error) { +func (e *Exchange) CryptoLoanIncomeHistory(ctx context.Context, curr currency.Code, loanType string, startTime, endTime time.Time, limit int64) ([]CryptoLoansIncomeHistory, error) { params := url.Values{} if !curr.IsEmpty() { params.Set("asset", curr.String()) @@ -1200,11 +1200,11 @@ func (b *Binance) CryptoLoanIncomeHistory(ctx context.Context, curr currency.Cod } var resp []CryptoLoansIncomeHistory - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanIncomeHistory, params, spotDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanIncomeHistory, params, spotDefaultRate, &resp) } // CryptoLoanBorrow borrows crypto -func (b *Binance) CryptoLoanBorrow(ctx context.Context, loanCoin currency.Code, loanAmount float64, collateralCoin currency.Code, collateralAmount float64, loanTerm int64) ([]CryptoLoanBorrow, error) { +func (e *Exchange) CryptoLoanBorrow(ctx context.Context, loanCoin currency.Code, loanAmount float64, collateralCoin currency.Code, collateralAmount float64, loanTerm int64) ([]CryptoLoanBorrow, error) { if loanCoin.IsEmpty() { return nil, errLoanCoinMustBeSet } @@ -1230,11 +1230,11 @@ func (b *Binance) CryptoLoanBorrow(ctx context.Context, loanCoin currency.Code, params.Set("loanTerm", strconv.FormatInt(loanTerm, 10)) var resp []CryptoLoanBorrow - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanBorrow, params, spotDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanBorrow, params, spotDefaultRate, &resp) } // CryptoLoanBorrowHistory gets loan borrow history -func (b *Binance) CryptoLoanBorrowHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*LoanBorrowHistory, error) { +func (e *Exchange) CryptoLoanBorrowHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*LoanBorrowHistory, error) { params := url.Values{} if orderID != 0 { params.Set("orderId", strconv.FormatInt(orderID, 10)) @@ -1259,11 +1259,11 @@ func (b *Binance) CryptoLoanBorrowHistory(ctx context.Context, orderID int64, lo } var resp LoanBorrowHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanBorrowHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanBorrowHistory, params, spotDefaultRate, &resp) } // CryptoLoanOngoingOrders obtains ongoing loan orders -func (b *Binance) CryptoLoanOngoingOrders(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, current, limit int64) (*CryptoLoanOngoingOrder, error) { +func (e *Exchange) CryptoLoanOngoingOrders(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, current, limit int64) (*CryptoLoanOngoingOrder, error) { params := url.Values{} if orderID != 0 { params.Set("orderId", strconv.FormatInt(orderID, 10)) @@ -1282,11 +1282,11 @@ func (b *Binance) CryptoLoanOngoingOrders(ctx context.Context, orderID int64, lo } var resp CryptoLoanOngoingOrder - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanOngoingOrders, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanOngoingOrders, params, spotDefaultRate, &resp) } // CryptoLoanRepay repays a crypto loan -func (b *Binance) CryptoLoanRepay(ctx context.Context, orderID int64, amount float64, repayType int64, collateralReturn bool) ([]CryptoLoanRepay, error) { +func (e *Exchange) CryptoLoanRepay(ctx context.Context, orderID int64, amount float64, repayType int64, collateralReturn bool) ([]CryptoLoanRepay, error) { if orderID <= 0 { return nil, errOrderIDMustBeSet } @@ -1303,11 +1303,11 @@ func (b *Binance) CryptoLoanRepay(ctx context.Context, orderID int64, amount flo params.Set("collateralReturn", strconv.FormatBool(collateralReturn)) var resp []CryptoLoanRepay - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanRepay, params, spotDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanRepay, params, spotDefaultRate, &resp) } // CryptoLoanRepaymentHistory gets the crypto loan repayment history -func (b *Binance) CryptoLoanRepaymentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanRepayHistory, error) { +func (e *Exchange) CryptoLoanRepaymentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanRepayHistory, error) { params := url.Values{} if orderID != 0 { params.Set("orderId", strconv.FormatInt(orderID, 10)) @@ -1332,11 +1332,11 @@ func (b *Binance) CryptoLoanRepaymentHistory(ctx context.Context, orderID int64, } var resp CryptoLoanRepayHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanRepaymentHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanRepaymentHistory, params, spotDefaultRate, &resp) } // CryptoLoanAdjustLTV adjusts the LTV of a crypto loan -func (b *Binance) CryptoLoanAdjustLTV(ctx context.Context, orderID int64, reduce bool, amount float64) (*CryptoLoanAdjustLTV, error) { +func (e *Exchange) CryptoLoanAdjustLTV(ctx context.Context, orderID int64, reduce bool, amount float64) (*CryptoLoanAdjustLTV, error) { if orderID <= 0 { return nil, errOrderIDMustBeSet } @@ -1354,11 +1354,11 @@ func (b *Binance) CryptoLoanAdjustLTV(ctx context.Context, orderID int64, reduce params.Set("direction", direction) var resp CryptoLoanAdjustLTV - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanAdjustLTV, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanAdjustLTV, params, spotDefaultRate, &resp) } // CryptoLoanLTVAdjustmentHistory gets the crypto loan LTV adjustment history -func (b *Binance) CryptoLoanLTVAdjustmentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanLTVAdjustmentHistory, error) { +func (e *Exchange) CryptoLoanLTVAdjustmentHistory(ctx context.Context, orderID int64, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*CryptoLoanLTVAdjustmentHistory, error) { params := url.Values{} if orderID != 0 { params.Set("orderId", strconv.FormatInt(orderID, 10)) @@ -1383,11 +1383,11 @@ func (b *Binance) CryptoLoanLTVAdjustmentHistory(ctx context.Context, orderID in } var resp CryptoLoanLTVAdjustmentHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanLTVAdjustmentHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanLTVAdjustmentHistory, params, spotDefaultRate, &resp) } // CryptoLoanAssetsData gets the loanable assets data -func (b *Binance) CryptoLoanAssetsData(ctx context.Context, loanCoin currency.Code, vipLevel int64) (*LoanableAssetsData, error) { +func (e *Exchange) CryptoLoanAssetsData(ctx context.Context, loanCoin currency.Code, vipLevel int64) (*LoanableAssetsData, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) @@ -1397,11 +1397,11 @@ func (b *Binance) CryptoLoanAssetsData(ctx context.Context, loanCoin currency.Co } var resp LoanableAssetsData - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanableAssetsData, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanableAssetsData, params, spotDefaultRate, &resp) } // CryptoLoanCollateralAssetsData gets the collateral assets data -func (b *Binance) CryptoLoanCollateralAssetsData(ctx context.Context, collateralCoin currency.Code, vipLevel int64) (*CollateralAssetData, error) { +func (e *Exchange) CryptoLoanCollateralAssetsData(ctx context.Context, collateralCoin currency.Code, vipLevel int64) (*CollateralAssetData, error) { params := url.Values{} if !collateralCoin.IsEmpty() { params.Set("collateralCoin", collateralCoin.String()) @@ -1411,11 +1411,11 @@ func (b *Binance) CryptoLoanCollateralAssetsData(ctx context.Context, collateral } var resp CollateralAssetData - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCollateralAssetsData, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCollateralAssetsData, params, spotDefaultRate, &resp) } // CryptoLoanCheckCollateralRepayRate checks the collateral repay rate -func (b *Binance) CryptoLoanCheckCollateralRepayRate(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64) (*CollateralRepayRate, error) { +func (e *Exchange) CryptoLoanCheckCollateralRepayRate(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64) (*CollateralRepayRate, error) { if loanCoin.IsEmpty() { return nil, errLoanCoinMustBeSet } @@ -1432,11 +1432,11 @@ func (b *Binance) CryptoLoanCheckCollateralRepayRate(ctx context.Context, loanCo params.Set("repayAmount", strconv.FormatFloat(amount, 'f', -1, 64)) var resp CollateralRepayRate - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCheckCollateralRepayRate, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, loanCheckCollateralRepayRate, params, spotDefaultRate, &resp) } // CryptoLoanCustomiseMarginCall customises a loan's margin call -func (b *Binance) CryptoLoanCustomiseMarginCall(ctx context.Context, orderID int64, collateralCoin currency.Code, marginCallValue float64) (*CustomiseMarginCall, error) { +func (e *Exchange) CryptoLoanCustomiseMarginCall(ctx context.Context, orderID int64, collateralCoin currency.Code, marginCallValue float64) (*CustomiseMarginCall, error) { if marginCallValue <= 0 { return nil, errors.New("marginCallValue must not be <= 0") } @@ -1451,11 +1451,11 @@ func (b *Binance) CryptoLoanCustomiseMarginCall(ctx context.Context, orderID int params.Set("marginCall", strconv.FormatFloat(marginCallValue, 'f', -1, 64)) var resp CustomiseMarginCall - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanCustomiseMarginCall, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, loanCustomiseMarginCall, params, spotDefaultRate, &resp) } // FlexibleLoanBorrow creates a flexible loan -func (b *Binance) FlexibleLoanBorrow(ctx context.Context, loanCoin, collateralCoin currency.Code, loanAmount, collateralAmount float64) (*FlexibleLoanBorrow, error) { +func (e *Exchange) FlexibleLoanBorrow(ctx context.Context, loanCoin, collateralCoin currency.Code, loanAmount, collateralAmount float64) (*FlexibleLoanBorrow, error) { if loanCoin.IsEmpty() { return nil, errLoanCoinMustBeSet } @@ -1477,11 +1477,11 @@ func (b *Binance) FlexibleLoanBorrow(ctx context.Context, loanCoin, collateralCo } var resp FlexibleLoanBorrow - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanBorrow, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanBorrow, params, spotDefaultRate, &resp) } // FlexibleLoanOngoingOrders gets the flexible loan ongoing orders -func (b *Binance) FlexibleLoanOngoingOrders(ctx context.Context, loanCoin, collateralCoin currency.Code, current, limit int64) (*FlexibleLoanOngoingOrder, error) { +func (e *Exchange) FlexibleLoanOngoingOrders(ctx context.Context, loanCoin, collateralCoin currency.Code, current, limit int64) (*FlexibleLoanOngoingOrder, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) @@ -1497,11 +1497,11 @@ func (b *Binance) FlexibleLoanOngoingOrders(ctx context.Context, loanCoin, colla } var resp FlexibleLoanOngoingOrder - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanOngoingOrders, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanOngoingOrders, params, spotDefaultRate, &resp) } // FlexibleLoanBorrowHistory gets the flexible loan borrow history -func (b *Binance) FlexibleLoanBorrowHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanBorrowHistory, error) { +func (e *Exchange) FlexibleLoanBorrowHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanBorrowHistory, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) @@ -1523,11 +1523,11 @@ func (b *Binance) FlexibleLoanBorrowHistory(ctx context.Context, loanCoin, colla } var resp FlexibleLoanBorrowHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanBorrowHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanBorrowHistory, params, spotDefaultRate, &resp) } // FlexibleLoanRepay repays a flexible loan -func (b *Binance) FlexibleLoanRepay(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, collateralReturn, fullRepayment bool) (*FlexibleLoanRepay, error) { +func (e *Exchange) FlexibleLoanRepay(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, collateralReturn, fullRepayment bool) (*FlexibleLoanRepay, error) { if loanCoin.IsEmpty() { return nil, errLoanCoinMustBeSet } @@ -1548,11 +1548,11 @@ func (b *Binance) FlexibleLoanRepay(ctx context.Context, loanCoin, collateralCoi } var resp FlexibleLoanRepay - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanRepay, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanRepay, params, spotDefaultRate, &resp) } // FlexibleLoanRepayHistory gets the flexible loan repayment history -func (b *Binance) FlexibleLoanRepayHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanRepayHistory, error) { +func (e *Exchange) FlexibleLoanRepayHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanRepayHistory, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) @@ -1574,11 +1574,11 @@ func (b *Binance) FlexibleLoanRepayHistory(ctx context.Context, loanCoin, collat } var resp FlexibleLoanRepayHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanRepayHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanRepayHistory, params, spotDefaultRate, &resp) } // FlexibleLoanAdjustLTV adjusts the LTV of a flexible loan -func (b *Binance) FlexibleLoanAdjustLTV(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, reduce bool) (*FlexibleLoanAdjustLTV, error) { +func (e *Exchange) FlexibleLoanAdjustLTV(ctx context.Context, loanCoin, collateralCoin currency.Code, amount float64, reduce bool) (*FlexibleLoanAdjustLTV, error) { if loanCoin.IsEmpty() { return nil, errLoanCoinMustBeSet } @@ -1601,11 +1601,11 @@ func (b *Binance) FlexibleLoanAdjustLTV(ctx context.Context, loanCoin, collatera params.Set("direction", direction) var resp FlexibleLoanAdjustLTV - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanAdjustLTV, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, flexibleLoanAdjustLTV, params, spotDefaultRate, &resp) } // FlexibleLoanLTVAdjustmentHistory gets the flexible loan LTV adjustment history -func (b *Binance) FlexibleLoanLTVAdjustmentHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanLTVAdjustmentHistory, error) { +func (e *Exchange) FlexibleLoanLTVAdjustmentHistory(ctx context.Context, loanCoin, collateralCoin currency.Code, startTime, endTime time.Time, current, limit int64) (*FlexibleLoanLTVAdjustmentHistory, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) @@ -1627,27 +1627,27 @@ func (b *Binance) FlexibleLoanLTVAdjustmentHistory(ctx context.Context, loanCoin } var resp FlexibleLoanLTVAdjustmentHistory - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanLTVHistory, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanLTVHistory, params, spotDefaultRate, &resp) } // FlexibleLoanAssetsData gets the flexible loan assets data -func (b *Binance) FlexibleLoanAssetsData(ctx context.Context, loanCoin currency.Code) (*FlexibleLoanAssetsData, error) { +func (e *Exchange) FlexibleLoanAssetsData(ctx context.Context, loanCoin currency.Code) (*FlexibleLoanAssetsData, error) { params := url.Values{} if !loanCoin.IsEmpty() { params.Set("loanCoin", loanCoin.String()) } var resp FlexibleLoanAssetsData - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanAssetsData, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanAssetsData, params, spotDefaultRate, &resp) } // FlexibleCollateralAssetsData gets the flexible loan collateral assets data -func (b *Binance) FlexibleCollateralAssetsData(ctx context.Context, collateralCoin currency.Code) (*FlexibleCollateralAssetsData, error) { +func (e *Exchange) FlexibleCollateralAssetsData(ctx context.Context, collateralCoin currency.Code) (*FlexibleCollateralAssetsData, error) { params := url.Values{} if !collateralCoin.IsEmpty() { params.Set("collateralCoin", collateralCoin.String()) } var resp FlexibleCollateralAssetsData - return &resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanCollateralAssetsData, params, spotDefaultRate, &resp) + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, flexibleLoanCollateralAssetsData, params, spotDefaultRate, &resp) } diff --git a/exchanges/binance/binance_cfutures.go b/exchanges/binance/binance_cfutures.go index 609b2bbc594..3a8b902c4da 100644 --- a/exchanges/binance/binance_cfutures.go +++ b/exchanges/binance/binance_cfutures.go @@ -77,14 +77,14 @@ const ( ) // FuturesExchangeInfo stores CoinMarginedFutures, data -func (b *Binance) FuturesExchangeInfo(ctx context.Context) (CExchangeInfo, error) { +func (e *Exchange) FuturesExchangeInfo(ctx context.Context) (CExchangeInfo, error) { var resp CExchangeInfo - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesExchangeInfo, cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesExchangeInfo, cFuturesDefaultRate, &resp) } // GetFuturesOrderbook gets orderbook data for CoinMarginedFutures, -func (b *Binance) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (*OrderBook, error) { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) +func (e *Exchange) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (*OrderBook, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (b *Binance) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair, } var data *OrderbookData - if err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOrderbook+params.Encode(), rateBudget, &data); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOrderbook+params.Encode(), rateBudget, &data); err != nil { return nil, err } @@ -129,10 +129,10 @@ func (b *Binance) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair, } // GetFuturesPublicTrades gets recent public trades for CoinMarginedFutures, -func (b *Binance) GetFuturesPublicTrades(ctx context.Context, symbol currency.Pair, limit int64) ([]FuturesPublicTradesData, error) { +func (e *Exchange) GetFuturesPublicTrades(ctx context.Context, symbol currency.Pair, limit int64) ([]FuturesPublicTradesData, error) { var resp []FuturesPublicTradesData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -140,14 +140,14 @@ func (b *Binance) GetFuturesPublicTrades(ctx context.Context, symbol currency.Pa if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesHistoricalTrades gets historical public trades for CoinMarginedFutures, -func (b *Binance) GetFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { +func (e *Exchange) GetFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { var resp []UPublicTradesData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -158,14 +158,14 @@ func (b *Binance) GetFuturesHistoricalTrades(ctx context.Context, symbol currenc if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesHistoricalTrades, params, cFuturesHistoricalTradesRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesHistoricalTrades, params, cFuturesHistoricalTradesRate, &resp) } // GetPastPublicTrades gets past public trades for CoinMarginedFutures, -func (b *Binance) GetPastPublicTrades(ctx context.Context, symbol currency.Pair, limit, fromID int64) ([]FuturesPublicTradesData, error) { +func (e *Exchange) GetPastPublicTrades(ctx context.Context, symbol currency.Pair, limit, fromID int64) ([]FuturesPublicTradesData, error) { var resp []FuturesPublicTradesData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -176,14 +176,14 @@ func (b *Binance) GetPastPublicTrades(ctx context.Context, symbol currency.Pair, if fromID != 0 { params.Set("fromID", strconv.FormatInt(fromID, 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesAggregatedTradesList gets aggregated trades list for CoinMarginedFutures, -func (b *Binance) GetFuturesAggregatedTradesList(ctx context.Context, symbol currency.Pair, fromID, limit int64, startTime, endTime time.Time) ([]AggregatedTrade, error) { +func (e *Exchange) GetFuturesAggregatedTradesList(ctx context.Context, symbol currency.Pair, fromID, limit int64, startTime, endTime time.Time) ([]AggregatedTrade, error) { var resp []AggregatedTrade params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -201,11 +201,11 @@ func (b *Binance) GetFuturesAggregatedTradesList(ctx context.Context, symbol cur params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesCompressedTrades+params.Encode(), cFuturesHistoricalTradesRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesCompressedTrades+params.Encode(), cFuturesHistoricalTradesRate, &resp) } // GetIndexAndMarkPrice gets index and mark prices for CoinMarginedFutures, -func (b *Binance) GetIndexAndMarkPrice(ctx context.Context, symbol, pair string) ([]IndexMarkPrice, error) { +func (e *Exchange) GetIndexAndMarkPrice(ctx context.Context, symbol, pair string) ([]IndexMarkPrice, error) { var resp []IndexMarkPrice params := url.Values{} if symbol != "" { @@ -214,21 +214,21 @@ func (b *Binance) GetIndexAndMarkPrice(ctx context.Context, symbol, pair string) if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPrice+params.Encode(), cFuturesIndexMarkPriceRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPrice+params.Encode(), cFuturesIndexMarkPriceRate, &resp) } // GetFundingRateInfo returns extra details about funding rates -func (b *Binance) GetFundingRateInfo(ctx context.Context) ([]FundingRateInfoResponse, error) { +func (e *Exchange) GetFundingRateInfo(ctx context.Context) ([]FundingRateInfoResponse, error) { params := url.Values{} var resp []FundingRateInfoResponse - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesFundingRateInfo+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesFundingRateInfo+params.Encode(), uFuturesDefaultRate, &resp) } // GetFuturesKlineData gets futures kline data for CoinMarginedFutures, -func (b *Binance) GetFuturesKlineData(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (e *Exchange) GetFuturesKlineData(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return nil, err } @@ -251,14 +251,14 @@ func (b *Binance) GetFuturesKlineData(ctx context.Context, symbol currency.Pair, var resp []FuturesCandleStick rateBudget := getKlineRateBudget(limit) - if err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesKlineData+params.Encode(), rateBudget, &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesKlineData+params.Encode(), rateBudget, &resp); err != nil { return nil, err } return resp, nil } // GetContinuousKlineData gets continuous kline data -func (b *Binance) GetContinuousKlineData(ctx context.Context, pair, contractType, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (e *Exchange) GetContinuousKlineData(ctx context.Context, pair, contractType, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { params := url.Values{} params.Set("pair", pair) if !slices.Contains(validContractType, contractType) { @@ -282,7 +282,7 @@ func (b *Binance) GetContinuousKlineData(ctx context.Context, pair, contractType rateBudget := getKlineRateBudget(limit) var resp []FuturesCandleStick - if err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesContinuousKline+params.Encode(), rateBudget, &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesContinuousKline+params.Encode(), rateBudget, &resp); err != nil { return nil, err } @@ -290,7 +290,7 @@ func (b *Binance) GetContinuousKlineData(ctx context.Context, pair, contractType } // GetIndexPriceKlines gets continuous kline data -func (b *Binance) GetIndexPriceKlines(ctx context.Context, pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (e *Exchange) GetIndexPriceKlines(ctx context.Context, pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { params := url.Values{} params.Set("pair", pair) if limit > 0 { @@ -310,7 +310,7 @@ func (b *Binance) GetIndexPriceKlines(ctx context.Context, pair, interval string rateBudget := getKlineRateBudget(limit) var candles []FuturesCandleStick - err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesIndexKline+params.Encode(), rateBudget, &candles) + err := e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesIndexKline+params.Encode(), rateBudget, &candles) if err != nil { return nil, err } @@ -318,8 +318,8 @@ func (b *Binance) GetIndexPriceKlines(ctx context.Context, pair, interval string } // GetMarkPriceKline gets mark price kline data -func (b *Binance) GetMarkPriceKline(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) +func (e *Exchange) GetMarkPriceKline(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return nil, err } @@ -342,7 +342,7 @@ func (b *Binance) GetMarkPriceKline(ctx context.Context, symbol currency.Pair, i var candles []FuturesCandleStick rateBudget := getKlineRateBudget(limit) - err = b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPriceKline+params.Encode(), rateBudget, &candles) + err = e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPriceKline+params.Encode(), rateBudget, &candles) if err != nil { return nil, err } @@ -366,13 +366,13 @@ func getKlineRateBudget(limit uint64) request.EndpointLimit { } // GetFuturesSwapTickerChangeStats gets 24hr ticker change stats for CoinMarginedFutures, -func (b *Binance) GetFuturesSwapTickerChangeStats(ctx context.Context, symbol currency.Pair, pair string) ([]PriceChangeStats, error) { +func (e *Exchange) GetFuturesSwapTickerChangeStats(ctx context.Context, symbol currency.Pair, pair string) ([]PriceChangeStats, error) { var resp []PriceChangeStats params := url.Values{} rateLimit := cFuturesTickerPriceHistoryRate if !symbol.IsEmpty() { rateLimit = cFuturesDefaultRate - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -381,15 +381,15 @@ func (b *Binance) GetFuturesSwapTickerChangeStats(ctx context.Context, symbol cu if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTickerPriceStats+params.Encode(), rateLimit, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTickerPriceStats+params.Encode(), rateLimit, &resp) } // FuturesGetFundingHistory gets funding history for CoinMarginedFutures, -func (b *Binance) FuturesGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (e *Exchange) FuturesGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { var resp []FundingRateHistory params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -405,17 +405,17 @@ func (b *Binance) FuturesGetFundingHistory(ctx context.Context, symbol currency. params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesFundingRateHistory+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesFundingRateHistory+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesSymbolPriceTicker gets price ticker for symbol -func (b *Binance) GetFuturesSymbolPriceTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolPriceTicker, error) { +func (e *Exchange) GetFuturesSymbolPriceTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolPriceTicker, error) { var resp []SymbolPriceTicker params := url.Values{} rateLimit := cFuturesOrderbookTickerAllRate if !symbol.IsEmpty() { rateLimit = cFuturesDefaultRate - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -424,17 +424,17 @@ func (b *Binance) GetFuturesSymbolPriceTicker(ctx context.Context, symbol curren if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolPriceTicker+params.Encode(), rateLimit, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolPriceTicker+params.Encode(), rateLimit, &resp) } // GetFuturesOrderbookTicker gets orderbook ticker for symbol -func (b *Binance) GetFuturesOrderbookTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolOrderBookTicker, error) { +func (e *Exchange) GetFuturesOrderbookTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolOrderBookTicker, error) { var resp []SymbolOrderBookTicker params := url.Values{} rateLimit := cFuturesOrderbookTickerAllRate if !symbol.IsEmpty() { rateLimit = cFuturesDefaultRate - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -443,23 +443,23 @@ func (b *Binance) GetFuturesOrderbookTicker(ctx context.Context, symbol currency if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolOrderbook+params.Encode(), rateLimit, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolOrderbook+params.Encode(), rateLimit, &resp) } // OpenInterest gets open interest data for a symbol -func (b *Binance) OpenInterest(ctx context.Context, symbol currency.Pair) (OpenInterestData, error) { +func (e *Exchange) OpenInterest(ctx context.Context, symbol currency.Pair) (OpenInterestData, error) { var resp OpenInterestData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterest+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterest+params.Encode(), cFuturesDefaultRate, &resp) } // GetOpenInterestStats gets open interest stats for a symbol -func (b *Binance) GetOpenInterestStats(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]OpenInterestStats, error) { +func (e *Exchange) GetOpenInterestStats(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]OpenInterestStats, error) { var resp []OpenInterestStats params := url.Values{} if pair != "" { @@ -483,11 +483,11 @@ func (b *Binance) GetOpenInterestStats(ctx context.Context, pair, contractType, params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterestStats+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterestStats+params.Encode(), cFuturesDefaultRate, &resp) } // GetTraderFuturesAccountRatio gets a traders futures account long/short ratio -func (b *Binance) GetTraderFuturesAccountRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderAccountRatio, error) { +func (e *Exchange) GetTraderFuturesAccountRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderAccountRatio, error) { var resp []TopTraderAccountRatio params := url.Values{} params.Set("pair", pair) @@ -505,11 +505,11 @@ func (b *Binance) GetTraderFuturesAccountRatio(ctx context.Context, pair, period params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopAccountsRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopAccountsRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetTraderFuturesPositionsRatio gets a traders futures positions' long/short ratio -func (b *Binance) GetTraderFuturesPositionsRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { +func (e *Exchange) GetTraderFuturesPositionsRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { var resp []TopTraderPositionRatio params := url.Values{} params.Set("pair", pair) @@ -527,11 +527,11 @@ func (b *Binance) GetTraderFuturesPositionsRatio(ctx context.Context, pair, peri params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopPositionsRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopPositionsRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetMarketRatio gets global long/short ratio -func (b *Binance) GetMarketRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { +func (e *Exchange) GetMarketRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { var resp []TopTraderPositionRatio params := url.Values{} params.Set("pair", pair) @@ -549,11 +549,11 @@ func (b *Binance) GetMarketRatio(ctx context.Context, pair, period string, limit params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesLongShortRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesLongShortRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesTakerVolume gets futures taker buy/sell volumes -func (b *Binance) GetFuturesTakerVolume(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]TakerBuySellVolume, error) { +func (e *Exchange) GetFuturesTakerVolume(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]TakerBuySellVolume, error) { var resp []TakerBuySellVolume params := url.Values{} params.Set("pair", pair) @@ -575,11 +575,11 @@ func (b *Binance) GetFuturesTakerVolume(ctx context.Context, pair, contractType, params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBuySellVolume+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBuySellVolume+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesBasisData gets futures basis data -func (b *Binance) GetFuturesBasisData(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]FuturesBasisData, error) { +func (e *Exchange) GetFuturesBasisData(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]FuturesBasisData, error) { var resp []FuturesBasisData params := url.Values{} params.Set("pair", pair) @@ -601,17 +601,17 @@ func (b *Binance) GetFuturesBasisData(ctx context.Context, pair, contractType, p params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBasis+params.Encode(), cFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBasis+params.Encode(), cFuturesDefaultRate, &resp) } // FuturesNewOrder sends a new futures order to the exchange -func (b *Binance) FuturesNewOrder(ctx context.Context, x *FuturesNewOrderRequest) ( +func (e *Exchange) FuturesNewOrder(ctx context.Context, x *FuturesNewOrderRequest) ( FuturesOrderPlaceData, error, ) { var resp FuturesOrderPlaceData params := url.Values{} - symbolValue, err := b.FormatSymbol(x.Symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(x.Symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -666,11 +666,11 @@ func (b *Binance) FuturesNewOrder(ctx context.Context, x *FuturesNewOrderRequest if x.PriceProtect { params.Set("priceProtect", "TRUE") } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesBatchOrder sends a batch order request -func (b *Binance) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) ([]FuturesOrderPlaceData, error) { +func (e *Exchange) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) ([]FuturesOrderPlaceData, error) { var resp []FuturesOrderPlaceData params := url.Values{} for x := range data { @@ -678,7 +678,7 @@ func (b *Binance) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderD if err != nil { return resp, err } - formattedPair, err := b.FormatExchangeCurrency(unformattedPair, asset.CoinMarginedFutures) + formattedPair, err := e.FormatExchangeCurrency(unformattedPair, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -704,14 +704,14 @@ func (b *Binance) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderD return resp, err } params.Set("batchOrders", string(jsonData)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesBatchOrder, params, cFuturesBatchOrdersRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesBatchOrder, params, cFuturesBatchOrdersRate, &resp) } // FuturesBatchCancelOrders sends a batch request to cancel orders -func (b *Binance) FuturesBatchCancelOrders(ctx context.Context, symbol currency.Pair, orderList, origClientOrderIDList []string) ([]BatchCancelOrderData, error) { +func (e *Exchange) FuturesBatchCancelOrders(ctx context.Context, symbol currency.Pair, orderList, origClientOrderIDList []string) ([]BatchCancelOrderData, error) { var resp []BatchCancelOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -730,14 +730,14 @@ func (b *Binance) FuturesBatchCancelOrders(ctx context.Context, symbol currency. } params.Set("origClientOrderIdList", string(jsonCliOrdIDList)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesBatchOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesBatchOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesGetOrderData gets futures order data -func (b *Binance) FuturesGetOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (e *Exchange) FuturesGetOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -748,14 +748,14 @@ func (b *Binance) FuturesGetOrderData(ctx context.Context, symbol currency.Pair, if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesCancelOrder cancels a futures order -func (b *Binance) FuturesCancelOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (e *Exchange) FuturesCancelOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -766,40 +766,40 @@ func (b *Binance) FuturesCancelOrder(ctx context.Context, symbol currency.Pair, if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesCancelAllOpenOrders cancels a futures order -func (b *Binance) FuturesCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { +func (e *Exchange) FuturesCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesCancelAllOrders, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesCancelAllOrders, params, cFuturesOrdersDefaultRate, &resp) } // AutoCancelAllOpenOrders cancels all open futures orders // countdownTime 1000 = 1s, example - to cancel all orders after 30s (countdownTime: 30000) -func (b *Binance) AutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { +func (e *Exchange) AutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { var resp AutoCancelAllOrdersData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) params.Set("countdownTime", strconv.FormatInt(countdownTime, 10)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesCountdownCancel, params, cFuturesCancelAllOrdersRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesCountdownCancel, params, cFuturesCancelAllOrdersRate, &resp) } // FuturesOpenOrderData gets open order data for CoinMarginedFutures, -func (b *Binance) FuturesOpenOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (e *Exchange) FuturesOpenOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -810,11 +810,11 @@ func (b *Binance) FuturesOpenOrderData(ctx context.Context, symbol currency.Pair if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOpenOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOpenOrder, params, cFuturesOrdersDefaultRate, &resp) } // GetFuturesAllOpenOrders gets all open orders data for CoinMarginedFutures, -func (b *Binance) GetFuturesAllOpenOrders(ctx context.Context, symbol currency.Pair, pair string) ([]FuturesOrderData, error) { +func (e *Exchange) GetFuturesAllOpenOrders(ctx context.Context, symbol currency.Pair, pair string) ([]FuturesOrderData, error) { var resp []FuturesOrderData params := url.Values{} var p string @@ -822,7 +822,7 @@ func (b *Binance) GetFuturesAllOpenOrders(ctx context.Context, symbol currency.P rateLimit := cFuturesGetAllOpenOrdersRate if !symbol.IsEmpty() { rateLimit = cFuturesOrdersDefaultRate - p, err = b.FormatSymbol(symbol, asset.CoinMarginedFutures) + p, err = e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -834,17 +834,17 @@ func (b *Binance) GetFuturesAllOpenOrders(ctx context.Context, symbol currency.P if pair != "" { params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOpenOrders, params, rateLimit, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOpenOrders, params, rateLimit, &resp) } // GetAllFuturesOrders gets all orders active cancelled or filled -func (b *Binance) GetAllFuturesOrders(ctx context.Context, symbol, pair currency.Pair, startTime, endTime time.Time, orderID, limit int64) ([]FuturesOrderData, error) { +func (e *Exchange) GetAllFuturesOrders(ctx context.Context, symbol, pair currency.Pair, startTime, endTime time.Time, orderID, limit int64) ([]FuturesOrderData, error) { var resp []FuturesOrderData params := url.Values{} rateLimit := cFuturesPairOrdersRate if !symbol.IsEmpty() { rateLimit = cFuturesSymbolOrdersRate - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -866,26 +866,26 @@ func (b *Binance) GetAllFuturesOrders(ctx context.Context, symbol, pair currency params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOrders, params, rateLimit, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOrders, params, rateLimit, &resp) } // GetFuturesAccountBalance gets account balance data for CoinMarginedFutures, account -func (b *Binance) GetFuturesAccountBalance(ctx context.Context) ([]FuturesAccountBalanceData, error) { +func (e *Exchange) GetFuturesAccountBalance(ctx context.Context) ([]FuturesAccountBalanceData, error) { var resp []FuturesAccountBalanceData - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountBalance, nil, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountBalance, nil, cFuturesDefaultRate, &resp) } // GetFuturesAccountInfo gets account info data for CoinMarginedFutures, account -func (b *Binance) GetFuturesAccountInfo(ctx context.Context) (FuturesAccountInformation, error) { +func (e *Exchange) GetFuturesAccountInfo(ctx context.Context) (FuturesAccountInformation, error) { var resp FuturesAccountInformation - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountInfo, nil, cFuturesAccountInformationRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountInfo, nil, cFuturesAccountInformationRate, &resp) } // FuturesChangeInitialLeverage changes initial leverage for the account -func (b *Binance) FuturesChangeInitialLeverage(ctx context.Context, symbol currency.Pair, leverage float64) (FuturesLeverageData, error) { +func (e *Exchange) FuturesChangeInitialLeverage(ctx context.Context, symbol currency.Pair, leverage float64) (FuturesLeverageData, error) { var resp FuturesLeverageData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -894,14 +894,14 @@ func (b *Binance) FuturesChangeInitialLeverage(ctx context.Context, symbol curre return resp, errors.New("invalid leverage") } params.Set("leverage", strconv.FormatFloat(leverage, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeInitialLeverage, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeInitialLeverage, params, cFuturesDefaultRate, &resp) } // FuturesChangeMarginType changes margin type -func (b *Binance) FuturesChangeMarginType(ctx context.Context, symbol currency.Pair, marginType string) (GenericAuthResponse, error) { +func (e *Exchange) FuturesChangeMarginType(ctx context.Context, symbol currency.Pair, marginType string) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -910,14 +910,14 @@ func (b *Binance) FuturesChangeMarginType(ctx context.Context, symbol currency.P return resp, errors.New("invalid marginType") } params.Set("marginType", marginType) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeMarginType, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeMarginType, params, cFuturesDefaultRate, &resp) } // ModifyIsolatedPositionMargin changes margin for an isolated position -func (b *Binance) ModifyIsolatedPositionMargin(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (FuturesMarginUpdatedResponse, error) { +func (e *Exchange) ModifyIsolatedPositionMargin(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (FuturesMarginUpdatedResponse, error) { var resp FuturesMarginUpdatedResponse params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -934,14 +934,14 @@ func (b *Binance) ModifyIsolatedPositionMargin(ctx context.Context, symbol curre } params.Set("type", strconv.FormatInt(cType, 10)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesModifyMargin, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesModifyMargin, params, cFuturesDefaultRate, &resp) } // FuturesMarginChangeHistory gets past margin changes for positions -func (b *Binance) FuturesMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, startTime, endTime time.Time, limit int64) ([]GetPositionMarginChangeHistoryData, error) { +func (e *Exchange) FuturesMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, startTime, endTime time.Time, limit int64) ([]GetPositionMarginChangeHistoryData, error) { var resp []GetPositionMarginChangeHistoryData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -961,13 +961,13 @@ func (b *Binance) FuturesMarginChangeHistory(ctx context.Context, symbol currenc if limit != 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesMarginChangeHistory, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesMarginChangeHistory, params, cFuturesDefaultRate, &resp) } // FuturesPositionsInfo gets futures positions info // "pair" for coinmarginedfutures in GCT terms is the pair base // eg ADAUSD_PERP the "pair" parameter is ADAUSD -func (b *Binance) FuturesPositionsInfo(ctx context.Context, marginAsset, pair string) ([]FuturesPositionInformation, error) { +func (e *Exchange) FuturesPositionsInfo(ctx context.Context, marginAsset, pair string) ([]FuturesPositionInformation, error) { var resp []FuturesPositionInformation params := url.Values{} if marginAsset != "" { @@ -978,17 +978,17 @@ func (b *Binance) FuturesPositionsInfo(ctx context.Context, marginAsset, pair st params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesPositionInfo, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesPositionInfo, params, cFuturesDefaultRate, &resp) } // FuturesTradeHistory gets trade history for CoinMarginedFutures, account -func (b *Binance) FuturesTradeHistory(ctx context.Context, symbol currency.Pair, pair string, startTime, endTime time.Time, limit, fromID int64) ([]FuturesAccountTradeList, error) { +func (e *Exchange) FuturesTradeHistory(ctx context.Context, symbol currency.Pair, pair string, startTime, endTime time.Time, limit, fromID int64) ([]FuturesAccountTradeList, error) { var resp []FuturesAccountTradeList params := url.Values{} rateLimit := cFuturesPairOrdersRate if !symbol.IsEmpty() { rateLimit = cFuturesSymbolOrdersRate - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -1010,15 +1010,15 @@ func (b *Binance) FuturesTradeHistory(ctx context.Context, symbol currency.Pair, if fromID != 0 { params.Set("fromId", strconv.FormatInt(fromID, 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountTradeList, params, rateLimit, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountTradeList, params, rateLimit, &resp) } // FuturesIncomeHistory gets income history for CoinMarginedFutures, -func (b *Binance) FuturesIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, startTime, endTime time.Time, limit int64) ([]FuturesIncomeHistoryData, error) { +func (e *Exchange) FuturesIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, startTime, endTime time.Time, limit int64) ([]FuturesIncomeHistoryData, error) { var resp []FuturesIncomeHistoryData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -1040,25 +1040,25 @@ func (b *Binance) FuturesIncomeHistory(ctx context.Context, symbol currency.Pair if limit != 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesIncomeHistory, params, cFuturesIncomeHistoryRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesIncomeHistory, params, cFuturesIncomeHistoryRate, &resp) } // FuturesNotionalBracket gets futures notional bracket -func (b *Binance) FuturesNotionalBracket(ctx context.Context, pair string) ([]NotionalBracketData, error) { +func (e *Exchange) FuturesNotionalBracket(ctx context.Context, pair string) ([]NotionalBracketData, error) { var resp []NotionalBracketData params := url.Values{} if pair != "" { params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesNotionalBracket, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesNotionalBracket, params, cFuturesDefaultRate, &resp) } // FuturesForceOrders gets futures forced orders -func (b *Binance) FuturesForceOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, startTime, endTime time.Time) ([]ForcedOrdersData, error) { +func (e *Exchange) FuturesForceOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, startTime, endTime time.Time) ([]ForcedOrdersData, error) { var resp []ForcedOrdersData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -1077,26 +1077,26 @@ func (b *Binance) FuturesForceOrders(ctx context.Context, symbol currency.Pair, params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesUsersForceOrders, params, cFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesUsersForceOrders, params, cFuturesDefaultRate, &resp) } // FuturesPositionsADLEstimate estimates ADL on positions -func (b *Binance) FuturesPositionsADLEstimate(ctx context.Context, symbol currency.Pair) ([]ADLEstimateData, error) { +func (e *Exchange) FuturesPositionsADLEstimate(ctx context.Context, symbol currency.Pair) ([]ADLEstimateData, error) { var resp []ADLEstimateData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.CoinMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesADLQuantile, params, cFuturesAccountInformationRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesADLQuantile, params, cFuturesAccountInformationRate, &resp) } // FetchCoinMarginExchangeLimits fetches coin margined order execution limits -func (b *Binance) FetchCoinMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { - coinFutures, err := b.FuturesExchangeInfo(ctx) +func (e *Exchange) FetchCoinMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { + coinFutures, err := e.FuturesExchangeInfo(ctx) if err != nil { return nil, err } diff --git a/exchanges/binance/binance_live_test.go b/exchanges/binance/binance_live_test.go index 5d1d8e7cd4c..23a4df188f0 100644 --- a/exchanges/binance/binance_live_test.go +++ b/exchanges/binance/binance_live_test.go @@ -18,15 +18,15 @@ import ( var mockTests = false func TestMain(m *testing.M) { - b = new(Binance) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Binance Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.API.CredentialsValidator.RequiresBase64DecodeSecret = false - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.CredentialsValidator.RequiresBase64DecodeSecret = false + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } if useTestNet { @@ -35,15 +35,15 @@ func TestMain(m *testing.M) { exchange.RestCoinMargined: testnetFutures, exchange.RestSpot: testnetSpotURL, } { - if err := b.API.Endpoints.SetRunningURL(k.String(), v); err != nil { + if err := e.API.Endpoints.SetRunningURL(k.String(), v); err != nil { log.Fatalf("Binance SetRunningURL error: %s", err) } } } - b.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride() - log.Printf(sharedtestvalues.LiveTesting, b.Name) - if err := b.UpdateTradablePairs(context.Background(), true); err != nil { + e.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride() + log.Printf(sharedtestvalues.LiveTesting, e.Name) + if err := e.UpdateTradablePairs(context.Background(), true); err != nil { log.Fatalf("Binance UpdateTradablePairs error: %s", err) } diff --git a/exchanges/binance/binance_mock_test.go b/exchanges/binance/binance_mock_test.go index f6d8f7d42c9..94d19e036f2 100644 --- a/exchanges/binance/binance_mock_test.go +++ b/exchanges/binance/binance_mock_test.go @@ -20,16 +20,16 @@ func TestMain(m *testing.M) { log.Fatal("cannot use testnet with mock tests") } - b = new(Binance) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Binance Setup error: %s", err) } - if err := testexch.MockHTTPInstance(b); err != nil { + if err := testexch.MockHTTPInstance(e); err != nil { log.Fatalf("Binance MockHTTPInstance error: %s", err) } - if err := b.UpdateTradablePairs(context.Background(), true); err != nil { + if err := e.UpdateTradablePairs(context.Background(), true); err != nil { log.Fatalf("Binance UpdateTradablePairs error: %s", err) } diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index b2b8e8dffb5..c0968c36e9b 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -43,7 +43,7 @@ const ( ) var ( - b = &Binance{} + e *Exchange // this pair is used to ensure that endpoints match it correctly testPairMapping = currency.NewPair(currency.DOGE, currency.USDT) ) @@ -72,7 +72,7 @@ func getTime() (start, end time.Time) { func TestUServerTime(t *testing.T) { t.Parallel() - _, err := b.UServerTime(t.Context()) + _, err := e.UServerTime(t.Context()) if err != nil { t.Error(err) } @@ -80,24 +80,24 @@ func TestUServerTime(t *testing.T) { func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - _, err := b.GetServerTime(t.Context(), asset.Empty) + _, err := e.GetServerTime(t.Context(), asset.Empty) require.ErrorIs(t, err, asset.ErrNotSupported) - st, err := b.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) if st.IsZero() { t.Fatal("expected a time") } - st, err = b.GetServerTime(t.Context(), asset.USDTMarginedFutures) + st, err = e.GetServerTime(t.Context(), asset.USDTMarginedFutures) require.NoError(t, err) if st.IsZero() { t.Fatal("expected a time") } - st, err = b.GetServerTime(t.Context(), asset.CoinMarginedFutures) + st, err = e.GetServerTime(t.Context(), asset.CoinMarginedFutures) require.NoError(t, err) if st.IsZero() { @@ -107,50 +107,50 @@ func TestWrapperGetServerTime(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - r, err := b.UpdateTicker(t.Context(), testPairMapping, asset.Spot) + r, err := e.UpdateTicker(t.Context(), testPairMapping, asset.Spot) if err != nil { t.Error(err) } if r.Pair.Base != currency.DOGE && r.Pair.Quote != currency.USDT { t.Error("invalid pair values") } - tradablePairs, err := b.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) + tradablePairs, err := e.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } if len(tradablePairs) == 0 { t.Fatal("no tradable pairs") } - _, err = b.UpdateTicker(t.Context(), tradablePairs[0], asset.CoinMarginedFutures) + _, err = e.UpdateTicker(t.Context(), tradablePairs[0], asset.CoinMarginedFutures) if err != nil { t.Error(err) } - usdtMarginedPairs, err := b.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) + usdtMarginedPairs, err := e.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } if len(usdtMarginedPairs) == 0 { t.Errorf("no pairs are enabled") } - _, err = b.UpdateTicker(t.Context(), usdtMarginedPairs[0], asset.USDTMarginedFutures) + _, err = e.UpdateTicker(t.Context(), usdtMarginedPairs[0], asset.USDTMarginedFutures) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := b.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) if err != nil { t.Error(err) } - err = b.UpdateTickers(t.Context(), asset.CoinMarginedFutures) + err = e.UpdateTickers(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } - err = b.UpdateTickers(t.Context(), asset.USDTMarginedFutures) + err = e.UpdateTickers(t.Context(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -162,15 +162,15 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), cp, asset.Spot) + _, err = e.UpdateOrderbook(t.Context(), cp, asset.Spot) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), cp, asset.Margin) + _, err = e.UpdateOrderbook(t.Context(), cp, asset.Margin) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), cp, asset.USDTMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), cp, asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -178,7 +178,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), cp2, asset.CoinMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), cp2, asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -188,7 +188,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestUExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.UExchangeInfo(t.Context()) + _, err := e.UExchangeInfo(t.Context()) if err != nil { t.Error(err) } @@ -196,7 +196,7 @@ func TestUExchangeInfo(t *testing.T) { func TestUFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := b.UFuturesOrderbook(t.Context(), currency.NewBTCUSDT(), 1000) + _, err := e.UFuturesOrderbook(t.Context(), currency.NewBTCUSDT(), 1000) if err != nil { t.Error(err) } @@ -204,7 +204,7 @@ func TestUFuturesOrderbook(t *testing.T) { func TestURecentTrades(t *testing.T) { t.Parallel() - _, err := b.URecentTrades(t.Context(), currency.NewBTCUSDT(), "", 1000) + _, err := e.URecentTrades(t.Context(), currency.NewBTCUSDT(), "", 1000) if err != nil { t.Error(err) } @@ -212,12 +212,12 @@ func TestURecentTrades(t *testing.T) { func TestUCompressedTrades(t *testing.T) { t.Parallel() - _, err := b.UCompressedTrades(t.Context(), currency.NewBTCUSDT(), "", 5, time.Time{}, time.Time{}) + _, err := e.UCompressedTrades(t.Context(), currency.NewBTCUSDT(), "", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UCompressedTrades(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "", 0, start, end) + _, err = e.UCompressedTrades(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "", 0, start, end) if err != nil { t.Error(err) } @@ -225,12 +225,12 @@ func TestUCompressedTrades(t *testing.T) { func TestUKlineData(t *testing.T) { t.Parallel() - _, err := b.UKlineData(t.Context(), currency.NewBTCUSDT(), "1d", 5, time.Time{}, time.Time{}) + _, err := e.UKlineData(t.Context(), currency.NewBTCUSDT(), "1d", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UKlineData(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "5m", 0, start, end) + _, err = e.UKlineData(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "5m", 0, start, end) if err != nil { t.Error(err) } @@ -238,11 +238,11 @@ func TestUKlineData(t *testing.T) { func TestUGetMarkPrice(t *testing.T) { t.Parallel() - _, err := b.UGetMarkPrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.UGetMarkPrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } - _, err = b.UGetMarkPrice(t.Context(), currency.EMPTYPAIR) + _, err = e.UGetMarkPrice(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -250,12 +250,12 @@ func TestUGetMarkPrice(t *testing.T) { func TestUGetFundingHistory(t *testing.T) { t.Parallel() - _, err := b.UGetFundingHistory(t.Context(), currency.NewBTCUSDT(), 1, time.Time{}, time.Time{}) + _, err := e.UGetFundingHistory(t.Context(), currency.NewBTCUSDT(), 1, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UGetFundingHistory(t.Context(), currency.NewPair(currency.LTC, currency.USDT), 1, start, end) + _, err = e.UGetFundingHistory(t.Context(), currency.NewPair(currency.LTC, currency.USDT), 1, start, end) if err != nil { t.Error(err) } @@ -263,11 +263,11 @@ func TestUGetFundingHistory(t *testing.T) { func TestU24HTickerPriceChangeStats(t *testing.T) { t.Parallel() - _, err := b.U24HTickerPriceChangeStats(t.Context(), currency.NewBTCUSDT()) + _, err := e.U24HTickerPriceChangeStats(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } - _, err = b.U24HTickerPriceChangeStats(t.Context(), currency.EMPTYPAIR) + _, err = e.U24HTickerPriceChangeStats(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -275,11 +275,11 @@ func TestU24HTickerPriceChangeStats(t *testing.T) { func TestUSymbolPriceTicker(t *testing.T) { t.Parallel() - _, err := b.USymbolPriceTicker(t.Context(), currency.NewBTCUSDT()) + _, err := e.USymbolPriceTicker(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } - _, err = b.USymbolPriceTicker(t.Context(), currency.EMPTYPAIR) + _, err = e.USymbolPriceTicker(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -287,11 +287,11 @@ func TestUSymbolPriceTicker(t *testing.T) { func TestUSymbolOrderbookTicker(t *testing.T) { t.Parallel() - _, err := b.USymbolOrderbookTicker(t.Context(), currency.NewBTCUSDT()) + _, err := e.USymbolOrderbookTicker(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } - _, err = b.USymbolOrderbookTicker(t.Context(), currency.EMPTYPAIR) + _, err = e.USymbolOrderbookTicker(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -299,7 +299,7 @@ func TestUSymbolOrderbookTicker(t *testing.T) { func TestUOpenInterest(t *testing.T) { t.Parallel() - _, err := b.UOpenInterest(t.Context(), currency.NewBTCUSDT()) + _, err := e.UOpenInterest(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -307,12 +307,12 @@ func TestUOpenInterest(t *testing.T) { func TestUOpenInterestStats(t *testing.T) { t.Parallel() - _, err := b.UOpenInterestStats(t.Context(), currency.NewBTCUSDT(), "5m", 1, time.Time{}, time.Time{}) + _, err := e.UOpenInterestStats(t.Context(), currency.NewBTCUSDT(), "5m", 1, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UOpenInterestStats(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "1d", 10, start, end) + _, err = e.UOpenInterestStats(t.Context(), currency.NewPair(currency.LTC, currency.USDT), "1d", 10, start, end) if err != nil { t.Error(err) } @@ -320,12 +320,12 @@ func TestUOpenInterestStats(t *testing.T) { func TestUTopAcccountsLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UTopAcccountsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 2, time.Time{}, time.Time{}) + _, err := e.UTopAcccountsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 2, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UTopAcccountsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 2, start, end) + _, err = e.UTopAcccountsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 2, start, end) if err != nil { t.Error(err) } @@ -333,12 +333,12 @@ func TestUTopAcccountsLongShortRatio(t *testing.T) { func TestUTopPostionsLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UTopPostionsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 3, time.Time{}, time.Time{}) + _, err := e.UTopPostionsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 3, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UTopPostionsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "1d", 0, start, end) + _, err = e.UTopPostionsLongShortRatio(t.Context(), currency.NewBTCUSDT(), "1d", 0, start, end) if err != nil { t.Error(err) } @@ -346,12 +346,12 @@ func TestUTopPostionsLongShortRatio(t *testing.T) { func TestUGlobalLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UGlobalLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 3, time.Time{}, time.Time{}) + _, err := e.UGlobalLongShortRatio(t.Context(), currency.NewBTCUSDT(), "5m", 3, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.UGlobalLongShortRatio(t.Context(), currency.NewBTCUSDT(), "4h", 0, start, end) + _, err = e.UGlobalLongShortRatio(t.Context(), currency.NewBTCUSDT(), "4h", 0, start, end) if err != nil { t.Error(err) } @@ -360,7 +360,7 @@ func TestUGlobalLongShortRatio(t *testing.T) { func TestUTakerBuySellVol(t *testing.T) { t.Parallel() start, end := getTime() - _, err := b.UTakerBuySellVol(t.Context(), currency.NewBTCUSDT(), "5m", 10, start, end) + _, err := e.UTakerBuySellVol(t.Context(), currency.NewBTCUSDT(), "5m", 10, start, end) if err != nil { t.Error(err) } @@ -372,11 +372,11 @@ func TestUCompositeIndexInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UCompositeIndexInfo(t.Context(), cp) + _, err = e.UCompositeIndexInfo(t.Context(), cp) if err != nil { t.Error(err) } - _, err = b.UCompositeIndexInfo(t.Context(), currency.EMPTYPAIR) + _, err = e.UCompositeIndexInfo(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -384,8 +384,8 @@ func TestUCompositeIndexInfo(t *testing.T) { func TestUFuturesNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UFuturesNewOrder(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UFuturesNewOrder(t.Context(), &UFuturesNewOrderRequest{ Symbol: currency.NewBTCUSDT(), Side: "BUY", @@ -402,7 +402,7 @@ func TestUFuturesNewOrder(t *testing.T) { func TestUPlaceBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) var data []PlaceBatchOrderData var tempData PlaceBatchOrderData tempData.Symbol = "BTCUSDT" @@ -412,7 +412,7 @@ func TestUPlaceBatchOrders(t *testing.T) { tempData.Price = 1 tempData.TimeInForce = "GTC" data = append(data, tempData) - _, err := b.UPlaceBatchOrders(t.Context(), data) + _, err := e.UPlaceBatchOrders(t.Context(), data) if err != nil { t.Error(err) } @@ -420,8 +420,8 @@ func TestUPlaceBatchOrders(t *testing.T) { func TestUGetOrderData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UGetOrderData(t.Context(), currency.NewBTCUSDT(), "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UGetOrderData(t.Context(), currency.NewBTCUSDT(), "123", "") if err != nil { t.Error(err) } @@ -429,8 +429,8 @@ func TestUGetOrderData(t *testing.T) { func TestUCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UCancelOrder(t.Context(), currency.NewBTCUSDT(), "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UCancelOrder(t.Context(), currency.NewBTCUSDT(), "123", "") if err != nil { t.Error(err) } @@ -438,8 +438,8 @@ func TestUCancelOrder(t *testing.T) { func TestUCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UCancelAllOpenOrders(t.Context(), currency.NewBTCUSDT()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UCancelAllOpenOrders(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -447,8 +447,8 @@ func TestUCancelAllOpenOrders(t *testing.T) { func TestUCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UCancelBatchOrders(t.Context(), currency.NewBTCUSDT(), []string{"123"}, []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UCancelBatchOrders(t.Context(), currency.NewBTCUSDT(), []string{"123"}, []string{}) if err != nil { t.Error(err) } @@ -456,8 +456,8 @@ func TestUCancelBatchOrders(t *testing.T) { func TestUAutoCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UAutoCancelAllOpenOrders(t.Context(), currency.NewBTCUSDT(), 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UAutoCancelAllOpenOrders(t.Context(), currency.NewBTCUSDT(), 30) if err != nil { t.Error(err) } @@ -465,8 +465,8 @@ func TestUAutoCancelAllOpenOrders(t *testing.T) { func TestUFetchOpenOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UFetchOpenOrder(t.Context(), currency.NewBTCUSDT(), "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UFetchOpenOrder(t.Context(), currency.NewBTCUSDT(), "123", "") if err != nil { t.Error(err) } @@ -474,8 +474,8 @@ func TestUFetchOpenOrder(t *testing.T) { func TestUAllAccountOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAllAccountOpenOrders(t.Context(), currency.NewBTCUSDT()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAllAccountOpenOrders(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -483,12 +483,12 @@ func TestUAllAccountOpenOrders(t *testing.T) { func TestUAllAccountOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAllAccountOrders(t.Context(), currency.EMPTYPAIR, 0, 0, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAllAccountOrders(t.Context(), currency.EMPTYPAIR, 0, 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UAllAccountOrders(t.Context(), currency.NewBTCUSDT(), 0, 5, time.Now().Add(-time.Hour*4), time.Now()) + _, err = e.UAllAccountOrders(t.Context(), currency.NewBTCUSDT(), 0, 5, time.Now().Add(-time.Hour*4), time.Now()) if err != nil { t.Error(err) } @@ -496,8 +496,8 @@ func TestUAllAccountOrders(t *testing.T) { func TestUAccountBalanceV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAccountBalanceV2(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAccountBalanceV2(t.Context()) if err != nil { t.Error(err) } @@ -505,8 +505,8 @@ func TestUAccountBalanceV2(t *testing.T) { func TestUAccountInformationV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAccountInformationV2(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAccountInformationV2(t.Context()) if err != nil { t.Error(err) } @@ -514,8 +514,8 @@ func TestUAccountInformationV2(t *testing.T) { func TestUChangeInitialLeverageRequest(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UChangeInitialLeverageRequest(t.Context(), currency.NewBTCUSDT(), 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UChangeInitialLeverageRequest(t.Context(), currency.NewBTCUSDT(), 2) if err != nil { t.Error(err) } @@ -523,8 +523,8 @@ func TestUChangeInitialLeverageRequest(t *testing.T) { func TestUChangeInitialMarginType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.UChangeInitialMarginType(t.Context(), currency.NewBTCUSDT(), "ISOLATED") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.UChangeInitialMarginType(t.Context(), currency.NewBTCUSDT(), "ISOLATED") if err != nil { t.Error(err) } @@ -532,8 +532,8 @@ func TestUChangeInitialMarginType(t *testing.T) { func TestUModifyIsolatedPositionMarginReq(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UModifyIsolatedPositionMarginReq(t.Context(), currency.NewBTCUSDT(), "LONG", "add", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UModifyIsolatedPositionMarginReq(t.Context(), currency.NewBTCUSDT(), "LONG", "add", 5) if err != nil { t.Error(err) } @@ -541,8 +541,8 @@ func TestUModifyIsolatedPositionMarginReq(t *testing.T) { func TestUPositionMarginChangeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UPositionMarginChangeHistory(t.Context(), currency.NewBTCUSDT(), "add", 5, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UPositionMarginChangeHistory(t.Context(), currency.NewBTCUSDT(), "add", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -550,8 +550,8 @@ func TestUPositionMarginChangeHistory(t *testing.T) { func TestUPositionsInfoV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UPositionsInfoV2(t.Context(), currency.NewBTCUSDT()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UPositionsInfoV2(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -559,8 +559,8 @@ func TestUPositionsInfoV2(t *testing.T) { func TestUAccountTradesHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAccountTradesHistory(t.Context(), currency.NewBTCUSDT(), "", 5, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAccountTradesHistory(t.Context(), currency.NewBTCUSDT(), "", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -568,8 +568,8 @@ func TestUAccountTradesHistory(t *testing.T) { func TestUAccountIncomeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAccountIncomeHistory(t.Context(), currency.EMPTYPAIR, "", 5, time.Now().Add(-time.Hour*48), time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAccountIncomeHistory(t.Context(), currency.EMPTYPAIR, "", 5, time.Now().Add(-time.Hour*48), time.Now()) if err != nil { t.Error(err) } @@ -577,8 +577,8 @@ func TestUAccountIncomeHistory(t *testing.T) { func TestUGetNotionalAndLeverageBrackets(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UGetNotionalAndLeverageBrackets(t.Context(), currency.NewBTCUSDT()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UGetNotionalAndLeverageBrackets(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -586,8 +586,8 @@ func TestUGetNotionalAndLeverageBrackets(t *testing.T) { func TestUPositionsADLEstimate(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UPositionsADLEstimate(t.Context(), currency.NewBTCUSDT()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UPositionsADLEstimate(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -595,8 +595,8 @@ func TestUPositionsADLEstimate(t *testing.T) { func TestUAccountForcedOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.UAccountForcedOrders(t.Context(), currency.NewBTCUSDT(), "ADL", 5, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UAccountForcedOrders(t.Context(), currency.NewBTCUSDT(), "ADL", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -606,7 +606,7 @@ func TestUAccountForcedOrders(t *testing.T) { func TestGetFuturesExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.FuturesExchangeInfo(t.Context()) + _, err := e.FuturesExchangeInfo(t.Context()) if err != nil { t.Error(err) } @@ -614,7 +614,7 @@ func TestGetFuturesExchangeInfo(t *testing.T) { func TestGetFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetFuturesOrderbook(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 1000) + _, err := e.GetFuturesOrderbook(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 1000) if err != nil { t.Error(err) } @@ -622,7 +622,7 @@ func TestGetFuturesOrderbook(t *testing.T) { func TestGetFuturesPublicTrades(t *testing.T) { t.Parallel() - _, err := b.GetFuturesPublicTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) + _, err := e.GetFuturesPublicTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) if err != nil { t.Error(err) } @@ -630,7 +630,7 @@ func TestGetFuturesPublicTrades(t *testing.T) { func TestGetPastPublicTrades(t *testing.T) { t.Parallel() - _, err := b.GetPastPublicTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, 0) + _, err := e.GetPastPublicTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, 0) if err != nil { t.Error(err) } @@ -638,7 +638,7 @@ func TestGetPastPublicTrades(t *testing.T) { func TestGetAggregatedTradesList(t *testing.T) { t.Parallel() - _, err := b.GetFuturesAggregatedTradesList(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 0, 5, time.Time{}, time.Time{}) + _, err := e.GetFuturesAggregatedTradesList(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 0, 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -646,7 +646,7 @@ func TestGetAggregatedTradesList(t *testing.T) { func TestGetPerpsExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.GetPerpMarkets(t.Context()) + _, err := e.GetPerpMarkets(t.Context()) if err != nil { t.Error(err) } @@ -654,7 +654,7 @@ func TestGetPerpsExchangeInfo(t *testing.T) { func TestGetIndexAndMarkPrice(t *testing.T) { t.Parallel() - _, err := b.GetIndexAndMarkPrice(t.Context(), "", "BTCUSD") + _, err := e.GetIndexAndMarkPrice(t.Context(), "", "BTCUSD") if err != nil { t.Error(err) } @@ -662,7 +662,7 @@ func TestGetIndexAndMarkPrice(t *testing.T) { func TestGetFuturesKlineData(t *testing.T) { t.Parallel() - r, err := b.GetFuturesKlineData(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) + r, err := e.GetFuturesKlineData(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) require.NoError(t, err, "GetFuturesKlineData must not error") if mockTests { require.Equal(t, 5, len(r), "GetFuturesKlineData must return 5 items in mock test") @@ -685,19 +685,19 @@ func TestGetFuturesKlineData(t *testing.T) { } start, end := getTime() - r, err = b.GetFuturesKlineData(t.Context(), currency.NewPairWithDelimiter("LTCUSD", "PERP", "_"), "5m", 5, start, end) + r, err = e.GetFuturesKlineData(t.Context(), currency.NewPairWithDelimiter("LTCUSD", "PERP", "_"), "5m", 5, start, end) require.NoError(t, err, "GetFuturesKlineData must not error") assert.NotEmpty(t, r, "GetFuturesKlineData should return data") } func TestGetContinuousKlineData(t *testing.T) { t.Parallel() - _, err := b.GetContinuousKlineData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Time{}, time.Time{}) + _, err := e.GetContinuousKlineData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetContinuousKlineData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, start, end) + _, err = e.GetContinuousKlineData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, start, end) if err != nil { t.Error(err) } @@ -705,12 +705,12 @@ func TestGetContinuousKlineData(t *testing.T) { func TestGetIndexPriceKlines(t *testing.T) { t.Parallel() - _, err := b.GetIndexPriceKlines(t.Context(), "BTCUSD", "1M", 5, time.Time{}, time.Time{}) + _, err := e.GetIndexPriceKlines(t.Context(), "BTCUSD", "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetIndexPriceKlines(t.Context(), "BTCUSD", "1M", 5, start, end) + _, err = e.GetIndexPriceKlines(t.Context(), "BTCUSD", "1M", 5, start, end) if err != nil { t.Error(err) } @@ -718,15 +718,15 @@ func TestGetIndexPriceKlines(t *testing.T) { func TestGetFuturesSwapTickerChangeStats(t *testing.T) { t.Parallel() - _, err := b.GetFuturesSwapTickerChangeStats(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err := e.GetFuturesSwapTickerChangeStats(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } - _, err = b.GetFuturesSwapTickerChangeStats(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err = e.GetFuturesSwapTickerChangeStats(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } - _, err = b.GetFuturesSwapTickerChangeStats(t.Context(), currency.EMPTYPAIR, "") + _, err = e.GetFuturesSwapTickerChangeStats(t.Context(), currency.EMPTYPAIR, "") if err != nil { t.Error(err) } @@ -734,13 +734,13 @@ func TestGetFuturesSwapTickerChangeStats(t *testing.T) { func TestFuturesGetFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesGetFundingHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesGetFundingHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.FuturesGetFundingHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 50, start, end) + _, err = e.FuturesGetFundingHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 50, start, end) if err != nil { t.Error(err) } @@ -748,12 +748,12 @@ func TestFuturesGetFundingHistory(t *testing.T) { func TestGetFuturesHistoricalTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFuturesHistoricalTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesHistoricalTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 5) if err != nil { t.Error(err) } - _, err = b.GetFuturesHistoricalTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0) + _, err = e.GetFuturesHistoricalTrades(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0) if err != nil { t.Error(err) } @@ -761,7 +761,7 @@ func TestGetFuturesHistoricalTrades(t *testing.T) { func TestGetFuturesSymbolPriceTicker(t *testing.T) { t.Parallel() - _, err := b.GetFuturesSymbolPriceTicker(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err := e.GetFuturesSymbolPriceTicker(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -769,11 +769,11 @@ func TestGetFuturesSymbolPriceTicker(t *testing.T) { func TestGetFuturesOrderbookTicker(t *testing.T) { t.Parallel() - _, err := b.GetFuturesOrderbookTicker(t.Context(), currency.EMPTYPAIR, "") + _, err := e.GetFuturesOrderbookTicker(t.Context(), currency.EMPTYPAIR, "") if err != nil { t.Error(err) } - _, err = b.GetFuturesOrderbookTicker(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err = e.GetFuturesOrderbookTicker(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -781,7 +781,7 @@ func TestGetFuturesOrderbookTicker(t *testing.T) { func TestOpenInterest(t *testing.T) { t.Parallel() - _, err := b.OpenInterest(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) + _, err := e.OpenInterest(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) if err != nil { t.Error(err) } @@ -789,12 +789,12 @@ func TestOpenInterest(t *testing.T) { func TestGetOpenInterestStats(t *testing.T) { t.Parallel() - _, err := b.GetOpenInterestStats(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetOpenInterestStats(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetOpenInterestStats(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end) + _, err = e.GetOpenInterestStats(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -802,12 +802,12 @@ func TestGetOpenInterestStats(t *testing.T) { func TestGetTraderFuturesAccountRatio(t *testing.T) { t.Parallel() - _, err := b.GetTraderFuturesAccountRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetTraderFuturesAccountRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetTraderFuturesAccountRatio(t.Context(), "BTCUSD", "5m", 0, start, end) + _, err = e.GetTraderFuturesAccountRatio(t.Context(), "BTCUSD", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -815,12 +815,12 @@ func TestGetTraderFuturesAccountRatio(t *testing.T) { func TestGetTraderFuturesPositionsRatio(t *testing.T) { t.Parallel() - _, err := b.GetTraderFuturesPositionsRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetTraderFuturesPositionsRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetTraderFuturesPositionsRatio(t.Context(), "BTCUSD", "5m", 0, start, end) + _, err = e.GetTraderFuturesPositionsRatio(t.Context(), "BTCUSD", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -828,12 +828,12 @@ func TestGetTraderFuturesPositionsRatio(t *testing.T) { func TestGetMarketRatio(t *testing.T) { t.Parallel() - _, err := b.GetMarketRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetMarketRatio(t.Context(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetMarketRatio(t.Context(), "BTCUSD", "5m", 0, start, end) + _, err = e.GetMarketRatio(t.Context(), "BTCUSD", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -841,12 +841,12 @@ func TestGetMarketRatio(t *testing.T) { func TestGetFuturesTakerVolume(t *testing.T) { t.Parallel() - _, err := b.GetFuturesTakerVolume(t.Context(), "BTCUSD", "ALL", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetFuturesTakerVolume(t.Context(), "BTCUSD", "ALL", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetFuturesTakerVolume(t.Context(), "BTCUSD", "ALL", "5m", 0, start, end) + _, err = e.GetFuturesTakerVolume(t.Context(), "BTCUSD", "ALL", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -854,12 +854,12 @@ func TestGetFuturesTakerVolume(t *testing.T) { func TestFuturesBasisData(t *testing.T) { t.Parallel() - _, err := b.GetFuturesBasisData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) + _, err := e.GetFuturesBasisData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } start, end := getTime() - _, err = b.GetFuturesBasisData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end) + _, err = e.GetFuturesBasisData(t.Context(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, start, end) if err != nil { t.Error(err) } @@ -867,8 +867,8 @@ func TestFuturesBasisData(t *testing.T) { func TestFuturesNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.FuturesNewOrder( + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FuturesNewOrder( t.Context(), &FuturesNewOrderRequest{ Symbol: currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), @@ -886,7 +886,7 @@ func TestFuturesNewOrder(t *testing.T) { func TestFuturesBatchOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) var data []PlaceBatchOrderData var tempData PlaceBatchOrderData tempData.Symbol = "BTCUSD_PERP" @@ -897,7 +897,7 @@ func TestFuturesBatchOrder(t *testing.T) { tempData.TimeInForce = "GTC" data = append(data, tempData) - _, err := b.FuturesBatchOrder(t.Context(), data) + _, err := e.FuturesBatchOrder(t.Context(), data) if err != nil { t.Error(err) } @@ -905,8 +905,8 @@ func TestFuturesBatchOrder(t *testing.T) { func TestFuturesBatchCancelOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.FuturesBatchCancelOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), []string{"123"}, []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FuturesBatchCancelOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), []string{"123"}, []string{}) if err != nil { t.Error(err) } @@ -914,8 +914,8 @@ func TestFuturesBatchCancelOrders(t *testing.T) { func TestFuturesGetOrderData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesGetOrderData(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesGetOrderData(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "123", "") if err != nil { t.Error(err) } @@ -923,8 +923,8 @@ func TestFuturesGetOrderData(t *testing.T) { func TestCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.FuturesCancelAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FuturesCancelAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) if err != nil { t.Error(err) } @@ -932,8 +932,8 @@ func TestCancelAllOpenOrders(t *testing.T) { func TestAutoCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.AutoCancelAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 30000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.AutoCancelAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 30000) if err != nil { t.Error(err) } @@ -941,8 +941,8 @@ func TestAutoCancelAllOpenOrders(t *testing.T) { func TestFuturesOpenOrderData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesOpenOrderData(t.Context(), currency.NewBTCUSDT(), "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesOpenOrderData(t.Context(), currency.NewBTCUSDT(), "", "") if err != nil { t.Error(err) } @@ -950,8 +950,8 @@ func TestFuturesOpenOrderData(t *testing.T) { func TestGetFuturesAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFuturesAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesAllOpenOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -959,8 +959,8 @@ func TestGetFuturesAllOpenOrders(t *testing.T) { func TestGetAllFuturesOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAllFuturesOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), currency.EMPTYPAIR, time.Time{}, time.Time{}, 0, 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAllFuturesOrders(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), currency.EMPTYPAIR, time.Time{}, time.Time{}, 0, 2) if err != nil { t.Error(err) } @@ -968,8 +968,8 @@ func TestGetAllFuturesOrders(t *testing.T) { func TestFuturesChangeMarginType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.FuturesChangeMarginType(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "ISOLATED") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FuturesChangeMarginType(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "ISOLATED") if err != nil { t.Error(err) } @@ -977,8 +977,8 @@ func TestFuturesChangeMarginType(t *testing.T) { func TestGetFuturesAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFuturesAccountBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesAccountBalance(t.Context()) if err != nil { t.Error(err) } @@ -986,8 +986,8 @@ func TestGetFuturesAccountBalance(t *testing.T) { func TestGetFuturesAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFuturesAccountInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesAccountInfo(t.Context()) if err != nil { t.Error(err) } @@ -995,8 +995,8 @@ func TestGetFuturesAccountInfo(t *testing.T) { func TestFuturesChangeInitialLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.FuturesChangeInitialLeverage(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FuturesChangeInitialLeverage(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) if err != nil { t.Error(err) } @@ -1004,8 +1004,8 @@ func TestFuturesChangeInitialLeverage(t *testing.T) { func TestModifyIsolatedPositionMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifyIsolatedPositionMargin(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BOTH", "add", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyIsolatedPositionMargin(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BOTH", "add", 5) if err != nil { t.Error(err) } @@ -1013,8 +1013,8 @@ func TestModifyIsolatedPositionMargin(t *testing.T) { func TestFuturesMarginChangeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesMarginChangeHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "add", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesMarginChangeHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "add", time.Time{}, time.Time{}, 10) if err != nil { t.Error(err) } @@ -1022,8 +1022,8 @@ func TestFuturesMarginChangeHistory(t *testing.T) { func TestFuturesPositionsInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesPositionsInfo(t.Context(), "BTCUSD", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesPositionsInfo(t.Context(), "BTCUSD", "") if err != nil { t.Error(err) } @@ -1031,8 +1031,8 @@ func TestFuturesPositionsInfo(t *testing.T) { func TestFuturesTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesTradeHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 5, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesTradeHistory(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 5, 0) if err != nil { t.Error(err) } @@ -1040,8 +1040,8 @@ func TestFuturesTradeHistory(t *testing.T) { func TestFuturesIncomeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesIncomeHistory(t.Context(), currency.EMPTYPAIR, "TRANSFER", time.Time{}, time.Time{}, 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesIncomeHistory(t.Context(), currency.EMPTYPAIR, "TRANSFER", time.Time{}, time.Time{}, 5) if err != nil { t.Error(err) } @@ -1049,8 +1049,8 @@ func TestFuturesIncomeHistory(t *testing.T) { func TestFuturesForceOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesForceOrders(t.Context(), currency.EMPTYPAIR, "ADL", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesForceOrders(t.Context(), currency.EMPTYPAIR, "ADL", time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -1058,12 +1058,12 @@ func TestFuturesForceOrders(t *testing.T) { func TestUGetNotionalLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesNotionalBracket(t.Context(), "BTCUSD") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesNotionalBracket(t.Context(), "BTCUSD") if err != nil { t.Error(err) } - _, err = b.FuturesNotionalBracket(t.Context(), "") + _, err = e.FuturesNotionalBracket(t.Context(), "") if err != nil { t.Error(err) } @@ -1071,8 +1071,8 @@ func TestUGetNotionalLeverage(t *testing.T) { func TestFuturesPositionsADLEstimate(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.FuturesPositionsADLEstimate(t.Context(), currency.EMPTYPAIR) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FuturesPositionsADLEstimate(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } @@ -1080,7 +1080,7 @@ func TestFuturesPositionsADLEstimate(t *testing.T) { func TestGetMarkPriceKline(t *testing.T) { t.Parallel() - _, err := b.GetMarkPriceKline(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) + _, err := e.GetMarkPriceKline(t.Context(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -1088,7 +1088,7 @@ func TestGetMarkPriceKline(t *testing.T) { func TestGetExchangeInfo(t *testing.T) { t.Parallel() - info, err := b.GetExchangeInfo(t.Context()) + info, err := e.GetExchangeInfo(t.Context()) require.NoError(t, err, "GetExchangeInfo must not error") if mockTests { exp := time.Date(2024, 5, 10, 6, 8, 1, int(707*time.Millisecond), time.UTC) @@ -1100,17 +1100,17 @@ func TestGetExchangeInfo(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := b.FetchTradablePairs(t.Context(), asset.Spot) + _, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Error("Binance FetchTradablePairs(asset asets.AssetType) error", err) } - _, err = b.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) + _, err = e.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) + _, err = e.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -1118,7 +1118,7 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook(t.Context(), + _, err := e.GetOrderBook(t.Context(), OrderBookDataRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 1000, @@ -1130,7 +1130,7 @@ func TestGetOrderBook(t *testing.T) { func TestGetMostRecentTrades(t *testing.T) { t.Parallel() - _, err := b.GetMostRecentTrades(t.Context(), + _, err := e.GetMostRecentTrades(t.Context(), RecentTradeRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 15, @@ -1142,7 +1142,7 @@ func TestGetMostRecentTrades(t *testing.T) { func TestGetHistoricalTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricalTrades(t.Context(), "BTCUSDT", 5, -1) + _, err := e.GetHistoricalTrades(t.Context(), "BTCUSDT", 5, -1) if !mockTests && err == nil { t.Errorf("Binance GetHistoricalTrades() error: %v", "expected error") } else if mockTests && err != nil { @@ -1152,7 +1152,7 @@ func TestGetHistoricalTrades(t *testing.T) { func TestGetAggregatedTrades(t *testing.T) { t.Parallel() - _, err := b.GetAggregatedTrades(t.Context(), + _, err := e.GetAggregatedTrades(t.Context(), &AggregatedTradeRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 5, @@ -1165,7 +1165,7 @@ func TestGetAggregatedTrades(t *testing.T) { func TestGetSpotKline(t *testing.T) { t.Parallel() start, end := getTime() - r, err := b.GetSpotKline(t.Context(), &KlinesRequestParams{ + r, err := e.GetSpotKline(t.Context(), &KlinesRequestParams{ Symbol: currency.NewBTCUSDT(), Interval: kline.FiveMin.Short(), Limit: 24, @@ -1197,7 +1197,7 @@ func TestGetSpotKline(t *testing.T) { func TestGetAveragePrice(t *testing.T) { t.Parallel() - _, err := b.GetAveragePrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetAveragePrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetAveragePrice() error", err) } @@ -1206,7 +1206,7 @@ func TestGetAveragePrice(t *testing.T) { func TestGetPriceChangeStats(t *testing.T) { t.Parallel() - _, err := b.GetPriceChangeStats(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetPriceChangeStats(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetPriceChangeStats() error", err) } @@ -1214,10 +1214,10 @@ func TestGetPriceChangeStats(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - _, err := b.GetTickers(t.Context()) + _, err := e.GetTickers(t.Context()) require.NoError(t, err) - resp, err := b.GetTickers(t.Context(), + resp, err := e.GetTickers(t.Context(), currency.NewBTCUSDT(), currency.NewPair(currency.ETH, currency.USDT)) require.NoError(t, err) @@ -1227,7 +1227,7 @@ func TestGetTickers(t *testing.T) { func TestGetLatestSpotPrice(t *testing.T) { t.Parallel() - _, err := b.GetLatestSpotPrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetLatestSpotPrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetLatestSpotPrice() error", err) } @@ -1236,7 +1236,7 @@ func TestGetLatestSpotPrice(t *testing.T) { func TestGetBestPrice(t *testing.T) { t.Parallel() - _, err := b.GetBestPrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetBestPrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetBestPrice() error", err) } @@ -1245,11 +1245,11 @@ func TestGetBestPrice(t *testing.T) { func TestQueryOrder(t *testing.T) { t.Parallel() - _, err := b.QueryOrder(t.Context(), currency.NewBTCUSDT(), "", 1337) + _, err := e.QueryOrder(t.Context(), currency.NewBTCUSDT(), "", 1337) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("QueryOrder() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("QueryOrder() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock QueryOrder() error", err) @@ -1258,14 +1258,14 @@ func TestQueryOrder(t *testing.T) { func TestOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.OpenOrders(t.Context(), currency.EMPTYPAIR) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.OpenOrders(t.Context(), currency.EMPTYPAIR) if err != nil { t.Error(err) } p := currency.NewBTCUSDT() - _, err = b.OpenOrders(t.Context(), p) + _, err = e.OpenOrders(t.Context(), p) if err != nil { t.Error(err) } @@ -1274,11 +1274,11 @@ func TestOpenOrders(t *testing.T) { func TestAllOrders(t *testing.T) { t.Parallel() - _, err := b.AllOrders(t.Context(), currency.NewBTCUSDT(), "", "") + _, err := e.AllOrders(t.Context(), currency.NewBTCUSDT(), "", "") switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("AllOrders() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("AllOrders() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock AllOrders() error", err) @@ -1290,11 +1290,11 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(b) || mockTests { + if !sharedtestvalues.AreAPICredentialsSet(e) || mockTests { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -1310,9 +1310,9 @@ func TestGetFee(t *testing.T) { feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(b) && mockTests { + if sharedtestvalues.AreAPICredentialsSet(e) && mockTests { // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -1320,21 +1320,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -1342,14 +1342,14 @@ func TestGetFee(t *testing.T) { // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -1357,7 +1357,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -1365,7 +1365,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -1374,7 +1374,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -1393,11 +1393,11 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err = b.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetActiveOrders() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("GetActiveOrders() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock GetActiveOrders() error", err) @@ -1413,7 +1413,7 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) if err == nil { t.Error("Expected: 'At least one currency is required to fetch order history'. received nil") } @@ -1423,11 +1423,11 @@ func TestGetOrderHistory(t *testing.T) { currency.BTC), } - _, err = b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetOrderHistory() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("GetOrderHistory() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock GetOrderHistory() error", err) @@ -1446,11 +1446,11 @@ func TestNewOrderTest(t *testing.T) { TimeInForce: order.GoodTillCancel.String(), } - err := b.NewOrderTest(t.Context(), req) + err := e.NewOrderTest(t.Context(), req) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("NewOrderTest() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("NewOrderTest() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock NewOrderTest() error", err) @@ -1464,11 +1464,11 @@ func TestNewOrderTest(t *testing.T) { QuoteOrderQty: 10, } - err = b.NewOrderTest(t.Context(), req) + err = e.NewOrderTest(t.Context(), req) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("NewOrderTest() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("NewOrderTest() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock NewOrderTest() error", err) @@ -1480,7 +1480,7 @@ func TestGetHistoricTrades(t *testing.T) { p := currency.NewBTCUSDT() start := time.Unix(1577977445, 0) // 2020-01-02 15:04:05 end := start.Add(15 * time.Minute) // 2020-01-02 15:19:05 - result, err := b.GetHistoricTrades(t.Context(), p, asset.Spot, start, end) + result, err := e.GetHistoricTrades(t.Context(), p, asset.Spot, start, end) assert.NoError(t, err, "GetHistoricTrades should not error") expected := 2134 if mockTests { @@ -1570,7 +1570,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) { if tt.mock != mockTests { t.Skip("mock mismatch, skipping") } - result, err := b.GetAggregatedTrades(t.Context(), tt.args) + result, err := e.GetAggregatedTrades(t.Context(), tt.args) if err != nil { t.Error(err) } @@ -1619,7 +1619,7 @@ func TestGetAggregatedTradesErrors(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() - _, err := b.GetAggregatedTrades(t.Context(), tt.args) + _, err := e.GetAggregatedTrades(t.Context(), tt.args) if err == nil { t.Errorf("Binance.GetAggregatedTrades() error = %v, wantErr true", err) return @@ -1635,11 +1635,11 @@ func TestSubmitOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "_", Base: currency.LTC, @@ -1653,11 +1653,11 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - _, err := b.SubmitOrder(t.Context(), orderSubmission) + _, err := e.SubmitOrder(t.Context(), orderSubmission) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("SubmitOrder() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("SubmitOrder() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock SubmitOrder() error", err) @@ -1668,7 +1668,7 @@ func TestCancelExchangeOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderCancellation := &order.Cancel{ OrderID: "1", @@ -1677,11 +1677,11 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("CancelExchangeOrder() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("CancelExchangeOrder() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock CancelExchangeOrder() error", err) @@ -1692,7 +1692,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderCancellation := &order.Cancel{ OrderID: "1", @@ -1701,11 +1701,11 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.CancelAllOrders(t.Context(), orderCancellation) + _, err := e.CancelAllOrders(t.Context(), orderCancellation) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("CancelAllExchangeOrders() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("CancelAllExchangeOrders() expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock CancelAllExchangeOrders() error", err) @@ -1714,7 +1714,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) items := asset.Items{ asset.CoinMarginedFutures, asset.USDTMarginedFutures, @@ -1725,7 +1725,7 @@ func TestGetAccountInfo(t *testing.T) { assetType := items[i] t.Run(fmt.Sprintf("Update info of account [%s]", assetType.String()), func(t *testing.T) { t.Parallel() - _, err := b.UpdateAccountInfo(t.Context(), assetType) + _, err := e.UpdateAccountInfo(t.Context(), assetType) if err != nil { t.Error(err) } @@ -1735,12 +1735,12 @@ func TestGetAccountInfo(t *testing.T) { func TestWrapperGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) p, err := currency.NewPairFromString("EOS-USDT") if err != nil { t.Error(err) } - _, err = b.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ + _, err = e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, Side: order.AnySide, Pairs: currency.Pairs{p}, @@ -1754,7 +1754,7 @@ func TestWrapperGetActiveOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ + _, err = e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, Side: order.AnySide, Pairs: currency.Pairs{p2}, @@ -1767,12 +1767,12 @@ func TestWrapperGetActiveOrders(t *testing.T) { func TestWrapperGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) p, err := currency.NewPairFromString("EOSUSD_PERP") if err != nil { t.Error(err) } - _, err = b.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + _, err = e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, Side: order.AnySide, FromOrderID: "123", @@ -1787,7 +1787,7 @@ func TestWrapperGetOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + _, err = e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, Side: order.AnySide, FromOrderID: "123", @@ -1798,7 +1798,7 @@ func TestWrapperGetOrderHistory(t *testing.T) { t.Error(err) } - _, err = b.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + _, err = e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ AssetType: asset.USDTMarginedFutures, }) if err == nil { @@ -1808,16 +1808,16 @@ func TestWrapperGetOrderHistory(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) p, err := currency.NewPairFromString("EOS-USDT") if err != nil { t.Error(err) } - fPair, err := b.FormatExchangeCurrency(p, asset.CoinMarginedFutures) + fPair, err := e.FormatExchangeCurrency(p, asset.CoinMarginedFutures) if err != nil { t.Error(err) } - err = b.CancelOrder(t.Context(), &order.Cancel{ + err = e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.CoinMarginedFutures, Pair: fPair, OrderID: "1234", @@ -1830,11 +1830,11 @@ func TestCancelOrder(t *testing.T) { if err != nil { t.Error(err) } - fpair2, err := b.FormatExchangeCurrency(p2, asset.USDTMarginedFutures) + fpair2, err := e.FormatExchangeCurrency(p2, asset.USDTMarginedFutures) if err != nil { t.Error(err) } - err = b.CancelOrder(t.Context(), &order.Cancel{ + err = e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.USDTMarginedFutures, Pair: fpair2, OrderID: "1234", @@ -1846,8 +1846,8 @@ func TestCancelOrder(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - tradablePairs, err := b.FetchTradablePairs(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + tradablePairs, err := e.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Error(err) @@ -1855,7 +1855,7 @@ func TestGetOrderInfo(t *testing.T) { if len(tradablePairs) == 0 { t.Fatal("no tradable pairs") } - _, err = b.GetOrderInfo(t.Context(), + _, err = e.GetOrderInfo(t.Context(), "123", tradablePairs[0], asset.CoinMarginedFutures) if err != nil { t.Error(err) @@ -1864,7 +1864,7 @@ func TestGetOrderInfo(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := b.ModifyOrder(t.Context(), + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() error cannot be nil") @@ -1874,9 +1874,9 @@ func TestModifyOrder(t *testing.T) { func TestGetAllCoinsInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetAllCoinsInfo(t.Context()) + _, err := e.GetAllCoinsInfo(t.Context()) if err != nil { t.Error(err) } @@ -1885,11 +1885,11 @@ func TestGetAllCoinsInfo(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } withdrawCryptoRequest := withdraw.Request{ - Exchange: b.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -1898,12 +1898,12 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("Withdraw() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Withdraw() expecting an error when no keys are set") } } @@ -1911,13 +1911,13 @@ func TestWithdraw(t *testing.T) { func TestDepositHistory(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } - _, err := b.DepositHistory(t.Context(), currency.ETH, "", time.Time{}, time.Time{}, 0, 10000) + _, err := e.DepositHistory(t.Context(), currency.ETH, "", time.Time{}, time.Time{}, 0, 10000) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error(err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("expecting an error when no keys are set") } } @@ -1925,20 +1925,20 @@ func TestDepositHistory(t *testing.T) { func TestWithdrawHistory(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } - _, err := b.GetWithdrawalsHistory(t.Context(), currency.ETH, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.ETH, asset.Spot) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetWithdrawalsHistory() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("GetWithdrawalsHistory() expecting an error when no keys are set") } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - _, err := b.WithdrawFiatFunds(t.Context(), + _, err := e.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -1947,7 +1947,7 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - _, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdraw.Request{}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -1956,11 +1956,11 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := b.GetDepositAddress(t.Context(), currency.USDT, "", currency.BNB.String()) + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", currency.BNB.String()) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetDepositAddress() error", err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("GetDepositAddress() error cannot be nil") case mockTests && err != nil: t.Error("Mock GetDepositAddress() error", err) @@ -1969,9 +1969,9 @@ func TestGetDepositAddress(t *testing.T) { func BenchmarkWsHandleData(bb *testing.B) { bb.ReportAllocs() - ap, err := b.CurrencyPairs.GetPairs(asset.Spot, false) + ap, err := e.CurrencyPairs.GetPairs(asset.Spot, false) require.NoError(bb, err) - err = b.CurrencyPairs.StorePairs(asset.Spot, ap, true) + err = e.CurrencyPairs.StorePairs(asset.Spot, ap, true) require.NoError(bb, err) data, err := os.ReadFile("testdata/wsHandleData.json") @@ -1980,21 +1980,21 @@ func BenchmarkWsHandleData(bb *testing.B) { require.Len(bb, lines, 8) go func() { for { - <-b.Websocket.DataHandler + <-e.Websocket.DataHandler } }() for bb.Loop() { for x := range lines { - assert.NoError(bb, b.wsHandleData(lines[x])) + assert.NoError(bb, e.wsHandleData(lines[x])) } } } func TestSubscribe(t *testing.T) { t.Parallel() - b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - channels, err := b.generateSubscriptions() // Note: We grab this before it's overwritten by MockWsInstance below + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + channels, err := e.generateSubscriptions() // Note: We grab this before it's overwritten by MockWsInstance below require.NoError(t, err, "generateSubscriptions must not error") if mockTests { exp := []string{"btcusdt@depth@100ms", "btcusdt@kline_1m", "btcusdt@ticker", "btcusdt@trade", "dogeusdt@depth@100ms", "dogeusdt@kline_1m", "dogeusdt@ticker", "dogeusdt@trade"} @@ -2005,13 +2005,13 @@ func TestSubscribe(t *testing.T) { require.ElementsMatch(tb, req.Params, exp, "Params must have correct channels") return w.WriteMessage(gws.TextMessage, fmt.Appendf(nil, `{"result":null,"id":%d}`, req.ID)) } - b = testexch.MockWsInstance[Binance](t, mockws.CurryWsMockUpgrader(t, mock)) + e = testexch.MockWsInstance[Exchange](t, mockws.CurryWsMockUpgrader(t, mock)) } else { - testexch.SetupWs(t, b) + testexch.SetupWs(t, e) } - err = b.Subscribe(channels) + err = e.Subscribe(channels) require.NoError(t, err, "Subscribe must not error") - err = b.Unsubscribe(channels) + err = e.Unsubscribe(channels) require.NoError(t, err, "Unsubscribe must not error") } @@ -2027,7 +2027,7 @@ func TestSubscribeBadResp(t *testing.T) { require.NoError(tb, err, "Unmarshal must not error") return w.WriteMessage(gws.TextMessage, fmt.Appendf(nil, `{"result":{"error":"carrots"},"id":%d}`, req.ID)) } - b := testexch.MockWsInstance[Binance](t, mockws.CurryWsMockUpgrader(t, mock)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + b := testexch.MockWsInstance[Exchange](t, mockws.CurryWsMockUpgrader(t, mock)) err := b.Subscribe(channels) assert.ErrorIs(t, err, common.ErrUnknownError, "Subscribe should error correctly") assert.ErrorContains(t, err, "carrots", "Subscribe should error containing the carrots") @@ -2036,7 +2036,7 @@ func TestSubscribeBadResp(t *testing.T) { func TestWsTickerUpdate(t *testing.T) { t.Parallel() pressXToJSON := []byte(`{"stream":"btcusdt@ticker","data":{"e":"24hrTicker","E":1580254809477,"s":"BTCUSDT","p":"420.97000000","P":"4.720","w":"9058.27981278","x":"8917.98000000","c":"9338.96000000","Q":"0.17246300","b":"9338.03000000","B":"0.18234600","a":"9339.70000000","A":"0.14097600","o":"8917.99000000","h":"9373.19000000","l":"8862.40000000","v":"72229.53692000","q":"654275356.16896672","O":1580168409456,"C":1580254809456,"F":235294268,"L":235894703,"n":600436}}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -2068,7 +2068,7 @@ func TestWsKlineUpdate(t *testing.T) { "B": "123456" } }}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -2076,7 +2076,7 @@ func TestWsKlineUpdate(t *testing.T) { func TestWsTradeUpdate(t *testing.T) { t.Parallel() - b.SetSaveTradeDataStatus(true) + e.SetSaveTradeDataStatus(true) pressXToJSON := []byte(`{"stream":"btcusdt@trade","data":{ "e": "trade", "E": 1234567891, @@ -2090,7 +2090,7 @@ func TestWsTradeUpdate(t *testing.T) { "m": true, "M": true }}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -2098,9 +2098,9 @@ func TestWsTradeUpdate(t *testing.T) { func TestWsDepthUpdate(t *testing.T) { t.Parallel() - b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - b.setupOrderbookManager(t.Context()) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + e.setupOrderbookManager(t.Context()) seedLastUpdateID := int64(161) book := OrderBook{ Asks: []OrderbookItem{ @@ -2145,17 +2145,17 @@ func TestWsDepthUpdate(t *testing.T) { }}`) p := currency.NewPairWithDelimiter("BTC", "USDT", "-") - if err := b.SeedLocalCacheWithBook(p, &book); err != nil { + if err := e.SeedLocalCacheWithBook(p, &book); err != nil { t.Fatal(err) } - if err := b.wsHandleData(update1); err != nil { + if err := e.wsHandleData(update1); err != nil { t.Fatal(err) } - b.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false + e.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false - ob, err := b.Websocket.Orderbook.GetOrderbook(p, asset.Spot) + ob, err := e.Websocket.Orderbook.GetOrderbook(p, asset.Spot) if err != nil { t.Fatal(err) } @@ -2185,11 +2185,11 @@ func TestWsDepthUpdate(t *testing.T) { ] }}`) - if err = b.wsHandleData(update2); err != nil { + if err = e.wsHandleData(update2); err != nil { t.Error(err) } - ob, err = b.Websocket.Orderbook.GetOrderbook(p, asset.Spot) + ob, err = e.Websocket.Orderbook.GetOrderbook(p, asset.Spot) if err != nil { t.Fatal(err) } @@ -2207,7 +2207,7 @@ func TestWsDepthUpdate(t *testing.T) { } // reset order book sync status - b.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 + e.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 } func TestWsBalanceUpdate(t *testing.T) { @@ -2218,7 +2218,7 @@ func TestWsBalanceUpdate(t *testing.T) { "a": "BTC", "d": "100.00000000", "T": 1573200697068}}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -2250,34 +2250,34 @@ func TestWsOCO(t *testing.T) { } ] }}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } } func TestGetWsAuthStreamKey(t *testing.T) { - key, err := b.GetWsAuthStreamKey(t.Context()) + key, err := e.GetWsAuthStreamKey(t.Context()) switch { case mockTests && err != nil, - !mockTests && sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + !mockTests && sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Fatal(err) - case !mockTests && !sharedtestvalues.AreAPICredentialsSet(b) && err == nil: + case !mockTests && !sharedtestvalues.AreAPICredentialsSet(e) && err == nil: t.Fatal("Expected error") } - if key == "" && (sharedtestvalues.AreAPICredentialsSet(b) || mockTests) { + if key == "" && (sharedtestvalues.AreAPICredentialsSet(e) || mockTests) { t.Error("Expected key") } } func TestMaintainWsAuthStreamKey(t *testing.T) { - err := b.MaintainWsAuthStreamKey(t.Context()) + err := e.MaintainWsAuthStreamKey(t.Context()) switch { case mockTests && err != nil, - !mockTests && sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + !mockTests && sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Fatal(err) - case !mockTests && !sharedtestvalues.AreAPICredentialsSet(b) && err == nil: + case !mockTests && !sharedtestvalues.AreAPICredentialsSet(e) && err == nil: t.Fatal("Expected error") } } @@ -2309,20 +2309,20 @@ func TestGetHistoricCandles(t *testing.T) { t.Parallel() startTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) end := startTime.Add(time.Hour * 24 * 7) - bAssets := b.GetAssetTypes(false) + bAssets := e.GetAssetTypes(false) for i := range bAssets { - cps, err := b.GetAvailablePairs(bAssets[i]) + cps, err := e.GetAvailablePairs(bAssets[i]) require.NoErrorf(t, err, "GetAvailablePairs for asset %s must not error", bAssets[i]) require.NotEmptyf(t, cps, "GetAvailablePairs for asset %s must return at least one pair", bAssets[i]) - err = b.CurrencyPairs.EnablePair(bAssets[i], cps[0]) + err = e.CurrencyPairs.EnablePair(bAssets[i], cps[0]) require.Truef(t, err == nil || errors.Is(err, currency.ErrPairAlreadyEnabled), "EnablePair for asset %s and pair %s must not error: %s", bAssets[i], cps[0], err) - _, err = b.GetHistoricCandles(t.Context(), cps[0], bAssets[i], kline.OneDay, startTime, end) + _, err = e.GetHistoricCandles(t.Context(), cps[0], bAssets[i], kline.OneDay, startTime, end) assert.NoErrorf(t, err, "GetHistoricCandles should not error for asset %s and pair %s", bAssets[i], cps[0]) } startTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) - _, err := b.GetHistoricCandles(t.Context(), currency.NewBTCUSDT(), asset.Spot, kline.Interval(time.Hour*7), startTime, end) + _, err := e.GetHistoricCandles(t.Context(), currency.NewBTCUSDT(), asset.Spot, kline.Interval(time.Hour*7), startTime, end) require.ErrorIs(t, err, kline.ErrRequestExceedsExchangeLimits) } @@ -2330,15 +2330,15 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() startTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) end := startTime.Add(time.Hour * 24 * 7) - bAssets := b.GetAssetTypes(false) + bAssets := e.GetAssetTypes(false) for i := range bAssets { - cps, err := b.GetAvailablePairs(bAssets[i]) + cps, err := e.GetAvailablePairs(bAssets[i]) require.NoErrorf(t, err, "GetAvailablePairs for asset %s must not error", bAssets[i]) require.NotEmptyf(t, cps, "GetAvailablePairs for asset %s must return at least one pair", bAssets[i]) - err = b.CurrencyPairs.EnablePair(bAssets[i], cps[0]) + err = e.CurrencyPairs.EnablePair(bAssets[i], cps[0]) require.Truef(t, err == nil || errors.Is(err, currency.ErrPairAlreadyEnabled), "EnablePair for asset %s and pair %s must not error: %s", bAssets[i], cps[0], err) - _, err = b.GetHistoricCandlesExtended(t.Context(), cps[0], bAssets[i], kline.OneDay, startTime, end) + _, err = e.GetHistoricCandlesExtended(t.Context(), cps[0], bAssets[i], kline.OneDay, startTime, end) assert.NoErrorf(t, err, "GetHistoricCandlesExtended should not error for asset %s and pair %s", bAssets[i], cps[0]) } } @@ -2368,7 +2368,7 @@ func TestFormatExchangeKlineInterval(t *testing.T) { } { t.Run(tc.interval.String(), func(t *testing.T) { t.Parallel() - assert.Equal(t, tc.output, b.FormatExchangeKlineInterval(tc.interval)) + assert.Equal(t, tc.output, e.FormatExchangeKlineInterval(tc.interval)) }) } } @@ -2376,19 +2376,19 @@ func TestFormatExchangeKlineInterval(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() pair := currency.NewBTCUSDT() - _, err := b.GetRecentTrades(t.Context(), + _, err := e.GetRecentTrades(t.Context(), pair, asset.Spot) if err != nil { t.Error(err) } - _, err = b.GetRecentTrades(t.Context(), + _, err = e.GetRecentTrades(t.Context(), pair, asset.USDTMarginedFutures) if err != nil { t.Error(err) } pair.Base = currency.NewCode("BTCUSD") pair.Quote = currency.PERP - _, err = b.GetRecentTrades(t.Context(), + _, err = e.GetRecentTrades(t.Context(), pair, asset.CoinMarginedFutures) if err != nil { t.Error(err) @@ -2397,11 +2397,11 @@ func TestGetRecentTrades(t *testing.T) { func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - _, err := b.GetAvailableTransferChains(t.Context(), currency.BTC) + _, err := e.GetAvailableTransferChains(t.Context(), currency.BTC) switch { - case sharedtestvalues.AreAPICredentialsSet(b) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error(err) - case !sharedtestvalues.AreAPICredentialsSet(b) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("error cannot be nil") case mockTests && err != nil: t.Error(err) @@ -2410,7 +2410,7 @@ func TestGetAvailableTransferChains(t *testing.T) { func TestSeedLocalCache(t *testing.T) { t.Parallel() - err := b.SeedLocalCache(t.Context(), currency.NewBTCUSDT()) + err := e.SeedLocalCache(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Fatal(err) } @@ -2419,7 +2419,7 @@ func TestSeedLocalCache(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() exp := subscription.List{} - pairs, err := b.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) assert.NoError(t, err, "GetEnabledPairs should not error") wsFmt := currency.PairFormat{Uppercase: false, Delimiter: ""} baseExp := subscription.List{ @@ -2436,7 +2436,7 @@ func TestGenerateSubscriptions(t *testing.T) { exp = append(exp, sub) } } - subs, err := b.generateSubscriptions() + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") testsubs.EqualLists(t, exp, subs) } @@ -2460,9 +2460,9 @@ var websocketDepthUpdate = []byte(`{"E":1608001030784,"U":7145637266,"a":[["1945 func TestProcessOrderbookUpdate(t *testing.T) { t.Parallel() - b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - b.setupOrderbookManager(t.Context()) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + e.setupOrderbookManager(t.Context()) p := currency.NewBTCUSDT() var depth WebsocketDepthStream err := json.Unmarshal(websocketDepthUpdate, &depth) @@ -2470,37 +2470,37 @@ func TestProcessOrderbookUpdate(t *testing.T) { t.Fatal(err) } - err = b.obm.stageWsUpdate(&depth, p, asset.Spot) + err = e.obm.stageWsUpdate(&depth, p, asset.Spot) if err != nil { t.Fatal(err) } - err = b.obm.fetchBookViaREST(p) + err = e.obm.fetchBookViaREST(p) if err != nil { t.Fatal(err) } - err = b.obm.cleanup(p) + err = e.obm.cleanup(p) if err != nil { t.Fatal(err) } // reset order book sync status - b.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 + e.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 } func TestUFuturesHistoricalTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) cp, err := currency.NewPairFromString("BTCUSDT") if err != nil { t.Error(err) } - _, err = b.UFuturesHistoricalTrades(t.Context(), cp, "", 5) + _, err = e.UFuturesHistoricalTrades(t.Context(), cp, "", 5) if err != nil { t.Error(err) } - _, err = b.UFuturesHistoricalTrades(t.Context(), cp, "", 0) + _, err = e.UFuturesHistoricalTrades(t.Context(), cp, "", 0) if err != nil { t.Error(err) } @@ -2508,21 +2508,21 @@ func TestUFuturesHistoricalTrades(t *testing.T) { func TestSetExchangeOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(t.Context(), asset.CoinMarginedFutures) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(t.Context(), asset.USDTMarginedFutures) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.USDTMarginedFutures) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(t.Context(), asset.Binary) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Binary) if err == nil { t.Fatal("expected unhandled case") } @@ -2532,7 +2532,7 @@ func TestSetExchangeOrderExecutionLimits(t *testing.T) { t.Fatal(err) } - limit, err := b.GetOrderExecutionLimits(asset.CoinMarginedFutures, cmfCP) + limit, err := e.GetOrderExecutionLimits(asset.CoinMarginedFutures, cmfCP) if err != nil { t.Fatal(err) } @@ -2550,8 +2550,8 @@ func TestSetExchangeOrderExecutionLimits(t *testing.T) { func TestWsOrderExecutionReport(t *testing.T) { t.Parallel() - b := new(Binance) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616627567900,"s":"BTCUSDT","c":"c4wyKsIhoAaittTYlIVLqk","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028400","p":"52789.10000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"NEW","X":"NEW","r":"NONE","i":5340845958,"l":"0.00000000","z":"0.00000000","L":"0.00000000","n":"0","N":"BTC","T":1616627567900,"t":-1,"I":11388173160,"w":true,"m":false,"M":false,"O":1616627567900,"Z":"0.00000000","Y":"0.00000000","Q":"0.00000000","W":1616627567900}}`) // this is a buy BTC order, normally commission is charged in BTC, vice versa. expectedResult := order.Detail{ @@ -2577,15 +2577,15 @@ func TestWsOrderExecutionReport(t *testing.T) { Pair: currency.NewBTCUSDT(), } // empty the channel. otherwise mock_test will fail - for len(b.Websocket.DataHandler) > 0 { - <-b.Websocket.DataHandler + for len(e.Websocket.DataHandler) > 0 { + <-e.Websocket.DataHandler } - err := b.wsHandleData(payload) + err := e.wsHandleData(payload) if err != nil { t.Fatal(err) } - res := <-b.Websocket.DataHandler + res := <-e.Websocket.DataHandler switch r := res.(type) { case *order.Detail: if !reflect.DeepEqual(expectedResult, *r) { @@ -2596,7 +2596,7 @@ func TestWsOrderExecutionReport(t *testing.T) { } payload = []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616633041556,"s":"BTCUSDT","c":"YeULctvPAnHj5HXCQo9Mob","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028600","p":"52436.85000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"TRADE","X":"FILLED","r":"NONE","i":5341783271,"l":"0.00028600","z":"0.00028600","L":"52436.85000000","n":"0.00000029","N":"BTC","T":1616633041555,"t":726946523,"I":11390206312,"w":false,"m":false,"M":true,"O":1616633041555,"Z":"14.99693910","Y":"14.99693910","Q":"0.00000000","W":1616633041555}}`) - err = b.wsHandleData(payload) + err = e.wsHandleData(payload) if err != nil { t.Fatal(err) } @@ -2605,7 +2605,7 @@ func TestWsOrderExecutionReport(t *testing.T) { func TestWsOutboundAccountPosition(t *testing.T) { t.Parallel() payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"outboundAccountPosition","E":1616628815745,"u":1616628815745,"B":[{"a":"BTC","f":"0.00225109","l":"0.00123000"},{"a":"BNB","f":"0.00000000","l":"0.00000000"},{"a":"USDT","f":"54.43390661","l":"0.00000000"}]}}`) - if err := b.wsHandleData(payload); err != nil { + if err := e.wsHandleData(payload); err != nil { t.Fatal(err) } } @@ -2660,7 +2660,7 @@ func TestFormatExchangeCurrency(t *testing.T) { tt := testerinos[i] t.Run(tt.name, func(t *testing.T) { t.Parallel() - result, err := b.FormatExchangeCurrency(tt.pair, tt.asset) + result, err := e.FormatExchangeCurrency(tt.pair, tt.asset) if err != nil { t.Error(err) } @@ -2720,7 +2720,7 @@ func TestFormatSymbol(t *testing.T) { for _, tt := range testerinos { t.Run(tt.name, func(t *testing.T) { t.Parallel() - result, err := b.FormatSymbol(tt.pair, tt.asset) + result, err := e.FormatSymbol(tt.pair, tt.asset) if err != nil { t.Error(err) } @@ -2734,12 +2734,12 @@ func TestFormatSymbol(t *testing.T) { func TestFormatUSDTMarginedFuturesPair(t *testing.T) { t.Parallel() pairFormat := currency.PairFormat{Uppercase: true} - resp := b.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.USDT), pairFormat) + resp := e.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.USDT), pairFormat) if resp.String() != "DOGEUSDT" { t.Errorf("received '%v' expected '%v'", resp.String(), "DOGEUSDT") } - resp = b.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.NewCode("1234567890")), pairFormat) + resp = e.formatUSDTMarginedFuturesPair(currency.NewPair(currency.DOGE, currency.NewCode("1234567890")), pairFormat) if resp.String() != "DOGE_1234567890" { t.Errorf("received '%v' expected '%v'", resp.String(), "DOGE_1234567890") } @@ -2747,15 +2747,15 @@ func TestFormatUSDTMarginedFuturesPair(t *testing.T) { func TestFetchExchangeLimits(t *testing.T) { t.Parallel() - limits, err := b.FetchExchangeLimits(t.Context(), asset.Spot) + limits, err := e.FetchExchangeLimits(t.Context(), asset.Spot) assert.NoError(t, err, "FetchExchangeLimits should not error") assert.NotEmpty(t, limits, "Should get some limits back") - limits, err = b.FetchExchangeLimits(t.Context(), asset.Margin) + limits, err = e.FetchExchangeLimits(t.Context(), asset.Margin) assert.NoError(t, err, "FetchExchangeLimits should not error") assert.NotEmpty(t, limits, "Should get some limits back") - _, err = b.FetchExchangeLimits(t.Context(), asset.Futures) + _, err = e.FetchExchangeLimits(t.Context(), asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported, "FetchExchangeLimits should error on other asset types") } @@ -2767,18 +2767,18 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { asset.Margin: currency.NewPair(currency.ETH, currency.BTC), } for _, a := range []asset.Item{asset.CoinMarginedFutures, asset.USDTMarginedFutures} { - pairs, err := b.FetchTradablePairs(t.Context(), a) + pairs, err := e.FetchTradablePairs(t.Context(), a) require.NoErrorf(t, err, "FetchTradablePairs must not error for %s", a) require.NotEmptyf(t, pairs, "Must get some pairs for %s", a) tests[a] = pairs[0] } - for _, a := range b.GetAssetTypes(false) { - err := b.UpdateOrderExecutionLimits(t.Context(), a) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateOrderExecutionLimits(t.Context(), a) require.NoError(t, err, "UpdateOrderExecutionLimits must not error") p := tests[a] - limits, err := b.GetOrderExecutionLimits(a, p) + limits, err := e.GetOrderExecutionLimits(a, p) require.NoErrorf(t, err, "GetOrderExecutionLimits must not error for %s pair %s", a, p) assert.Positivef(t, limits.MinPrice, "MinPrice should be positive for %s pair %s", a, p) assert.Positivef(t, limits.MaxPrice, "MaxPrice should be positive for %s pair %s", a, p) @@ -2806,22 +2806,22 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestGetHistoricalFundingRates(t *testing.T) { t.Parallel() - s, e := getTime() - _, err := b.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + start, end := getTime() + _, err := e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), - StartDate: s, - EndDate: e, + StartDate: start, + EndDate: end, IncludePayments: true, IncludePredictedRate: true, }) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) - _, err = b.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), - StartDate: s, - EndDate: e, + StartDate: start, + EndDate: end, PaymentCurrency: currency.DOGE, }) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) @@ -2829,13 +2829,13 @@ func TestGetHistoricalFundingRates(t *testing.T) { r := &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), - StartDate: s, - EndDate: e, + StartDate: start, + EndDate: end, } - if sharedtestvalues.AreAPICredentialsSet(b) { + if sharedtestvalues.AreAPICredentialsSet(e) { r.IncludePayments = true } - _, err = b.GetHistoricalFundingRates(t.Context(), r) + _, err = e.GetHistoricalFundingRates(t.Context(), r) if err != nil { t.Error(err) } @@ -2845,7 +2845,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricalFundingRates(t.Context(), r) + _, err = e.GetHistoricalFundingRates(t.Context(), r) if err != nil { t.Error(err) } @@ -2854,23 +2854,23 @@ func TestGetHistoricalFundingRates(t *testing.T) { func TestGetLatestFundingRates(t *testing.T) { t.Parallel() cp := currency.NewBTCUSDT() - _, err := b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: cp, IncludePredictedRate: true, }) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) - err = b.CurrencyPairs.EnablePair(asset.USDTMarginedFutures, cp) + err = e.CurrencyPairs.EnablePair(asset.USDTMarginedFutures, cp) require.Truef(t, err == nil || errors.Is(err, currency.ErrPairAlreadyEnabled), "EnablePair for asset %s and pair %s must not error: %s", asset.USDTMarginedFutures, cp, err) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: cp, }) assert.NoError(t, err, "GetLatestFundingRates should not error for USDTMarginedFutures") - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.CoinMarginedFutures, }) assert.NoError(t, err, "GetLatestFundingRates should not error for CoinMarginedFutures") @@ -2878,7 +2878,7 @@ func TestGetLatestFundingRates(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := b.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) + is, err := e.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) if err != nil { t.Error(err) } @@ -2886,14 +2886,14 @@ func TestIsPerpetualFutureCurrency(t *testing.T) { t.Error("expected false") } - is, err = b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSDT()) + is, err = e.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSDT()) if err != nil { t.Error(err) } if is { t.Error("expected false") } - is, err = b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewPair(currency.BTC, currency.PERP)) + is, err = e.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewPair(currency.BTC, currency.PERP)) if err != nil { t.Error(err) } @@ -2901,14 +2901,14 @@ func TestIsPerpetualFutureCurrency(t *testing.T) { t.Error("expected true") } - is, err = b.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewBTCUSDT()) + is, err = e.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewBTCUSDT()) if err != nil { t.Error(err) } if !is { t.Error("expected true") } - is, err = b.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewPair(currency.BTC, currency.PERP)) + is, err = e.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, currency.NewPair(currency.BTC, currency.PERP)) if err != nil { t.Error(err) } @@ -2919,8 +2919,8 @@ func TestIsPerpetualFutureCurrency(t *testing.T) { func TestGetUserMarginInterestHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetUserMarginInterestHistory(t.Context(), currency.USDT, currency.NewBTCUSDT(), time.Now().Add(-time.Hour*24), time.Now(), 1, 10, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetUserMarginInterestHistory(t.Context(), currency.USDT, currency.NewBTCUSDT(), time.Now().Add(-time.Hour*24), time.Now(), 1, 10, false) if err != nil { t.Error(err) } @@ -2928,57 +2928,57 @@ func TestGetUserMarginInterestHistory(t *testing.T) { func TestSetAssetsMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - is, err := b.GetAssetsMode(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + is, err := e.GetAssetsMode(t.Context()) assert.NoError(t, err) - err = b.SetAssetsMode(t.Context(), !is) + err = e.SetAssetsMode(t.Context(), !is) assert.NoError(t, err) - err = b.SetAssetsMode(t.Context(), is) + err = e.SetAssetsMode(t.Context(), is) assert.NoError(t, err) } func TestGetAssetsMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAssetsMode(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAssetsMode(t.Context()) assert.NoError(t, err) } func TestGetCollateralMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.GetCollateralMode(t.Context(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.GetCollateralMode(t.Context(), asset.Spot) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetCollateralMode(t.Context(), asset.CoinMarginedFutures) + _, err = e.GetCollateralMode(t.Context(), asset.CoinMarginedFutures) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetCollateralMode(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetCollateralMode(t.Context(), asset.USDTMarginedFutures) assert.NoError(t, err) } func TestSetCollateralMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetCollateralMode(t.Context(), asset.Spot, collateral.SingleMode) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetCollateralMode(t.Context(), asset.Spot, collateral.SingleMode) assert.ErrorIs(t, err, asset.ErrNotSupported) - err = b.SetCollateralMode(t.Context(), asset.CoinMarginedFutures, collateral.SingleMode) + err = e.SetCollateralMode(t.Context(), asset.CoinMarginedFutures, collateral.SingleMode) assert.ErrorIs(t, err, asset.ErrNotSupported) - err = b.SetCollateralMode(t.Context(), asset.USDTMarginedFutures, collateral.MultiMode) + err = e.SetCollateralMode(t.Context(), asset.USDTMarginedFutures, collateral.MultiMode) assert.NoError(t, err) - err = b.SetCollateralMode(t.Context(), asset.USDTMarginedFutures, collateral.PortfolioMode) + err = e.SetCollateralMode(t.Context(), asset.USDTMarginedFutures, collateral.PortfolioMode) assert.ErrorIs(t, err, order.ErrCollateralInvalid) } func TestChangePositionMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ChangePositionMargin(t.Context(), &margin.PositionChangeRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ChangePositionMargin(t.Context(), &margin.PositionChangeRequest{ Pair: currency.NewBTCUSDT(), Asset: asset.USDTMarginedFutures, MarginType: margin.Isolated, @@ -2992,10 +2992,10 @@ func TestChangePositionMargin(t *testing.T) { func TestGetPositionSummary(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) bb := currency.NewBTCUSDT() - _, err := b.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ + _, err := e.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ Asset: asset.USDTMarginedFutures, Pair: bb, }) @@ -3004,7 +3004,7 @@ func TestGetPositionSummary(t *testing.T) { } bb.Quote = currency.BUSD - _, err = b.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ + _, err = e.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ Asset: asset.USDTMarginedFutures, Pair: bb, }) @@ -3017,7 +3017,7 @@ func TestGetPositionSummary(t *testing.T) { t.Fatal(err) } bb.Quote = currency.USD - _, err = b.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ + _, err = e.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ Asset: asset.CoinMarginedFutures, Pair: p, UnderlyingPair: bb, @@ -3026,7 +3026,7 @@ func TestGetPositionSummary(t *testing.T) { t.Error(err) } - _, err = b.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ + _, err = e.GetFuturesPositionSummary(t.Context(), &futures.PositionSummaryRequest{ Asset: asset.Spot, Pair: p, UnderlyingPair: bb, @@ -3036,8 +3036,8 @@ func TestGetPositionSummary(t *testing.T) { func TestGetFuturesPositionOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFuturesPositionOrders(t.Context(), &futures.PositionsRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesPositionOrders(t.Context(), &futures.PositionsRequest{ Asset: asset.USDTMarginedFutures, Pairs: []currency.Pair{currency.NewBTCUSDT()}, StartDate: time.Now().Add(-time.Hour * 24 * 70), @@ -3051,7 +3051,7 @@ func TestGetFuturesPositionOrders(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetFuturesPositionOrders(t.Context(), &futures.PositionsRequest{ + _, err = e.GetFuturesPositionOrders(t.Context(), &futures.PositionsRequest{ Asset: asset.CoinMarginedFutures, Pairs: []currency.Pair{p}, StartDate: time.Now().Add(time.Hour * 24 * -70), @@ -3064,26 +3064,26 @@ func TestGetFuturesPositionOrders(t *testing.T) { func TestSetMarginType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - err := b.SetMarginType(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), margin.Isolated) + err := e.SetMarginType(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), margin.Isolated) assert.NoError(t, err) p, err := currency.NewPairFromString("BTCUSD_PERP") if err != nil { t.Fatal(err) } - err = b.SetMarginType(t.Context(), asset.CoinMarginedFutures, p, margin.Isolated) + err = e.SetMarginType(t.Context(), asset.CoinMarginedFutures, p, margin.Isolated) assert.NoError(t, err) - err = b.SetMarginType(t.Context(), asset.Spot, currency.NewBTCUSDT(), margin.Isolated) + err = e.SetMarginType(t.Context(), asset.Spot, currency.NewBTCUSDT(), margin.Isolated) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestGetLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetLeverage(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), 0, order.UnknownSide) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetLeverage(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), 0, order.UnknownSide) if err != nil { t.Error(err) } @@ -3092,18 +3092,18 @@ func TestGetLeverage(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetLeverage(t.Context(), asset.CoinMarginedFutures, p, 0, order.UnknownSide) + _, err = e.GetLeverage(t.Context(), asset.CoinMarginedFutures, p, 0, order.UnknownSide) if err != nil { t.Error(err) } - _, err = b.GetLeverage(t.Context(), asset.Spot, currency.NewBTCUSDT(), 0, order.UnknownSide) + _, err = e.GetLeverage(t.Context(), asset.Spot, currency.NewBTCUSDT(), 0, order.UnknownSide) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestSetLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetLeverage(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), margin.Multi, 5, order.UnknownSide) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetLeverage(t.Context(), asset.USDTMarginedFutures, currency.NewBTCUSDT(), margin.Multi, 5, order.UnknownSide) if err != nil { t.Error(err) } @@ -3112,261 +3112,261 @@ func TestSetLeverage(t *testing.T) { if err != nil { t.Fatal(err) } - err = b.SetLeverage(t.Context(), asset.CoinMarginedFutures, p, margin.Multi, 5, order.UnknownSide) + err = e.SetLeverage(t.Context(), asset.CoinMarginedFutures, p, margin.Multi, 5, order.UnknownSide) if err != nil { t.Error(err) } - err = b.SetLeverage(t.Context(), asset.Spot, p, margin.Multi, 5, order.UnknownSide) + err = e.SetLeverage(t.Context(), asset.Spot, p, margin.Multi, 5, order.UnknownSide) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestGetCryptoLoansIncomeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanIncomeHistory(t.Context(), currency.USDT, "", time.Time{}, time.Time{}, 100); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanIncomeHistory(t.Context(), currency.USDT, "", time.Time{}, time.Time{}, 100); err != nil { t.Error(err) } } func TestCryptoLoanBorrow(t *testing.T) { t.Parallel() - _, err := b.CryptoLoanBorrow(t.Context(), currency.EMPTYCODE, 1000, currency.BTC, 1, 7) + _, err := e.CryptoLoanBorrow(t.Context(), currency.EMPTYCODE, 1000, currency.BTC, 1, 7) assert.ErrorIs(t, err, errLoanCoinMustBeSet) - _, err = b.CryptoLoanBorrow(t.Context(), currency.USDT, 1000, currency.EMPTYCODE, 1, 7) + _, err = e.CryptoLoanBorrow(t.Context(), currency.USDT, 1000, currency.EMPTYCODE, 1, 7) assert.ErrorIs(t, err, errCollateralCoinMustBeSet) - _, err = b.CryptoLoanBorrow(t.Context(), currency.USDT, 0, currency.BTC, 1, 0) + _, err = e.CryptoLoanBorrow(t.Context(), currency.USDT, 0, currency.BTC, 1, 0) assert.ErrorIs(t, err, errLoanTermMustBeSet) - _, err = b.CryptoLoanBorrow(t.Context(), currency.USDT, 0, currency.BTC, 0, 7) + _, err = e.CryptoLoanBorrow(t.Context(), currency.USDT, 0, currency.BTC, 0, 7) assert.ErrorIs(t, err, errEitherLoanOrCollateralAmountsMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.CryptoLoanBorrow(t.Context(), currency.USDT, 1000, currency.BTC, 1, 7); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CryptoLoanBorrow(t.Context(), currency.USDT, 1000, currency.BTC, 1, 7); err != nil { t.Error(err) } } func TestCryptoLoanBorrowHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanBorrowHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanBorrowHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestCryptoLoanOngoingOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanOngoingOrders(t.Context(), 0, currency.USDT, currency.BTC, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanOngoingOrders(t.Context(), 0, currency.USDT, currency.BTC, 0, 0); err != nil { t.Error(err) } } func TestCryptoLoanRepay(t *testing.T) { t.Parallel() - _, err := b.CryptoLoanRepay(t.Context(), 0, 1000, 1, false) + _, err := e.CryptoLoanRepay(t.Context(), 0, 1000, 1, false) assert.ErrorIs(t, err, errOrderIDMustBeSet) - _, err = b.CryptoLoanRepay(t.Context(), 42069, 0, 1, false) + _, err = e.CryptoLoanRepay(t.Context(), 42069, 0, 1, false) assert.ErrorIs(t, err, errAmountMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.CryptoLoanRepay(t.Context(), 42069, 1000, 1, false); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CryptoLoanRepay(t.Context(), 42069, 1000, 1, false); err != nil { t.Error(err) } } func TestCryptoLoanRepaymentHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanRepaymentHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanRepaymentHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestCryptoLoanAdjustLTV(t *testing.T) { t.Parallel() - _, err := b.CryptoLoanAdjustLTV(t.Context(), 0, true, 1) + _, err := e.CryptoLoanAdjustLTV(t.Context(), 0, true, 1) assert.ErrorIs(t, err, errOrderIDMustBeSet) - _, err = b.CryptoLoanAdjustLTV(t.Context(), 42069, true, 0) + _, err = e.CryptoLoanAdjustLTV(t.Context(), 42069, true, 0) assert.ErrorIs(t, err, errAmountMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.CryptoLoanAdjustLTV(t.Context(), 42069, true, 1); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CryptoLoanAdjustLTV(t.Context(), 42069, true, 1); err != nil { t.Error(err) } } func TestCryptoLoanLTVAdjustmentHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanLTVAdjustmentHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanLTVAdjustmentHistory(t.Context(), 0, currency.USDT, currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestCryptoLoanAssetsData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanAssetsData(t.Context(), currency.EMPTYCODE, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanAssetsData(t.Context(), currency.EMPTYCODE, 0); err != nil { t.Error(err) } } func TestCryptoLoanCollateralAssetsData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanCollateralAssetsData(t.Context(), currency.EMPTYCODE, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanCollateralAssetsData(t.Context(), currency.EMPTYCODE, 0); err != nil { t.Error(err) } } func TestCryptoLoanCheckCollateralRepayRate(t *testing.T) { t.Parallel() - _, err := b.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.EMPTYCODE, currency.BNB, 69) + _, err := e.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.EMPTYCODE, currency.BNB, 69) assert.ErrorIs(t, err, errLoanCoinMustBeSet) - _, err = b.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.EMPTYCODE, 69) + _, err = e.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.EMPTYCODE, 69) assert.ErrorIs(t, err, errCollateralCoinMustBeSet) - _, err = b.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.BNB, 0) + _, err = e.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.BNB, 0) assert.ErrorIs(t, err, errAmountMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.BNB, 69); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CryptoLoanCheckCollateralRepayRate(t.Context(), currency.BUSD, currency.BNB, 69); err != nil { t.Error(err) } } func TestCryptoLoanCustomiseMarginCall(t *testing.T) { t.Parallel() - if _, err := b.CryptoLoanCustomiseMarginCall(t.Context(), 0, currency.BTC, 0); err == nil { + if _, err := e.CryptoLoanCustomiseMarginCall(t.Context(), 0, currency.BTC, 0); err == nil { t.Error("expected an error") } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.CryptoLoanCustomiseMarginCall(t.Context(), 1337, currency.BTC, .70); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CryptoLoanCustomiseMarginCall(t.Context(), 1337, currency.BTC, .70); err != nil { t.Error(err) } } func TestFlexibleLoanBorrow(t *testing.T) { t.Parallel() - _, err := b.FlexibleLoanBorrow(t.Context(), currency.EMPTYCODE, currency.USDC, 1, 0) + _, err := e.FlexibleLoanBorrow(t.Context(), currency.EMPTYCODE, currency.USDC, 1, 0) assert.ErrorIs(t, err, errLoanCoinMustBeSet) - _, err = b.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.EMPTYCODE, 1, 0) + _, err = e.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.EMPTYCODE, 1, 0) assert.ErrorIs(t, err, errCollateralCoinMustBeSet) - _, err = b.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.USDC, 0, 0) + _, err = e.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.USDC, 0, 0) assert.ErrorIs(t, err, errEitherLoanOrCollateralAmountsMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.USDC, 1, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.FlexibleLoanBorrow(t.Context(), currency.ATOM, currency.USDC, 1, 0); err != nil { t.Error(err) } } func TestFlexibleLoanOngoingOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleLoanOngoingOrders(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleLoanOngoingOrders(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, 0, 0); err != nil { t.Error(err) } } func TestFlexibleLoanBorrowHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleLoanBorrowHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleLoanBorrowHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestFlexibleLoanRepay(t *testing.T) { t.Parallel() - _, err := b.FlexibleLoanRepay(t.Context(), currency.EMPTYCODE, currency.BTC, 1, false, false) + _, err := e.FlexibleLoanRepay(t.Context(), currency.EMPTYCODE, currency.BTC, 1, false, false) assert.ErrorIs(t, err, errLoanCoinMustBeSet) - _, err = b.FlexibleLoanRepay(t.Context(), currency.USDT, currency.EMPTYCODE, 1, false, false) + _, err = e.FlexibleLoanRepay(t.Context(), currency.USDT, currency.EMPTYCODE, 1, false, false) assert.ErrorIs(t, err, errCollateralCoinMustBeSet) - _, err = b.FlexibleLoanRepay(t.Context(), currency.USDT, currency.BTC, 0, false, false) + _, err = e.FlexibleLoanRepay(t.Context(), currency.USDT, currency.BTC, 0, false, false) assert.ErrorIs(t, err, errAmountMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.FlexibleLoanRepay(t.Context(), currency.ATOM, currency.USDC, 1, false, false); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.FlexibleLoanRepay(t.Context(), currency.ATOM, currency.USDC, 1, false, false); err != nil { t.Error(err) } } func TestFlexibleLoanRepayHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleLoanRepayHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleLoanRepayHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestFlexibleLoanAdjustLTV(t *testing.T) { t.Parallel() - _, err := b.FlexibleLoanAdjustLTV(t.Context(), currency.EMPTYCODE, currency.BTC, 1, true) + _, err := e.FlexibleLoanAdjustLTV(t.Context(), currency.EMPTYCODE, currency.BTC, 1, true) assert.ErrorIs(t, err, errLoanCoinMustBeSet) - _, err = b.FlexibleLoanAdjustLTV(t.Context(), currency.USDT, currency.EMPTYCODE, 1, true) + _, err = e.FlexibleLoanAdjustLTV(t.Context(), currency.USDT, currency.EMPTYCODE, 1, true) assert.ErrorIs(t, err, errCollateralCoinMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - if _, err := b.FlexibleLoanAdjustLTV(t.Context(), currency.USDT, currency.BTC, 1, true); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.FlexibleLoanAdjustLTV(t.Context(), currency.USDT, currency.BTC, 1, true); err != nil { t.Error(err) } } func TestFlexibleLoanLTVAdjustmentHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleLoanLTVAdjustmentHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleLoanLTVAdjustmentHistory(t.Context(), currency.EMPTYCODE, currency.EMPTYCODE, time.Time{}, time.Time{}, 0, 0); err != nil { t.Error(err) } } func TestFlexibleLoanAssetsData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleLoanAssetsData(t.Context(), currency.EMPTYCODE); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleLoanAssetsData(t.Context(), currency.EMPTYCODE); err != nil { t.Error(err) } } func TestFlexibleCollateralAssetsData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if _, err := b.FlexibleCollateralAssetsData(t.Context(), currency.EMPTYCODE); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.FlexibleCollateralAssetsData(t.Context(), currency.EMPTYCODE); err != nil { t.Error(err) } } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := b.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = b.GetFuturesContractDetails(t.Context(), asset.Futures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) assert.NoError(t, err) - _, err = b.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) assert.NoError(t, err) } func TestGetFundingRateInfo(t *testing.T) { t.Parallel() - _, err := b.GetFundingRateInfo(t.Context()) + _, err := e.GetFundingRateInfo(t.Context()) assert.NoError(t, err) } func TestUGetFundingRateInfo(t *testing.T) { t.Parallel() - _, err := b.UGetFundingRateInfo(t.Context()) + _, err := e.UGetFundingRateInfo(t.Context()) assert.NoError(t, err) } func TestGetOpenInterest(t *testing.T) { t.Parallel() - resp, err := b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.USDT.Item, Asset: asset.USDTMarginedFutures, @@ -3374,7 +3374,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.NewCode("BTCUSD").Item, Quote: currency.PERP.Item, Asset: asset.CoinMarginedFutures, @@ -3382,7 +3382,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - _, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.USDT.Item, Asset: asset.Spot, @@ -3392,12 +3392,12 @@ func TestGetOpenInterest(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/binance/binance_ufutures.go b/exchanges/binance/binance_ufutures.go index b9bc4f6ae35..2c223013eec 100644 --- a/exchanges/binance/binance_ufutures.go +++ b/exchanges/binance/binance_ufutures.go @@ -69,11 +69,11 @@ const ( ) // UServerTime gets the server time -func (b *Binance) UServerTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) UServerTime(ctx context.Context) (time.Time, error) { var data struct { ServerTime types.Time `json:"serverTime"` } - err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesServerTime, uFuturesDefaultRate, &data) + err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesServerTime, uFuturesDefaultRate, &data) if err != nil { return time.Time{}, err } @@ -81,14 +81,14 @@ func (b *Binance) UServerTime(ctx context.Context) (time.Time, error) { } // UExchangeInfo stores usdt margined futures data -func (b *Binance) UExchangeInfo(ctx context.Context) (UFuturesExchangeInfo, error) { +func (e *Exchange) UExchangeInfo(ctx context.Context) (UFuturesExchangeInfo, error) { var resp UFuturesExchangeInfo - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesExchangeInfo, uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesExchangeInfo, uFuturesDefaultRate, &resp) } // UFuturesOrderbook gets orderbook data for usdt margined futures -func (b *Binance) UFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (*OrderBook, error) { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) +func (e *Exchange) UFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (*OrderBook, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } @@ -114,7 +114,7 @@ func (b *Binance) UFuturesOrderbook(ctx context.Context, symbol currency.Pair, l } var data *OrderbookData - if err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOrderbook+params.Encode(), rateBudget, &data); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOrderbook+params.Encode(), rateBudget, &data); err != nil { return nil, err } @@ -137,10 +137,10 @@ func (b *Binance) UFuturesOrderbook(ctx context.Context, symbol currency.Pair, l } // URecentTrades gets recent trades for usdt margined futures -func (b *Binance) URecentTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { +func (e *Exchange) URecentTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { var resp []UPublicTradesData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -151,14 +151,14 @@ func (b *Binance) URecentTrades(ctx context.Context, symbol currency.Pair, fromI if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesRecentTrades+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesRecentTrades+params.Encode(), uFuturesDefaultRate, &resp) } // UFuturesHistoricalTrades gets historical public trades for USDTMarginedFutures -func (b *Binance) UFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]any, error) { +func (e *Exchange) UFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]any, error) { var resp []any params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -169,14 +169,14 @@ func (b *Binance) UFuturesHistoricalTrades(ctx context.Context, symbol currency. if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesHistoricalTrades, params, uFuturesHistoricalTradesRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesHistoricalTrades, params, uFuturesHistoricalTradesRate, &resp) } // UCompressedTrades gets compressed public trades for usdt margined futures -func (b *Binance) UCompressedTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UCompressedTradeData, error) { +func (e *Exchange) UCompressedTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UCompressedTradeData, error) { var resp []UCompressedTradeData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -194,13 +194,13 @@ func (b *Binance) UCompressedTrades(ctx context.Context, symbol currency.Pair, f params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompressedTrades+params.Encode(), uFuturesHistoricalTradesRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompressedTrades+params.Encode(), uFuturesHistoricalTradesRate, &resp) } // UKlineData gets kline data for usdt margined futures -func (b *Binance) UKlineData(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (e *Exchange) UKlineData(ctx context.Context, symbol currency.Pair, interval string, limit uint64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } @@ -232,7 +232,7 @@ func (b *Binance) UKlineData(ctx context.Context, symbol currency.Pair, interval } var resp []FuturesCandleStick - if err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesKlineData+params.Encode(), rateBudget, &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesKlineData+params.Encode(), rateBudget, &resp); err != nil { return nil, err } @@ -240,23 +240,23 @@ func (b *Binance) UKlineData(ctx context.Context, symbol currency.Pair, interval } // UGetMarkPrice gets mark price data for USDTMarginedFutures -func (b *Binance) UGetMarkPrice(ctx context.Context, symbol currency.Pair) ([]UMarkPrice, error) { +func (e *Exchange) UGetMarkPrice(ctx context.Context, symbol currency.Pair) ([]UMarkPrice, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } params.Set("symbol", symbolValue) var tempResp UMarkPrice - err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &tempResp) + err = e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []UMarkPrice{tempResp}, nil } var resp []UMarkPrice - err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &resp) if err != nil { return nil, err } @@ -264,17 +264,17 @@ func (b *Binance) UGetMarkPrice(ctx context.Context, symbol currency.Pair) ([]UM } // UGetFundingRateInfo returns extra details about funding rates -func (b *Binance) UGetFundingRateInfo(ctx context.Context) ([]FundingRateInfoResponse, error) { +func (e *Exchange) UGetFundingRateInfo(ctx context.Context) ([]FundingRateInfoResponse, error) { var resp []FundingRateInfoResponse - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesFundingRateInfo, uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesFundingRateInfo, uFuturesDefaultRate, &resp) } // UGetFundingHistory gets funding history for USDTMarginedFutures -func (b *Binance) UGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (e *Exchange) UGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { var resp []FundingRateHistory params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -290,89 +290,89 @@ func (b *Binance) UGetFundingHistory(ctx context.Context, symbol currency.Pair, params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesFundingRateHistory+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesFundingRateHistory+params.Encode(), uFuturesDefaultRate, &resp) } // U24HTickerPriceChangeStats gets 24hr ticker price change stats for USDTMarginedFutures -func (b *Binance) U24HTickerPriceChangeStats(ctx context.Context, symbol currency.Pair) ([]U24HrPriceChangeStats, error) { +func (e *Exchange) U24HTickerPriceChangeStats(ctx context.Context, symbol currency.Pair) ([]U24HrPriceChangeStats, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } params.Set("symbol", symbolValue) var tempResp U24HrPriceChangeStats - err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesDefaultRate, &tempResp) + err = e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []U24HrPriceChangeStats{tempResp}, err } var resp []U24HrPriceChangeStats - err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesTickerPriceHistoryRate, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesTickerPriceHistoryRate, &resp) return resp, err } // USymbolPriceTicker gets symbol price ticker for USDTMarginedFutures -func (b *Binance) USymbolPriceTicker(ctx context.Context, symbol currency.Pair) ([]USymbolPriceTicker, error) { +func (e *Exchange) USymbolPriceTicker(ctx context.Context, symbol currency.Pair) ([]USymbolPriceTicker, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } params.Set("symbol", symbolValue) var tempResp USymbolPriceTicker - err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesDefaultRate, &tempResp) + err = e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []USymbolPriceTicker{tempResp}, err } var resp []USymbolPriceTicker - err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) return resp, err } // USymbolOrderbookTicker gets symbol orderbook ticker -func (b *Binance) USymbolOrderbookTicker(ctx context.Context, symbol currency.Pair) ([]USymbolOrderbookTicker, error) { +func (e *Exchange) USymbolOrderbookTicker(ctx context.Context, symbol currency.Pair) ([]USymbolOrderbookTicker, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } params.Set("symbol", symbolValue) var tempResp USymbolOrderbookTicker - err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolOrderbook+params.Encode(), uFuturesDefaultRate, &tempResp) + err = e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolOrderbook+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []USymbolOrderbookTicker{tempResp}, err } var resp []USymbolOrderbookTicker - err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) return resp, err } // UOpenInterest gets open interest data for USDTMarginedFutures -func (b *Binance) UOpenInterest(ctx context.Context, symbol currency.Pair) (UOpenInterestData, error) { +func (e *Exchange) UOpenInterest(ctx context.Context, symbol currency.Pair) (UOpenInterestData, error) { var resp UOpenInterestData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterest+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterest+params.Encode(), uFuturesDefaultRate, &resp) } // UOpenInterestStats gets open interest stats for USDTMarginedFutures -func (b *Binance) UOpenInterestStats(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UOpenInterestStats, error) { +func (e *Exchange) UOpenInterestStats(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UOpenInterestStats, error) { var resp []UOpenInterestStats params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -391,14 +391,14 @@ func (b *Binance) UOpenInterestStats(ctx context.Context, symbol currency.Pair, params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterestStats+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterestStats+params.Encode(), uFuturesDefaultRate, &resp) } // UTopAcccountsLongShortRatio gets long/short ratio data for top trader accounts in ufutures -func (b *Binance) UTopAcccountsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (e *Exchange) UTopAcccountsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -417,14 +417,14 @@ func (b *Binance) UTopAcccountsLongShortRatio(ctx context.Context, symbol curren params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopAccountsRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopAccountsRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UTopPostionsLongShortRatio gets long/short ratio data for top positions' in ufutures -func (b *Binance) UTopPostionsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (e *Exchange) UTopPostionsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -443,14 +443,14 @@ func (b *Binance) UTopPostionsLongShortRatio(ctx context.Context, symbol currenc params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopPositionsRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopPositionsRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UGlobalLongShortRatio gets the global long/short ratio data for USDTMarginedFutures -func (b *Binance) UGlobalLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (e *Exchange) UGlobalLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -469,14 +469,14 @@ func (b *Binance) UGlobalLongShortRatio(ctx context.Context, symbol currency.Pai params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesLongShortRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesLongShortRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UTakerBuySellVol gets takers' buy/sell ratio for USDTMarginedFutures -func (b *Binance) UTakerBuySellVol(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UTakerVolumeData, error) { +func (e *Exchange) UTakerBuySellVol(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UTakerVolumeData, error) { var resp []UTakerVolumeData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -495,34 +495,34 @@ func (b *Binance) UTakerBuySellVol(ctx context.Context, symbol currency.Pair, pe params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesBuySellVolume+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesBuySellVolume+params.Encode(), uFuturesDefaultRate, &resp) } // UCompositeIndexInfo stores composite indexs' info for usdt margined futures -func (b *Binance) UCompositeIndexInfo(ctx context.Context, symbol currency.Pair) ([]UCompositeIndexInfoData, error) { +func (e *Exchange) UCompositeIndexInfo(ctx context.Context, symbol currency.Pair) ([]UCompositeIndexInfoData, error) { params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return nil, err } params.Set("symbol", symbolValue) var tempResp UCompositeIndexInfoData - err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &tempResp) + err = e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []UCompositeIndexInfoData{tempResp}, err } var resp []UCompositeIndexInfoData - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &resp) } // UFuturesNewOrder sends a new order for USDTMarginedFutures -func (b *Binance) UFuturesNewOrder(ctx context.Context, data *UFuturesNewOrderRequest) (UOrderData, error) { +func (e *Exchange) UFuturesNewOrder(ctx context.Context, data *UFuturesNewOrderRequest) (UOrderData, error) { var resp UOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(data.Symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(data.Symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -572,11 +572,11 @@ func (b *Binance) UFuturesNewOrder(ctx context.Context, data *UFuturesNewOrderRe if data.CallbackRate != 0 { params.Set("callbackRate", strconv.FormatFloat(data.CallbackRate, 'f', -1, 64)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UPlaceBatchOrders places batch orders -func (b *Binance) UPlaceBatchOrders(ctx context.Context, data []PlaceBatchOrderData) ([]UOrderData, error) { +func (e *Exchange) UPlaceBatchOrders(ctx context.Context, data []PlaceBatchOrderData) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} for x := range data { @@ -584,7 +584,7 @@ func (b *Binance) UPlaceBatchOrders(ctx context.Context, data []PlaceBatchOrderD if err != nil { return resp, err } - formattedPair, err := b.FormatExchangeCurrency(unformattedPair, asset.USDTMarginedFutures) + formattedPair, err := e.FormatExchangeCurrency(unformattedPair, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -610,14 +610,14 @@ func (b *Binance) UPlaceBatchOrders(ctx context.Context, data []PlaceBatchOrderD return resp, err } params.Set("batchOrders", string(jsonData)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesBatchOrder, params, uFuturesBatchOrdersRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesBatchOrder, params, uFuturesBatchOrdersRate, &resp) } // UGetOrderData gets order data for USDTMarginedFutures -func (b *Binance) UGetOrderData(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { +func (e *Exchange) UGetOrderData(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -628,14 +628,14 @@ func (b *Binance) UGetOrderData(ctx context.Context, symbol currency.Pair, order if cliOrderID != "" { params.Set("origClientOrderId", cliOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UCancelOrder cancel an order for USDTMarginedFutures -func (b *Binance) UCancelOrder(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { +func (e *Exchange) UCancelOrder(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -646,26 +646,26 @@ func (b *Binance) UCancelOrder(ctx context.Context, symbol currency.Pair, orderI if cliOrderID != "" { params.Set("origClientOrderId", cliOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UCancelAllOpenOrders cancels all open orders for a symbol ufutures -func (b *Binance) UCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { +func (e *Exchange) UCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesCancelAllOrders, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesCancelAllOrders, params, uFuturesOrdersDefaultRate, &resp) } // UCancelBatchOrders cancel batch order for USDTMarginedFutures -func (b *Binance) UCancelBatchOrders(ctx context.Context, symbol currency.Pair, orderIDList, origCliOrdIDList []string) ([]UOrderData, error) { +func (e *Exchange) UCancelBatchOrders(ctx context.Context, symbol currency.Pair, orderIDList, origCliOrdIDList []string) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -684,28 +684,28 @@ func (b *Binance) UCancelBatchOrders(ctx context.Context, symbol currency.Pair, } params.Set("origClientOrderIdList", string(jsonCliOrders)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesBatchOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesBatchOrder, params, uFuturesOrdersDefaultRate, &resp) } // UAutoCancelAllOpenOrders auto cancels all ufutures open orders for a symbol after the set countdown time -func (b *Binance) UAutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { +func (e *Exchange) UAutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { var resp AutoCancelAllOrdersData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) params.Set("countdownTime", strconv.FormatInt(countdownTime, 10)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesCountdownCancel, params, uFuturesCountdownCancelRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesCountdownCancel, params, uFuturesCountdownCancelRate, &resp) } // UFetchOpenOrder sends a request to fetch open order data for USDTMarginedFutures -func (b *Binance) UFetchOpenOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (UOrderData, error) { +func (e *Exchange) UFetchOpenOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -717,17 +717,17 @@ func (b *Binance) UFetchOpenOrder(ctx context.Context, symbol currency.Pair, ord if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOpenOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOpenOrder, params, uFuturesOrdersDefaultRate, &resp) } // UAllAccountOpenOrders gets all account's orders for USDTMarginedFutures -func (b *Binance) UAllAccountOpenOrders(ctx context.Context, symbol currency.Pair) ([]UOrderData, error) { +func (e *Exchange) UAllAccountOpenOrders(ctx context.Context, symbol currency.Pair) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} rateLimit := uFuturesGetAllOpenOrdersRate if !symbol.IsEmpty() { rateLimit = uFuturesOrdersDefaultRate - p, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + p, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -736,14 +736,14 @@ func (b *Binance) UAllAccountOpenOrders(ctx context.Context, symbol currency.Pai // extend the receive window when all currencies to prevent "recvwindow" error params.Set("recvWindow", "10000") } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOpenOrders, params, rateLimit, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOpenOrders, params, rateLimit, &resp) } // UAllAccountOrders gets all account's orders for USDTMarginedFutures -func (b *Binance) UAllAccountOrders(ctx context.Context, symbol currency.Pair, orderID, limit int64, startTime, endTime time.Time) ([]UFuturesOrderData, error) { +func (e *Exchange) UAllAccountOrders(ctx context.Context, symbol currency.Pair, orderID, limit int64, startTime, endTime time.Time) ([]UFuturesOrderData, error) { var resp []UFuturesOrderData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -760,26 +760,26 @@ func (b *Binance) UAllAccountOrders(ctx context.Context, symbol currency.Pair, o if !endTime.IsZero() { params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOrders, params, uFuturesGetAllOrdersRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOrders, params, uFuturesGetAllOrdersRate, &resp) } // UAccountBalanceV2 gets V2 account balance data -func (b *Binance) UAccountBalanceV2(ctx context.Context) ([]UAccountBalanceV2Data, error) { +func (e *Exchange) UAccountBalanceV2(ctx context.Context) ([]UAccountBalanceV2Data, error) { var resp []UAccountBalanceV2Data - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountBalance, nil, uFuturesOrdersDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountBalance, nil, uFuturesOrdersDefaultRate, &resp) } // UAccountInformationV2 gets V2 account balance data -func (b *Binance) UAccountInformationV2(ctx context.Context) (UAccountInformationV2Data, error) { +func (e *Exchange) UAccountInformationV2(ctx context.Context) (UAccountInformationV2Data, error) { var resp UAccountInformationV2Data - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountInfo, nil, uFuturesAccountInformationRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountInfo, nil, uFuturesAccountInformationRate, &resp) } // UChangeInitialLeverageRequest sends a request to change account's initial leverage -func (b *Binance) UChangeInitialLeverageRequest(ctx context.Context, symbol currency.Pair, leverage float64) (UChangeInitialLeverage, error) { +func (e *Exchange) UChangeInitialLeverageRequest(ctx context.Context, symbol currency.Pair, leverage float64) (UChangeInitialLeverage, error) { var resp UChangeInitialLeverage params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -788,13 +788,13 @@ func (b *Binance) UChangeInitialLeverageRequest(ctx context.Context, symbol curr return resp, errors.New("invalid leverage") } params.Set("leverage", strconv.FormatFloat(leverage, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeInitialLeverage, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeInitialLeverage, params, uFuturesDefaultRate, &resp) } // UChangeInitialMarginType sends a request to change account's initial margin type -func (b *Binance) UChangeInitialMarginType(ctx context.Context, symbol currency.Pair, marginType string) error { +func (e *Exchange) UChangeInitialMarginType(ctx context.Context, symbol currency.Pair, marginType string) error { params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return err } @@ -803,14 +803,14 @@ func (b *Binance) UChangeInitialMarginType(ctx context.Context, symbol currency. return errors.New("invalid marginType") } params.Set("marginType", marginType) - return b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeMarginType, params, uFuturesDefaultRate, nil) + return e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeMarginType, params, uFuturesDefaultRate, nil) } // UModifyIsolatedPositionMarginReq sends a request to modify isolated margin for USDTMarginedFutures -func (b *Binance) UModifyIsolatedPositionMarginReq(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (UModifyIsolatedPosMargin, error) { +func (e *Exchange) UModifyIsolatedPositionMarginReq(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (UModifyIsolatedPosMargin, error) { var resp UModifyIsolatedPosMargin params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -824,14 +824,14 @@ func (b *Binance) UModifyIsolatedPositionMarginReq(ctx context.Context, symbol c params.Set("positionSide", positionSide) } params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesModifyMargin, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesModifyMargin, params, uFuturesDefaultRate, &resp) } // UPositionMarginChangeHistory gets margin change history for USDTMarginedFutures -func (b *Binance) UPositionMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, limit int64, startTime, endTime time.Time) ([]UPositionMarginChangeHistoryData, error) { +func (e *Exchange) UPositionMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, limit int64, startTime, endTime time.Time) ([]UPositionMarginChangeHistoryData, error) { var resp []UPositionMarginChangeHistoryData params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -851,42 +851,42 @@ func (b *Binance) UPositionMarginChangeHistory(ctx context.Context, symbol curre params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesMarginChangeHistory, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesMarginChangeHistory, params, uFuturesDefaultRate, &resp) } // UPositionsInfoV2 gets positions' info for USDTMarginedFutures -func (b *Binance) UPositionsInfoV2(ctx context.Context, symbol currency.Pair) ([]UPositionInformationV2, error) { +func (e *Exchange) UPositionsInfoV2(ctx context.Context, symbol currency.Pair) ([]UPositionInformationV2, error) { var resp []UPositionInformationV2 params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesPositionInfo, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesPositionInfo, params, uFuturesDefaultRate, &resp) } // UGetCommissionRates returns the commission rates for USDTMarginedFutures -func (b *Binance) UGetCommissionRates(ctx context.Context, symbol currency.Pair) ([]UPositionInformationV2, error) { +func (e *Exchange) UGetCommissionRates(ctx context.Context, symbol currency.Pair) ([]UPositionInformationV2, error) { var resp []UPositionInformationV2 params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesCommissionRate, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesCommissionRate, params, uFuturesDefaultRate, &resp) } // UAccountTradesHistory gets account's trade history data for USDTMarginedFutures -func (b *Binance) UAccountTradesHistory(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UAccountTradeHistory, error) { +func (e *Exchange) UAccountTradesHistory(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UAccountTradeHistory, error) { var resp []UAccountTradeHistory params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -904,14 +904,14 @@ func (b *Binance) UAccountTradesHistory(ctx context.Context, symbol currency.Pai params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountTradeList, params, uFuturesAccountInformationRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountTradeList, params, uFuturesAccountInformationRate, &resp) } // UAccountIncomeHistory gets account's income history data for USDTMarginedFutures -func (b *Binance) UAccountIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, limit int64, startTime, endTime time.Time) ([]UAccountIncomeHistory, error) { +func (e *Exchange) UAccountIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, limit int64, startTime, endTime time.Time) ([]UAccountIncomeHistory, error) { var resp []UAccountIncomeHistory params := url.Values{} - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -932,45 +932,45 @@ func (b *Binance) UAccountIncomeHistory(ctx context.Context, symbol currency.Pai params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesIncomeHistory, params, uFuturesIncomeHistoryRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesIncomeHistory, params, uFuturesIncomeHistoryRate, &resp) } // UGetNotionalAndLeverageBrackets gets account's notional and leverage brackets for USDTMarginedFutures -func (b *Binance) UGetNotionalAndLeverageBrackets(ctx context.Context, symbol currency.Pair) ([]UNotionalLeverageAndBrakcetsData, error) { +func (e *Exchange) UGetNotionalAndLeverageBrackets(ctx context.Context, symbol currency.Pair) ([]UNotionalLeverageAndBrakcetsData, error) { var resp []UNotionalLeverageAndBrakcetsData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesNotionalBracket, params, uFuturesDefaultRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesNotionalBracket, params, uFuturesDefaultRate, &resp) } // UPositionsADLEstimate gets estimated ADL data for USDTMarginedFutures positions -func (b *Binance) UPositionsADLEstimate(ctx context.Context, symbol currency.Pair) (UPositionADLEstimationData, error) { +func (e *Exchange) UPositionsADLEstimate(ctx context.Context, symbol currency.Pair) (UPositionADLEstimationData, error) { var resp UPositionADLEstimationData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesADLQuantile, params, uFuturesAccountInformationRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesADLQuantile, params, uFuturesAccountInformationRate, &resp) } // UAccountForcedOrders gets account's forced (liquidation) orders for USDTMarginedFutures -func (b *Binance) UAccountForcedOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, limit int64, startTime, endTime time.Time) ([]UForceOrdersData, error) { +func (e *Exchange) UAccountForcedOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, limit int64, startTime, endTime time.Time) ([]UForceOrdersData, error) { var resp []UForceOrdersData params := url.Values{} rateLimit := uFuturesAllForceOrdersRate if !symbol.IsEmpty() { rateLimit = uFuturesCurrencyForceOrdersRate - symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) + symbolValue, err := e.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { return resp, err } @@ -992,18 +992,18 @@ func (b *Binance) UAccountForcedOrders(ctx context.Context, symbol currency.Pair params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } - return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesUsersForceOrders, params, rateLimit, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesUsersForceOrders, params, rateLimit, &resp) } // GetPerpMarkets returns exchange information. Check binance_types for more information -func (b *Binance) GetPerpMarkets(ctx context.Context) (PerpsExchangeInfo, error) { +func (e *Exchange) GetPerpMarkets(ctx context.Context) (PerpsExchangeInfo, error) { var resp PerpsExchangeInfo - return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, perpExchangeInfo, uFuturesDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestUSDTMargined, perpExchangeInfo, uFuturesDefaultRate, &resp) } // FetchUSDTMarginExchangeLimits fetches USDT margined order execution limits -func (b *Binance) FetchUSDTMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { - usdtFutures, err := b.UExchangeInfo(ctx) +func (e *Exchange) FetchUSDTMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { + usdtFutures, err := e.UExchangeInfo(ctx) if err != nil { return nil, err } @@ -1045,17 +1045,17 @@ func (b *Binance) FetchUSDTMarginExchangeLimits(ctx context.Context) ([]order.Mi } // SetAssetsMode sets the current asset margin type, true for multi, false for single -func (b *Binance) SetAssetsMode(ctx context.Context, multiMargin bool) error { +func (e *Exchange) SetAssetsMode(ctx context.Context, multiMargin bool) error { params := url.Values{ "multiAssetsMargin": {strconv.FormatBool(multiMargin)}, } - return b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, uFuturesMultiAssetsMargin, params, uFuturesDefaultRate, nil) + return e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, uFuturesMultiAssetsMargin, params, uFuturesDefaultRate, nil) } // GetAssetsMode returns the current asset margin type, true for multi, false for single -func (b *Binance) GetAssetsMode(ctx context.Context) (bool, error) { +func (e *Exchange) GetAssetsMode(ctx context.Context) (bool, error) { var result struct { MultiAssetsMargin bool `json:"multiAssetsMargin"` } - return result.MultiAssetsMargin, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, uFuturesMultiAssetsMargin, nil, uFuturesDefaultRate, &result) + return result.MultiAssetsMargin, e.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, uFuturesMultiAssetsMargin, nil, uFuturesDefaultRate, &result) } diff --git a/exchanges/binance/binance_websocket.go b/exchanges/binance/binance_websocket.go index 84f8dd96634..56c72f30681 100644 --- a/exchanges/binance/binance_websocket.go +++ b/exchanges/binance/binance_websocket.go @@ -50,68 +50,68 @@ var ( ) // WsConnect initiates a websocket connection -func (b *Binance) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !b.Websocket.IsEnabled() || !b.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - dialer.HandshakeTimeout = b.Config.HTTPTimeout + dialer.HandshakeTimeout = e.Config.HTTPTimeout dialer.Proxy = http.ProxyFromEnvironment var err error - if b.Websocket.CanUseAuthenticatedEndpoints() { - listenKey, err = b.GetWsAuthStreamKey(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + listenKey, err = e.GetWsAuthStreamKey(ctx) if err != nil { - b.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) log.Errorf(log.ExchangeSys, "%v unable to connect to authenticated Websocket. Error: %s", - b.Name, + e.Name, err) } else { // cleans on failed connection - clean := strings.Split(b.Websocket.GetWebsocketURL(), "?streams=") + clean := strings.Split(e.Websocket.GetWebsocketURL(), "?streams=") authPayload := clean[0] + "?streams=" + listenKey - err = b.Websocket.SetWebsocketURL(authPayload, false, false) + err = e.Websocket.SetWebsocketURL(authPayload, false, false) if err != nil { return err } } } - err = b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err = e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", - b.Name, + e.Name, err) } - if b.Websocket.CanUseAuthenticatedEndpoints() { - go b.KeepAuthKeyAlive(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + go e.KeepAuthKeyAlive(ctx) } - b.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ UseGorillaHandler: true, MessageType: gws.PongMessage, Delay: pingDelay, }) - b.Websocket.Wg.Add(1) - go b.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() - b.setupOrderbookManager(ctx) + e.setupOrderbookManager(ctx) return nil } -func (b *Binance) setupOrderbookManager(ctx context.Context) { - if b.obm == nil { - b.obm = &orderbookManager{ +func (e *Exchange) setupOrderbookManager(ctx context.Context) { + if e.obm == nil { + e.obm = &orderbookManager{ state: make(map[currency.Code]map[currency.Code]map[asset.Item]*update), jobs: make(chan job, maxWSOrderbookJobs), } } else { // Change state on reconnect for initial sync. - for _, m1 := range b.obm.state { + for _, m1 := range e.obm.state { for _, m2 := range m1 { for _, update := range m2 { update.initialSync = true @@ -124,50 +124,50 @@ func (b *Binance) setupOrderbookManager(ctx context.Context) { for range maxWSOrderbookWorkers { // 10 workers for synchronising book - b.SynchroniseWebsocketOrderbook(ctx) + e.SynchroniseWebsocketOrderbook(ctx) } } // KeepAuthKeyAlive will continuously send messages to // keep the WS auth key active -func (b *Binance) KeepAuthKeyAlive(ctx context.Context) { - b.Websocket.Wg.Add(1) - defer b.Websocket.Wg.Done() +func (e *Exchange) KeepAuthKeyAlive(ctx context.Context) { + e.Websocket.Wg.Add(1) + defer e.Websocket.Wg.Done() ticks := time.NewTicker(time.Minute * 30) for { select { - case <-b.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: ticks.Stop() return case <-ticks.C: - err := b.MaintainWsAuthStreamKey(ctx) + err := e.MaintainWsAuthStreamKey(ctx) if err != nil { - b.Websocket.DataHandler <- err - log.Warnf(log.ExchangeSys, "%s - Unable to renew auth websocket token, may experience shutdown", b.Name) + e.Websocket.DataHandler <- err + log.Warnf(log.ExchangeSys, "%s - Unable to renew auth websocket token, may experience shutdown", e.Name) } } } } // wsReadData receives and passes on websocket messages for processing -func (b *Binance) wsReadData() { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := b.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (b *Binance) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { if id, err := jsonparser.GetInt(respRaw, "id"); err == nil { - if b.Websocket.Match.IncomingWithData(id, respRaw) { + if e.Websocket.Match.IncomingWithData(id, respRaw) { return nil } } @@ -179,7 +179,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { } jsonData, _, _, err := jsonparser.Get(respRaw, "data") if err != nil { - return fmt.Errorf("%s %s %s", b.Name, websocket.UnhandledMessage, string(respRaw)) + return fmt.Errorf("%s %s %s", e.Name, websocket.UnhandledMessage, string(respRaw)) } var event string event, err = jsonparser.GetUnsafeString(jsonData, "e") @@ -190,27 +190,27 @@ func (b *Binance) wsHandleData(respRaw []byte) error { err = json.Unmarshal(jsonData, &data) if err != nil { return fmt.Errorf("%v - Could not convert to outboundAccountPosition structure %s", - b.Name, + e.Name, err) } - b.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil case "balanceUpdate": var data WsBalanceUpdateData err = json.Unmarshal(jsonData, &data) if err != nil { return fmt.Errorf("%v - Could not convert to balanceUpdate structure %s", - b.Name, + e.Name, err) } - b.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil case "executionReport": var data WsOrderUpdateData err = json.Unmarshal(jsonData, &data) if err != nil { return fmt.Errorf("%v - Could not convert to executionReport structure %s", - b.Name, + e.Name, err) } avgPrice := 0.0 @@ -220,7 +220,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { remainingAmount := data.Quantity - data.CumulativeFilledQuantity var pair currency.Pair var assetType asset.Item - pair, assetType, err = b.GetRequestFormattedPairAndAssetType(data.Symbol) + pair, assetType, err = e.GetRequestFormattedPairAndAssetType(data.Symbol) if err != nil { return err } @@ -232,8 +232,8 @@ func (b *Binance) wsHandleData(respRaw []byte) error { var orderStatus order.Status orderStatus, err = stringToOrderStatus(data.OrderStatus) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -245,8 +245,8 @@ func (b *Binance) wsHandleData(respRaw []byte) error { var orderType order.Type orderType, err = order.StringToOrderType(data.OrderType) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -254,13 +254,13 @@ func (b *Binance) wsHandleData(respRaw []byte) error { var orderSide order.Side orderSide, err = order.StringToOrderSide(data.Side) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } - b.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: data.Price, Amount: data.Quantity, AverageExecutedPrice: avgPrice, @@ -270,7 +270,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { CostAsset: pair.Quote, Fee: data.Commission, FeeAsset: feeAsset, - Exchange: b.Name, + Exchange: e.Name, OrderID: orderID, ClientOrderID: clientOrderID, Type: orderType, @@ -287,10 +287,10 @@ func (b *Binance) wsHandleData(respRaw []byte) error { err = json.Unmarshal(jsonData, &data) if err != nil { return fmt.Errorf("%v - Could not convert to listStatus structure %s", - b.Name, + e.Name, err) } - b.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil } } @@ -298,13 +298,13 @@ func (b *Binance) wsHandleData(respRaw []byte) error { streamStr, err := jsonparser.GetUnsafeString(respRaw, "stream") if err != nil { if errors.Is(err, jsonparser.KeyPathNotFoundError) { - return fmt.Errorf("%s %s %s", b.Name, websocket.UnhandledMessage, string(respRaw)) + return fmt.Errorf("%s %s %s", e.Name, websocket.UnhandledMessage, string(respRaw)) } return err } streamType := strings.Split(streamStr, "@") if len(streamType) <= 1 { - return fmt.Errorf("%s %s %s", b.Name, websocket.UnhandledMessage, string(respRaw)) + return fmt.Errorf("%s %s %s", e.Name, websocket.UnhandledMessage, string(respRaw)) } var ( pair currency.Pair @@ -316,7 +316,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { // there should be a symbol returned for all data types below return err } - pair, isEnabled, err = b.MatchSymbolCheckEnabled(symbol, asset.Spot, false) + pair, isEnabled, err = e.MatchSymbolCheckEnabled(symbol, asset.Spot, false) if err != nil { return err } @@ -325,9 +325,9 @@ func (b *Binance) wsHandleData(respRaw []byte) error { } switch streamType[1] { case "trade": - saveTradeData := b.IsSaveTradeDataEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() if !saveTradeData && - !b.IsTradeFeedEnabled() { + !e.IsTradeFeedEnabled() { return nil } @@ -335,7 +335,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { err := json.Unmarshal(jsonData, &t) if err != nil { return fmt.Errorf("%v - Could not unmarshal trade data: %s", - b.Name, + e.Name, err) } td := trade.Data{ @@ -343,7 +343,7 @@ func (b *Binance) wsHandleData(respRaw []byte) error { Timestamp: t.TimeStamp.Time(), Price: t.Price.Float64(), Amount: t.Quantity.Float64(), - Exchange: b.Name, + Exchange: e.Name, AssetType: asset.Spot, TID: strconv.FormatInt(t.TradeID, 10), } @@ -353,17 +353,17 @@ func (b *Binance) wsHandleData(respRaw []byte) error { } else { // Buyer is Taker td.Side = order.Buy } - return b.Websocket.Trade.Update(saveTradeData, td) + return e.Websocket.Trade.Update(saveTradeData, td) case "ticker": var t TickerStream err = json.Unmarshal(jsonData, &t) if err != nil { return fmt.Errorf("%v - Could not convert to a TickerStream structure %s", - b.Name, + e.Name, err.Error()) } - b.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: b.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Open: t.OpenPrice.Float64(), Close: t.ClosePrice.Float64(), Volume: t.TotalTradedVolume.Float64(), @@ -384,14 +384,14 @@ func (b *Binance) wsHandleData(respRaw []byte) error { err = json.Unmarshal(jsonData, &kline) if err != nil { return fmt.Errorf("%v - Could not convert to a KlineStream structure %s", - b.Name, + e.Name, err) } - b.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: kline.EventTime.Time(), Pair: pair, AssetType: asset.Spot, - Exchange: b.Name, + Exchange: e.Name, StartTime: kline.Kline.StartTime.Time(), CloseTime: kline.Kline.CloseTime.Time(), Interval: kline.Kline.Interval, @@ -407,22 +407,22 @@ func (b *Binance) wsHandleData(respRaw []byte) error { err = json.Unmarshal(jsonData, &depth) if err != nil { return fmt.Errorf("%v - Could not convert to depthStream structure %s", - b.Name, + e.Name, err) } var init bool - init, err = b.UpdateLocalBuffer(&depth) + init, err = e.UpdateLocalBuffer(&depth) if err != nil { if init { return nil } return fmt.Errorf("%v - UpdateLocalCache error: %s", - b.Name, + e.Name, err) } return nil default: - return fmt.Errorf("%s %s %s", b.Name, websocket.UnhandledMessage, string(respRaw)) + return fmt.Errorf("%s %s %s", e.Name, websocket.UnhandledMessage, string(respRaw)) } } @@ -448,8 +448,8 @@ func stringToOrderStatus(status string) (order.Status, error) { } // SeedLocalCache seeds depth data -func (b *Binance) SeedLocalCache(ctx context.Context, p currency.Pair) error { - ob, err := b.GetOrderBook(ctx, +func (e *Exchange) SeedLocalCache(ctx context.Context, p currency.Pair) error { + ob, err := e.GetOrderBook(ctx, OrderBookDataRequestParams{ Symbol: p, Limit: 1000, @@ -457,17 +457,17 @@ func (b *Binance) SeedLocalCache(ctx context.Context, p currency.Pair) error { if err != nil { return err } - return b.SeedLocalCacheWithBook(p, ob) + return e.SeedLocalCacheWithBook(p, ob) } // SeedLocalCacheWithBook seeds the local orderbook cache -func (b *Binance) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { +func (e *Exchange) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { newOrderBook := orderbook.Book{ Pair: p, Asset: asset.Spot, - Exchange: b.Name, + Exchange: e.Name, LastUpdateID: orderbookNew.LastUpdateID, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(orderbookNew.Bids)), Asks: make(orderbook.Levels, len(orderbookNew.Asks)), LastUpdated: time.Now(), // Time not provided in REST book. @@ -484,46 +484,46 @@ func (b *Binance) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBoo Price: orderbookNew.Asks[i].Price, } } - return b.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } // UpdateLocalBuffer updates and returns the most recent iteration of the orderbook -func (b *Binance) UpdateLocalBuffer(wsdp *WebsocketDepthStream) (bool, error) { - pair, err := b.MatchSymbolWithAvailablePairs(wsdp.Pair, asset.Spot, false) +func (e *Exchange) UpdateLocalBuffer(wsdp *WebsocketDepthStream) (bool, error) { + pair, err := e.MatchSymbolWithAvailablePairs(wsdp.Pair, asset.Spot, false) if err != nil { return false, err } - err = b.obm.stageWsUpdate(wsdp, pair, asset.Spot) + err = e.obm.stageWsUpdate(wsdp, pair, asset.Spot) if err != nil { - init, err2 := b.obm.checkIsInitialSync(pair) + init, err2 := e.obm.checkIsInitialSync(pair) if err2 != nil { return false, err2 } return init, err } - err = b.applyBufferUpdate(pair) + err = e.applyBufferUpdate(pair) if err != nil { - b.invalidateAndCleanupOrderbook(pair) + e.invalidateAndCleanupOrderbook(pair) } return false, err } -func (b *Binance) generateSubscriptions() (subscription.List, error) { - for _, s := range b.Features.Subscriptions { +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + for _, s := range e.Features.Subscriptions { if s.Asset == asset.Empty { // Handle backwards compatibility with config without assets, all binance subs are spot s.Asset = asset.Spot } } - return b.Features.Subscriptions.ExpandTemplates(b) + return e.Features.Subscriptions.ExpandTemplates(e) } var subTemplate *template.Template // GetSubscriptionTemplate returns a subscription channel template -func (b *Binance) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { var err error if subTemplate == nil { subTemplate, err = template.New("subscriptions.tmpl"). @@ -558,21 +558,21 @@ func formatChannelInterval(s *subscription.Subscription) string { } // Subscribe subscribes to a set of channels -func (b *Binance) Subscribe(channels subscription.List) error { +func (e *Exchange) Subscribe(channels subscription.List) error { ctx := context.TODO() - return b.ParallelChanOp(ctx, channels, func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsSubscribeMethod, l) }, 50) + return e.ParallelChanOp(ctx, channels, func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsSubscribeMethod, l) }, 50) } // Unsubscribe unsubscribes from a set of channels -func (b *Binance) Unsubscribe(channels subscription.List) error { +func (e *Exchange) Unsubscribe(channels subscription.List) error { ctx := context.TODO() - return b.ParallelChanOp(ctx, channels, func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsUnsubscribeMethod, l) }, 50) + return e.ParallelChanOp(ctx, channels, func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsUnsubscribeMethod, l) }, 50) } // manageSubs subscribes or unsubscribes from a list of subscriptions -func (b *Binance) manageSubs(ctx context.Context, op string, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.List) error { if op == wsSubscribeMethod { - if err := b.Websocket.AddSubscriptions(b.Websocket.Conn, subs...); err != nil { // Note: AddSubscription will set state to subscribing + if err := e.Websocket.AddSubscriptions(e.Websocket.Conn, subs...); err != nil { // Note: AddSubscription will set state to subscribing return err } } else { @@ -582,12 +582,12 @@ func (b *Binance) manageSubs(ctx context.Context, op string, subs subscription.L } req := WsPayload{ - ID: b.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), Method: op, Params: subs.QualifiedChannels(), } - respRaw, err := b.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + respRaw, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err == nil { if v, d, _, rErr := jsonparser.Get(respRaw, "result"); rErr != nil { err = rErr @@ -598,10 +598,10 @@ func (b *Binance) manageSubs(ctx context.Context, op string, subs subscription.L if err != nil { err = fmt.Errorf("%w; Channels: %s", err, strings.Join(subs.QualifiedChannels(), ", ")) - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err if op == wsSubscribeMethod { - if err2 := b.Websocket.RemoveSubscriptions(b.Websocket.Conn, subs...); err2 != nil { + if err2 := e.Websocket.RemoveSubscriptions(e.Websocket.Conn, subs...); err2 != nil { err = common.AppendError(err, err2) } } @@ -609,7 +609,7 @@ func (b *Binance) manageSubs(ctx context.Context, op string, subs subscription.L if op == wsSubscribeMethod { err = common.AppendError(err, subs.SetStates(subscription.SubscribedState)) } else { - err = b.Websocket.RemoveSubscriptions(b.Websocket.Conn, subs...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, subs...) } } @@ -617,7 +617,7 @@ func (b *Binance) manageSubs(ctx context.Context, op string, subs subscription.L } // ProcessOrderbookUpdate processes the websocket orderbook update -func (b *Binance) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WebsocketDepthStream) error { +func (e *Exchange) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WebsocketDepthStream) error { updateBid := make([]orderbook.Level, len(ws.UpdateBids)) for i := range ws.UpdateBids { updateBid[i] = orderbook.Level{ @@ -632,7 +632,7 @@ func (b *Binance) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, ws *Web Amount: ws.UpdateAsks[i][1].Float64(), } } - return b.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Bids: updateBid, Asks: updateAsk, Pair: cp, @@ -644,8 +644,8 @@ func (b *Binance) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, ws *Web // applyBufferUpdate applies the buffer to the orderbook or initiates a new // orderbook sync by the REST protocol which is off handed to go routine. -func (b *Binance) applyBufferUpdate(pair currency.Pair) error { - fetching, needsFetching, err := b.obm.handleFetchingBook(pair) +func (e *Exchange) applyBufferUpdate(pair currency.Pair) error { + fetching, needsFetching, err := e.obm.handleFetchingBook(pair) if err != nil { return err } @@ -653,30 +653,30 @@ func (b *Binance) applyBufferUpdate(pair currency.Pair) error { return nil } if needsFetching { - if b.Verbose { - log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", b.Name) + if e.Verbose { + log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", e.Name) } - return b.obm.fetchBookViaREST(pair) + return e.obm.fetchBookViaREST(pair) } - recent, err := b.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) + recent, err := e.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) if err != nil { log.Errorf( log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", - b.Name, + e.Name, err) } if recent != nil { - err = b.obm.checkAndProcessOrderbookUpdate(b.ProcessOrderbookUpdate, pair, recent) + err = e.obm.checkAndProcessOrderbookUpdate(e.ProcessOrderbookUpdate, pair, recent) if err != nil { log.Errorf( log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", - b.Name, + e.Name, err) - err = b.obm.setNeedsFetchingBook(pair) + err = e.obm.setNeedsFetchingBook(pair) if err != nil { return err } @@ -702,26 +702,26 @@ func (o *orderbookManager) setNeedsFetchingBook(pair currency.Pair) error { // SynchroniseWebsocketOrderbook synchronises full orderbook for currency pair // asset -func (b *Binance) SynchroniseWebsocketOrderbook(ctx context.Context) { - b.Websocket.Wg.Add(1) +func (e *Exchange) SynchroniseWebsocketOrderbook(ctx context.Context) { + e.Websocket.Wg.Add(1) go func() { - defer b.Websocket.Wg.Done() + defer e.Websocket.Wg.Done() for { select { - case <-b.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: for { select { - case <-b.obm.jobs: + case <-e.obm.jobs: default: return } } - case j := <-b.obm.jobs: - err := b.processJob(ctx, j.Pair) + case j := <-e.obm.jobs: + err := e.processJob(ctx, j.Pair) if err != nil { log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", - b.Name, err) + e.Name, err) } } } @@ -729,35 +729,35 @@ func (b *Binance) SynchroniseWebsocketOrderbook(ctx context.Context) { } // processJob fetches and processes orderbook updates -func (b *Binance) processJob(ctx context.Context, p currency.Pair) error { - err := b.SeedLocalCache(ctx, p) +func (e *Exchange) processJob(ctx context.Context, p currency.Pair) error { + err := e.SeedLocalCache(ctx, p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) } - err = b.obm.stopFetchingBook(p) + err = e.obm.stopFetchingBook(p) if err != nil { return err } // Immediately apply the buffer updates so we don't wait for a // new update to initiate this. - err = b.applyBufferUpdate(p) + err = e.applyBufferUpdate(p) if err != nil { - b.invalidateAndCleanupOrderbook(p) + e.invalidateAndCleanupOrderbook(p) return err } return nil } // invalidateAndCleanupOrderbook invalidaates orderbook and cleans local cache -func (b *Binance) invalidateAndCleanupOrderbook(p currency.Pair) { - if err := b.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { - log.Errorf(log.WebsocketMgr, "%s error invalidating websocket orderbook: %v", b.Name, err) +func (e *Exchange) invalidateAndCleanupOrderbook(p currency.Pair) { + if err := e.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { + log.Errorf(log.WebsocketMgr, "%s error invalidating websocket orderbook: %v", e.Name, err) } - if err := b.obm.cleanup(p); err != nil { - log.Errorf(log.WebsocketMgr, "%s error during websocket orderbook cleanup: %v", b.Name, err) + if err := e.obm.cleanup(p); err != nil { + log.Errorf(log.WebsocketMgr, "%s error during websocket orderbook cleanup: %v", e.Name, err) } } diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 499e777462a..d789e51d0bd 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -60,26 +60,26 @@ var defaultAssetPairStores = map[asset.Item]currency.PairStore{ } // SetDefaults sets the basic defaults for Binance -func (b *Binance) SetDefaults() { - b.Name = "Binance" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Binance" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for a, ps := range defaultAssetPairStores { - if err := b.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", b.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } for _, a := range []asset.Item{asset.Margin, asset.CoinMarginedFutures, asset.USDTMarginedFutures} { - if err := b.DisableAssetWebsocketSupport(a); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", b.Name, a, err) + if err := e.DisableAssetWebsocketSupport(a); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, a, err) } } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -177,14 +177,14 @@ func (b *Binance) SetDefaults() { } var err error - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimits())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: spotAPIURL, exchange.RestSpotSupplementary: apiURL, exchange.RestUSDTMargined: ufuturesAPIURL, @@ -196,47 +196,47 @@ func (b *Binance) SetDefaults() { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout } // Setup takes in the supplied exchange configuration details and sets params -func (b *Binance) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { if err := exch.Validate(); err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - if err := b.SetupDefaults(exch); err != nil { + if err := e.SetupDefaults(exch); err != nil { return err } - ePoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + ePoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: binanceDefaultWebsocketURL, RunningURL: ePoint, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, }, - TradeFeed: b.Features.Enabled.TradeFeed, + TradeFeed: e.Features.Enabled.TradeFeed, }) if err != nil { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, RateLimit: request.NewWeightedRateLimitByDuration(250 * time.Millisecond), @@ -244,15 +244,15 @@ func (b *Binance) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Binance) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !b.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } tradingStatus := "TRADING" var pairs []currency.Pair switch a { case asset.Spot, asset.Margin: - info, err := b.GetExchangeInfo(ctx) + info, err := e.GetExchangeInfo(ctx) if err != nil { return nil, err } @@ -274,7 +274,7 @@ func (b *Binance) FetchTradablePairs(ctx context.Context, a asset.Item) (currenc } } case asset.CoinMarginedFutures: - cInfo, err := b.FuturesExchangeInfo(ctx) + cInfo, err := e.FuturesExchangeInfo(ctx) if err != nil { return nil, err } @@ -290,7 +290,7 @@ func (b *Binance) FetchTradablePairs(ctx context.Context, a asset.Item) (currenc pairs = append(pairs, pair) } case asset.USDTMarginedFutures: - uInfo, err := b.UExchangeInfo(ctx) + uInfo, err := e.UExchangeInfo(ctx) if err != nil { return nil, err } @@ -317,39 +317,39 @@ func (b *Binance) FetchTradablePairs(ctx context.Context, a asset.Item) (currenc // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Binance) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assetTypes := b.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assetTypes := e.GetAssetTypes(false) for i := range assetTypes { - pairs, err := b.FetchTradablePairs(ctx, assetTypes[i]) + pairs, err := e.FetchTradablePairs(ctx, assetTypes[i]) if err != nil { return err } - err = b.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) + err = e.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) if err != nil { return err } } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { switch a { case asset.Spot, asset.Margin: - tick, err := b.GetTickers(ctx) + tick, err := e.GetTickers(ctx) if err != nil { return err } - pairs, err := b.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { return err } for i := range pairs { for y := range tick { - pairFmt, err := b.FormatExchangeCurrency(pairs[i], a) + pairFmt, err := e.FormatExchangeCurrency(pairs[i], a) if err != nil { return err } @@ -369,7 +369,7 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { Open: tick[y].OpenPrice.Float64(), Close: tick[y].PrevClosePrice.Float64(), Pair: pairFmt, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -378,7 +378,7 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { } } case asset.USDTMarginedFutures: - tick, err := b.U24HTickerPriceChangeStats(ctx, currency.EMPTYPAIR) + tick, err := e.U24HTickerPriceChangeStats(ctx, currency.EMPTYPAIR) if err != nil { return err } @@ -397,7 +397,7 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { Open: tick[y].OpenPrice, Close: tick[y].PrevClosePrice, Pair: cp, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -405,7 +405,7 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { } } case asset.CoinMarginedFutures: - tick, err := b.GetFuturesSwapTickerChangeStats(ctx, currency.EMPTYPAIR, "") + tick, err := e.GetFuturesSwapTickerChangeStats(ctx, currency.EMPTYPAIR, "") if err != nil { return err } @@ -424,7 +424,7 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { Open: tick[y].OpenPrice.Float64(), Close: tick[y].PrevClosePrice.Float64(), Pair: cp, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -438,13 +438,13 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } switch a { case asset.Spot, asset.Margin: - tick, err := b.GetPriceChangeStats(ctx, p) + tick, err := e.GetPriceChangeStats(ctx, p) if err != nil { return nil, err } @@ -459,14 +459,14 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite Open: tick.OpenPrice.Float64(), Close: tick.PrevClosePrice.Float64(), Pair: p, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } case asset.USDTMarginedFutures: - tick, err := b.U24HTickerPriceChangeStats(ctx, p) + tick, err := e.U24HTickerPriceChangeStats(ctx, p) if err != nil { return nil, err } @@ -479,14 +479,14 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite Open: tick[0].OpenPrice, Close: tick[0].PrevClosePrice, Pair: p, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } case asset.CoinMarginedFutures: - tick, err := b.GetFuturesSwapTickerChangeStats(ctx, p, "") + tick, err := e.GetFuturesSwapTickerChangeStats(ctx, p, "") if err != nil { return nil, err } @@ -499,7 +499,7 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite Open: tick[0].OpenPrice.Float64(), Close: tick[0].PrevClosePrice.Float64(), Pair: p, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -509,37 +509,37 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - return ticker.GetTicker(b.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } var orderbookNew *OrderBook var err error switch assetType { case asset.Spot, asset.Margin: - orderbookNew, err = b.GetOrderBook(ctx, + orderbookNew, err = e.GetOrderBook(ctx, OrderBookDataRequestParams{ Symbol: p, Limit: 1000, }) case asset.USDTMarginedFutures: - orderbookNew, err = b.UFuturesOrderbook(ctx, p, 1000) + orderbookNew, err = e.UFuturesOrderbook(ctx, p, 1000) case asset.CoinMarginedFutures: - orderbookNew, err = b.GetFuturesOrderbook(ctx, p, 1000) + orderbookNew, err = e.GetFuturesOrderbook(ctx, p, 1000) default: return nil, fmt.Errorf("[%s] %w", assetType, asset.ErrNotSupported) } @@ -566,19 +566,19 @@ func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp if err != nil { return book, err } - return orderbook.Get(b.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Binance exchange -func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount acc.AssetType = assetType - info.Exchange = b.Name + info.Exchange = e.Name switch assetType { case asset.Spot: - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return info, err } @@ -586,7 +586,7 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( // TODO: implement sub-account endpoints return info, common.ErrNotYetImplemented } - raw, err := b.GetAccount(ctx) + raw, err := e.GetAccount(ctx) if err != nil { return info, err } @@ -607,7 +607,7 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( acc.Currencies = currencyBalance case asset.CoinMarginedFutures: - accData, err := b.GetFuturesAccountInfo(ctx) + accData, err := e.GetFuturesAccountInfo(ctx) if err != nil { return info, err } @@ -624,7 +624,7 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( acc.Currencies = currencyDetails case asset.USDTMarginedFutures: - accData, err := b.UAccountBalanceV2(ctx) + accData, err := e.UAccountBalanceV2(ctx) if err != nil { return info, err } @@ -645,7 +645,7 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( return account.Holdings{}, err } case asset.Margin: - accData, err := b.GetMarginAccount(ctx) + accData, err := e.GetMarginAccount(ctx) if err != nil { return info, err } @@ -668,7 +668,7 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( } acc.AssetType = assetType info.Accounts = append(info.Accounts, acc) - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -680,13 +680,13 @@ func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Binance) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Binance) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - withdrawals, err := b.WithdrawHistory(ctx, c, "", time.Time{}, time.Time{}, 0, 10000) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + withdrawals, err := e.WithdrawHistory(ctx, c, "", time.Time{}, time.Time{}, 0, 10000) if err != nil { return nil, err } @@ -710,9 +710,9 @@ func (b *Binance) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { const limit = 1000 - rFmt, err := b.GetPairFormat(a, true) + rFmt, err := e.GetPairFormat(a, true) if err != nil { return nil, err } @@ -720,7 +720,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. resp := make([]trade.Data, 0, limit) switch a { case asset.Spot: - tradeData, err := b.GetMostRecentTrades(ctx, + tradeData, err := e.GetMostRecentTrades(ctx, RecentTradeRequestParams{pFmt, limit}) if err != nil { return nil, err @@ -729,7 +729,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. for i := range tradeData { td := trade.Data{ TID: strconv.FormatInt(tradeData[i].ID, 10), - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: tradeData[i].Price, @@ -744,7 +744,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. resp = append(resp, td) } case asset.USDTMarginedFutures: - tradeData, err := b.URecentTrades(ctx, pFmt, "", limit) + tradeData, err := e.URecentTrades(ctx, pFmt, "", limit) if err != nil { return nil, err } @@ -752,7 +752,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. for i := range tradeData { td := trade.Data{ TID: strconv.FormatInt(tradeData[i].ID, 10), - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: tradeData[i].Price, @@ -767,7 +767,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. resp = append(resp, td) } case asset.CoinMarginedFutures: - tradeData, err := b.GetFuturesPublicTrades(ctx, pFmt, limit) + tradeData, err := e.GetFuturesPublicTrades(ctx, pFmt, limit) if err != nil { return nil, err } @@ -775,7 +775,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. for i := range tradeData { td := trade.Data{ TID: strconv.FormatInt(tradeData[i].ID, 10), - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: tradeData[i].Price, @@ -791,7 +791,7 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. } } - if b.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err := trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -803,14 +803,14 @@ func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, a asset. } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Binance) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, from, to time.Time) ([]trade.Data, error) { - if err := b.CurrencyPairs.IsAssetEnabled(a); err != nil { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, from, to time.Time) ([]trade.Data, error) { + if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil { return nil, err } if a != asset.Spot { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - rFmt, err := b.GetPairFormat(a, true) + rFmt, err := e.GetPairFormat(a, true) if err != nil { return nil, err } @@ -820,7 +820,7 @@ func (b *Binance) GetHistoricTrades(ctx context.Context, p currency.Pair, a asse StartTime: from, EndTime: to, } - trades, err := b.GetAggregatedTrades(ctx, &req) + trades, err := e.GetAggregatedTrades(ctx, &req) if err != nil { return nil, fmt.Errorf("%w %v", err, pFmt) } @@ -830,7 +830,7 @@ func (b *Binance) GetHistoricTrades(ctx context.Context, p currency.Pair, a asse CurrencyPair: p, TID: strconv.FormatInt(trades[i].ATradeID, 10), Amount: trades[i].Quantity, - Exchange: b.Name, + Exchange: e.Name, Price: trades[i].Price, Timestamp: trades[i].TimeStamp.Time(), AssetType: a, @@ -846,8 +846,8 @@ func (b *Binance) GetHistoricTrades(ctx context.Context, p currency.Pair, a asse } // SubmitOrder submits a new order -func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } var orderID string @@ -888,7 +888,7 @@ func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm TimeInForce: timeInForce, NewClientOrderID: s.ClientOrderID, } - response, err := b.NewOrder(ctx, &orderRequest) + response, err := e.NewOrder(ctx, &orderRequest) if err != nil { return nil, err } @@ -939,7 +939,7 @@ func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm return nil, errors.New("invalid type, check api docs for updates") } - o, err := b.FuturesNewOrder( + o, err := e.FuturesNewOrder( ctx, &FuturesNewOrderRequest{ Symbol: s.Pair, @@ -985,7 +985,7 @@ func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm default: return nil, errors.New("invalid type, check api docs for updates") } - o, err := b.UFuturesNewOrder(ctx, + o, err := e.UFuturesNewOrder(ctx, &UFuturesNewOrderRequest{ Symbol: s.Pair, Side: reqSide, @@ -1016,12 +1016,12 @@ func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Binance) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Binance) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -1031,7 +1031,7 @@ func (b *Binance) CancelOrder(ctx context.Context, o *order.Cancel) error { if err != nil { return err } - _, err = b.CancelExistingOrder(ctx, + _, err = e.CancelExistingOrder(ctx, o.Pair, orderIDInt, o.AccountID) @@ -1039,12 +1039,12 @@ func (b *Binance) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } case asset.CoinMarginedFutures: - _, err := b.FuturesCancelOrder(ctx, o.Pair, o.OrderID, "") + _, err := e.FuturesCancelOrder(ctx, o.Pair, o.OrderID, "") if err != nil { return err } case asset.USDTMarginedFutures: - _, err := b.UCancelOrder(ctx, o.Pair, o.OrderID, "") + _, err := e.UCancelOrder(ctx, o.Pair, o.OrderID, "") if err != nil { return err } @@ -1053,12 +1053,12 @@ func (b *Binance) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Binance) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Binance) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { if err := req.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -1066,12 +1066,12 @@ func (b *Binance) CancelAllOrders(ctx context.Context, req *order.Cancel) (order cancelAllOrdersResponse.Status = make(map[string]string) switch req.AssetType { case asset.Spot, asset.Margin: - openOrders, err := b.OpenOrders(ctx, req.Pair) + openOrders, err := e.OpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } for i := range openOrders { - _, err = b.CancelExistingOrder(ctx, + _, err = e.CancelExistingOrder(ctx, req.Pair, openOrders[i].OrderID, "") @@ -1081,36 +1081,36 @@ func (b *Binance) CancelAllOrders(ctx context.Context, req *order.Cancel) (order } case asset.CoinMarginedFutures: if req.Pair.IsEmpty() { - enabledPairs, err := b.GetEnabledPairs(asset.CoinMarginedFutures) + enabledPairs, err := e.GetEnabledPairs(asset.CoinMarginedFutures) if err != nil { return cancelAllOrdersResponse, err } for i := range enabledPairs { - _, err = b.FuturesCancelAllOpenOrders(ctx, enabledPairs[i]) + _, err = e.FuturesCancelAllOpenOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } } } else { - _, err := b.FuturesCancelAllOpenOrders(ctx, req.Pair) + _, err := e.FuturesCancelAllOpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } } case asset.USDTMarginedFutures: if req.Pair.IsEmpty() { - enabledPairs, err := b.GetEnabledPairs(asset.USDTMarginedFutures) + enabledPairs, err := e.GetEnabledPairs(asset.USDTMarginedFutures) if err != nil { return cancelAllOrdersResponse, err } for i := range enabledPairs { - _, err = b.UCancelAllOpenOrders(ctx, enabledPairs[i]) + _, err = e.UCancelAllOpenOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } } } else { - _, err := b.UCancelAllOpenOrders(ctx, req.Pair) + _, err := e.UCancelAllOpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -1122,11 +1122,11 @@ func (b *Binance) CancelAllOrders(ctx context.Context, req *order.Cancel) (order } // GetOrderInfo returns information on a current open order -func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } @@ -1137,7 +1137,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc } switch assetType { case asset.Spot: - resp, err := b.QueryOrder(ctx, pair, "", orderIDInt) + resp, err := e.QueryOrder(ctx, pair, "", orderIDInt) if err != nil { return nil, err } @@ -1148,7 +1148,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc } status, err := order.StringToOrderStatus(resp.Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderType := order.Limit if resp.Type == "MARKET" { @@ -1157,7 +1157,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc return &order.Detail{ Amount: resp.OrigQty, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp.OrderID, 10), ClientOrderID: resp.ClientOrderID, Side: side, @@ -1172,7 +1172,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc LastUpdated: resp.UpdateTime.Time(), }, nil case asset.CoinMarginedFutures: - orderData, err := b.FuturesOpenOrderData(ctx, pair, orderID, "") + orderData, err := e.FuturesOpenOrderData(ctx, pair, orderID, "") if err != nil { return nil, err } @@ -1180,7 +1180,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc feeBuilder.Amount = orderData.ExecutedQuantity feeBuilder.PurchasePrice = orderData.AveragePrice feeBuilder.Pair = pair - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return nil, err } @@ -1188,7 +1188,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc respData.Amount = orderData.OriginalQuantity respData.AssetType = assetType respData.ClientOrderID = orderData.ClientOrderID - respData.Exchange = b.Name + respData.Exchange = e.Name respData.ExecutedAmount = orderData.ExecutedQuantity respData.Fee = fee respData.OrderID = orderID @@ -1201,7 +1201,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc respData.Date = orderData.Time.Time() respData.LastUpdated = orderData.UpdateTime.Time() case asset.USDTMarginedFutures: - orderData, err := b.UGetOrderData(ctx, pair, orderID, "") + orderData, err := e.UGetOrderData(ctx, pair, orderID, "") if err != nil { return nil, err } @@ -1209,7 +1209,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc feeBuilder.Amount = orderData.ExecutedQuantity feeBuilder.PurchasePrice = orderData.AveragePrice feeBuilder.Pair = pair - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return nil, err } @@ -1217,7 +1217,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc respData.Amount = orderData.OriginalQuantity respData.AssetType = assetType respData.ClientOrderID = orderData.ClientOrderID - respData.Exchange = b.Name + respData.Exchange = e.Name respData.ExecutedAmount = orderData.ExecutedQuantity respData.Fee = fee respData.OrderID = orderID @@ -1236,8 +1236,8 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc } // GetDepositAddress returns a deposit address for a specified currency -func (b *Binance) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { - addr, err := b.GetDepositAddressForCurrency(ctx, cryptocurrency.String(), chain) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { + addr, err := e.GetDepositAddressForCurrency(ctx, cryptocurrency.String(), chain) if err != nil { return nil, err } @@ -1250,12 +1250,12 @@ func (b *Binance) GetDepositAddress(ctx context.Context, cryptocurrency currency // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Binance) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } amountStr := strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64) - v, err := b.WithdrawCrypto(ctx, + v, err := e.WithdrawCrypto(ctx, withdrawRequest.Currency.String(), "", // withdrawal order ID withdrawRequest.Crypto.Chain, @@ -1274,30 +1274,30 @@ func (b *Binance) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Binance) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Binance) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Binance) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if (!b.AreCredentialsValid(ctx) || b.SkipAuthCheck) && // Todo check connection status + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1310,7 +1310,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ for i := range req.Pairs { switch req.AssetType { case asset.Spot, asset.Margin: - resp, err := b.OpenOrders(ctx, req.Pairs[i]) + resp, err := e.OpenOrders(ctx, req.Pairs[i]) if err != nil { return nil, err } @@ -1318,21 +1318,21 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ var side order.Side side, err = order.StringToOrderSide(resp[x].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var orderType order.Type orderType, err = order.StringToOrderType(resp[x].Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderStatus, err := order.StringToOrderStatus(resp[x].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders = append(orders, order.Detail{ Amount: resp[x].OrigQty, Date: resp[x].Time.Time(), - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp[x].OrderID, 10), ClientOrderID: resp[x].ClientOrderID, Side: side, @@ -1345,7 +1345,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ }) } case asset.CoinMarginedFutures: - openOrders, err := b.GetFuturesAllOpenOrders(ctx, req.Pairs[i], "") + openOrders, err := e.GetFuturesAllOpenOrders(ctx, req.Pairs[i], "") if err != nil { return nil, err } @@ -1354,7 +1354,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ feeBuilder.Amount = openOrders[y].ExecutedQty feeBuilder.PurchasePrice = openOrders[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1365,7 +1365,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ ExecutedAmount: openOrders[y].ExecutedQty, RemainingAmount: openOrders[y].OrigQty - openOrders[y].ExecutedQty, Fee: fee, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(openOrders[y].OrderID, 10), ClientOrderID: openOrders[y].ClientOrderID, Type: orderVars.OrderType, @@ -1378,7 +1378,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ }) } case asset.USDTMarginedFutures: - openOrders, err := b.UAllAccountOpenOrders(ctx, req.Pairs[i]) + openOrders, err := e.UAllAccountOpenOrders(ctx, req.Pairs[i]) if err != nil { return nil, err } @@ -1387,7 +1387,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ feeBuilder.Amount = openOrders[y].ExecutedQuantity feeBuilder.PurchasePrice = openOrders[y].AveragePrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1398,7 +1398,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ ExecutedAmount: openOrders[y].ExecutedQuantity, RemainingAmount: openOrders[y].OriginalQuantity - openOrders[y].ExecutedQuantity, Fee: fee, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(openOrders[y].OrderID, 10), ClientOrderID: openOrders[y].ClientOrderID, Type: orderVars.OrderType, @@ -1414,12 +1414,12 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ return orders, fmt.Errorf("%w %v", asset.ErrNotSupported, req.AssetType) } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1431,7 +1431,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ switch req.AssetType { case asset.Spot, asset.Margin: for x := range req.Pairs { - resp, err := b.AllOrders(ctx, + resp, err := e.AllOrders(ctx, req.Pairs[x], "", "1000") @@ -1443,16 +1443,16 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ var side order.Side side, err = order.StringToOrderSide(resp[i].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var orderType order.Type orderType, err = order.StringToOrderType(resp[i].Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderStatus, err := order.StringToOrderStatus(resp[i].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } // New orders are covered in GetOpenOrders if orderStatus == order.New { @@ -1473,7 +1473,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ CostAsset: req.Pairs[x].Quote, Date: resp[i].Time.Time(), LastUpdated: resp[i].UpdateTime.Time(), - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp[i].OrderID, 10), Side: side, Type: orderType, @@ -1497,7 +1497,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ if time.Since(req.StartTime) > time.Hour*24*30 { return nil, errors.New("can only fetch orders 30 days out") } - orderHistory, err = b.GetAllFuturesOrders(ctx, + orderHistory, err = e.GetAllFuturesOrders(ctx, req.Pairs[i], currency.EMPTYPAIR, req.StartTime, req.EndTime, 0, 0) if err != nil { return nil, err @@ -1507,7 +1507,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ if err != nil { return nil, err } - orderHistory, err = b.GetAllFuturesOrders(ctx, + orderHistory, err = e.GetAllFuturesOrders(ctx, req.Pairs[i], currency.EMPTYPAIR, time.Time{}, time.Time{}, fromID, 0) if err != nil { return nil, err @@ -1520,7 +1520,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ feeBuilder.Amount = orderHistory[y].ExecutedQty feeBuilder.PurchasePrice = orderHistory[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1531,7 +1531,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ ExecutedAmount: orderHistory[y].ExecutedQty, RemainingAmount: orderHistory[y].OrigQty - orderHistory[y].ExecutedQty, Fee: fee, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(orderHistory[y].OrderID, 10), ClientOrderID: orderHistory[y].ClientOrderID, Type: orderVars.OrderType, @@ -1555,7 +1555,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ if time.Since(req.StartTime) > time.Hour*24*7 { return nil, errors.New("can only fetch orders 7 days out") } - orderHistory, err = b.UAllAccountOrders(ctx, + orderHistory, err = e.UAllAccountOrders(ctx, req.Pairs[i], 0, 0, req.StartTime, req.EndTime) if err != nil { return nil, err @@ -1565,7 +1565,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ if err != nil { return nil, err } - orderHistory, err = b.UAllAccountOrders(ctx, + orderHistory, err = e.UAllAccountOrders(ctx, req.Pairs[i], fromID, 0, time.Time{}, time.Time{}) if err != nil { return nil, err @@ -1578,7 +1578,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ feeBuilder.Amount = orderHistory[y].ExecutedQty feeBuilder.PurchasePrice = orderHistory[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(ctx, &feeBuilder) + fee, err := e.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1589,7 +1589,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ ExecutedAmount: orderHistory[y].ExecutedQty, RemainingAmount: orderHistory[y].OrigQty - orderHistory[y].ExecutedQty, Fee: fee, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(orderHistory[y].OrderID, 10), ClientOrderID: orderHistory[y].ClientOrderID, Type: orderVars.OrderType, @@ -1604,18 +1604,18 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ default: return orders, fmt.Errorf("%w %v", asset.ErrNotSupported, req.AssetType) } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Binance) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (b *Binance) FormatExchangeKlineInterval(interval kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(interval kline.Interval) string { switch interval { case kline.OneDay: return "1d" @@ -1631,8 +1631,8 @@ func (b *Binance) FormatExchangeKlineInterval(interval kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } @@ -1641,8 +1641,8 @@ func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a switch a { case asset.Spot, asset.Margin: var candles []CandleStick - candles, err = b.GetSpotKline(ctx, &KlinesRequestParams{ - Interval: b.FormatExchangeKlineInterval(req.ExchangeInterval), + candles, err = e.GetSpotKline(ctx, &KlinesRequestParams{ + Interval: e.FormatExchangeKlineInterval(req.ExchangeInterval), Symbol: req.Pair, StartTime: req.Start, EndTime: req.End, @@ -1663,9 +1663,9 @@ func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } case asset.USDTMarginedFutures: var candles []FuturesCandleStick - candles, err = b.UKlineData(ctx, + candles, err = e.UKlineData(ctx, req.RequestFormatted, - b.FormatExchangeKlineInterval(interval), + e.FormatExchangeKlineInterval(interval), req.RequestLimit, req.Start, req.End) @@ -1684,9 +1684,9 @@ func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } case asset.CoinMarginedFutures: var candles []FuturesCandleStick - candles, err = b.GetFuturesKlineData(ctx, + candles, err = e.GetFuturesKlineData(ctx, req.RequestFormatted, - b.FormatExchangeKlineInterval(interval), + e.FormatExchangeKlineInterval(interval), req.RequestLimit, req.Start, req.End) @@ -1711,8 +1711,8 @@ func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a // GetHistoricCandlesExtended returns candles between a time period for a set // time interval -func (b *Binance) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1722,8 +1722,8 @@ func (b *Binance) GetHistoricCandlesExtended(ctx context.Context, pair currency. switch a { case asset.Spot, asset.Margin: var candles []CandleStick - candles, err = b.GetSpotKline(ctx, &KlinesRequestParams{ - Interval: b.FormatExchangeKlineInterval(req.ExchangeInterval), + candles, err = e.GetSpotKline(ctx, &KlinesRequestParams{ + Interval: e.FormatExchangeKlineInterval(req.ExchangeInterval), Symbol: req.Pair, StartTime: req.RangeHolder.Ranges[x].Start.Time, EndTime: req.RangeHolder.Ranges[x].End.Time, @@ -1744,9 +1744,9 @@ func (b *Binance) GetHistoricCandlesExtended(ctx context.Context, pair currency. } case asset.USDTMarginedFutures: var candles []FuturesCandleStick - candles, err = b.UKlineData(ctx, + candles, err = e.UKlineData(ctx, req.RequestFormatted, - b.FormatExchangeKlineInterval(interval), + e.FormatExchangeKlineInterval(interval), req.RangeHolder.Limit, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) @@ -1765,9 +1765,9 @@ func (b *Binance) GetHistoricCandlesExtended(ctx context.Context, pair currency. } case asset.CoinMarginedFutures: var candles []FuturesCandleStick - candles, err = b.GetFuturesKlineData(ctx, + candles, err = e.GetFuturesKlineData(ctx, req.RequestFormatted, - b.FormatExchangeKlineInterval(interval), + e.FormatExchangeKlineInterval(interval), req.RangeHolder.Limit, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) @@ -1835,31 +1835,30 @@ func compatibleOrderVars(side, status, orderType string) OrderVars { } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (b *Binance) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { var limits []order.MinMaxLevel var err error switch a { case asset.Spot: - limits, err = b.FetchExchangeLimits(ctx, asset.Spot) + limits, err = e.FetchExchangeLimits(ctx, asset.Spot) case asset.USDTMarginedFutures: - limits, err = b.FetchUSDTMarginExchangeLimits(ctx) + limits, err = e.FetchUSDTMarginExchangeLimits(ctx) case asset.CoinMarginedFutures: - limits, err = b.FetchCoinMarginExchangeLimits(ctx) + limits, err = e.FetchCoinMarginExchangeLimits(ctx) case asset.Margin: - limits, err = b.FetchExchangeLimits(ctx, asset.Margin) + limits, err = e.FetchExchangeLimits(ctx, asset.Margin) default: err = fmt.Errorf("%w %v", asset.ErrNotSupported, a) } if err != nil { return fmt.Errorf("cannot update exchange execution limits: %w", err) } - return b.LoadLimits(limits) + return e.LoadLimits(limits) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (b *Binance) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - coinInfo, err := b.GetAllCoinsInfo(ctx) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + coinInfo, err := e.GetAllCoinsInfo(ctx) if err != nil { return nil, err } @@ -1878,26 +1877,26 @@ func (b *Binance) GetAvailableTransferChains(ctx context.Context, cryptocurrency // FormatExchangeCurrency is a method that formats and returns a currency pair // based on the user currency display preferences // overrides default implementation to use optional delimiter -func (b *Binance) FormatExchangeCurrency(p currency.Pair, a asset.Item) (currency.Pair, error) { - pairFmt, err := b.GetPairFormat(a, true) +func (e *Exchange) FormatExchangeCurrency(p currency.Pair, a asset.Item) (currency.Pair, error) { + pairFmt, err := e.GetPairFormat(a, true) if err != nil { return currency.EMPTYPAIR, err } if a == asset.USDTMarginedFutures { - return b.formatUSDTMarginedFuturesPair(p, pairFmt), nil + return e.formatUSDTMarginedFuturesPair(p, pairFmt), nil } return p.Format(pairFmt), nil } // FormatSymbol formats the given pair to a string suitable for exchange API requests // overrides default implementation to use optional delimiter -func (b *Binance) FormatSymbol(p currency.Pair, a asset.Item) (string, error) { - pairFmt, err := b.GetPairFormat(a, true) +func (e *Exchange) FormatSymbol(p currency.Pair, a asset.Item) (string, error) { + pairFmt, err := e.GetPairFormat(a, true) if err != nil { return p.String(), err } if a == asset.USDTMarginedFutures { - p = b.formatUSDTMarginedFuturesPair(p, pairFmt) + p = e.formatUSDTMarginedFuturesPair(p, pairFmt) return p.String(), nil } return pairFmt.Format(p), nil @@ -1905,7 +1904,7 @@ func (b *Binance) FormatSymbol(p currency.Pair, a asset.Item) (string, error) { // formatUSDTMarginedFuturesPair Binance USDTMarginedFutures pairs have a delimiter // only if the contract has an expiry date -func (b *Binance) formatUSDTMarginedFuturesPair(p currency.Pair, pairFmt currency.PairFormat) currency.Pair { +func (e *Exchange) formatUSDTMarginedFuturesPair(p currency.Pair, pairFmt currency.PairFormat) currency.Pair { quote := p.Quote.String() for _, c := range quote { if c < '0' || c > '9' { @@ -1918,18 +1917,18 @@ func (b *Binance) formatUSDTMarginedFuturesPair(p currency.Pair, pairFmt currenc } // GetServerTime returns the current exchange server time. -func (b *Binance) GetServerTime(ctx context.Context, ai asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(ctx context.Context, ai asset.Item) (time.Time, error) { switch ai { case asset.USDTMarginedFutures: - return b.UServerTime(ctx) + return e.UServerTime(ctx) case asset.Spot: - info, err := b.GetExchangeInfo(ctx) + info, err := e.GetExchangeInfo(ctx) if err != nil { return time.Time{}, err } return info.ServerTime.Time(), nil case asset.CoinMarginedFutures: - info, err := b.FuturesExchangeInfo(ctx) + info, err := e.FuturesExchangeInfo(ctx) if err != nil { return time.Time{}, err } @@ -1939,7 +1938,7 @@ func (b *Binance) GetServerTime(ctx context.Context, ai asset.Item) (time.Time, } // GetLatestFundingRates returns the latest funding rates data -func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1950,7 +1949,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late var err error if !fPair.IsEmpty() { var format currency.PairFormat - format, err = b.GetPairFormat(r.Asset, true) + format, err = e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } @@ -1961,11 +1960,11 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late case asset.USDTMarginedFutures: var mp []UMarkPrice var fri []FundingRateInfoResponse - fri, err = b.UGetFundingRateInfo(ctx) + fri, err = e.UGetFundingRateInfo(ctx) if err != nil { return nil, err } - mp, err = b.UGetMarkPrice(ctx, fPair) + mp, err = e.UGetMarkPrice(ctx, fPair) if err != nil { return nil, err } @@ -1973,7 +1972,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late for i := range mp { var cp currency.Pair var isEnabled bool - cp, isEnabled, err = b.MatchSymbolCheckEnabled(mp[i].Symbol, r.Asset, true) + cp, isEnabled, err = e.MatchSymbolCheckEnabled(mp[i].Symbol, r.Asset, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1981,7 +1980,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late continue } var isPerp bool - isPerp, err = b.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -2000,7 +1999,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late cft := nft.Add(-time.Hour * time.Duration(fundingRateFrequency)) rate := fundingrate.LatestRateResponse{ TimeChecked: time.Now(), - Exchange: b.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -2019,12 +2018,12 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late return resp, nil case asset.CoinMarginedFutures: var fri []FundingRateInfoResponse - fri, err = b.GetFundingRateInfo(ctx) + fri, err = e.GetFundingRateInfo(ctx) if err != nil { return nil, err } var mp []IndexMarkPrice - mp, err = b.GetIndexAndMarkPrice(ctx, fPair.String(), "") + mp, err = e.GetIndexAndMarkPrice(ctx, fPair.String(), "") if err != nil { return nil, err } @@ -2036,7 +2035,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late return nil, err } var isPerp bool - isPerp, err = b.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -2055,7 +2054,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late cft := nft.Add(-time.Hour * time.Duration(fundingRateFrequency)) rate := fundingrate.LatestRateResponse{ TimeChecked: time.Now(), - Exchange: b.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -2077,7 +2076,7 @@ func (b *Binance) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } // GetHistoricalFundingRates returns funding rates for a given asset and currency for a time period -func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { +func (e *Exchange) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } @@ -2090,13 +2089,13 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. if err := common.StartEndTimeCheck(r.StartDate, r.EndDate); err != nil { return nil, err } - format, err := b.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } fPair := r.Pair.Format(format) pairRate := fundingrate.HistoricalRates{ - Exchange: b.Name, + Exchange: e.Name, Asset: r.Asset, Pair: fPair, StartDate: r.StartDate, @@ -2107,7 +2106,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. requestLimit := 1000 sd := r.StartDate var fri []FundingRateInfoResponse - fri, err = b.UGetFundingRateInfo(ctx) + fri, err = e.UGetFundingRateInfo(ctx) if err != nil { return nil, err } @@ -2122,7 +2121,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } for { var frh []FundingRateHistory - frh, err = b.UGetFundingHistory(ctx, fPair, int64(requestLimit), sd, r.EndDate) + frh, err = e.UGetFundingHistory(ctx, fPair, int64(requestLimit), sd, r.EndDate) if err != nil { return nil, err } @@ -2138,7 +2137,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. sd = frh[len(frh)-1].FundingTime.Time() } var mp []UMarkPrice - mp, err = b.UGetMarkPrice(ctx, fPair) + mp, err = e.UGetMarkPrice(ctx, fPair) if err != nil { return nil, err } @@ -2149,7 +2148,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. pairRate.TimeOfNextRate = mp[len(mp)-1].NextFundingTime.Time() if r.IncludePayments { var income []UAccountIncomeHistory - income, err = b.UAccountIncomeHistory(ctx, fPair, "FUNDING_FEE", int64(requestLimit), r.StartDate, r.EndDate) + income, err = e.UAccountIncomeHistory(ctx, fPair, "FUNDING_FEE", int64(requestLimit), r.StartDate, r.EndDate) if err != nil { return nil, err } @@ -2172,7 +2171,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. requestLimit := 1000 sd := r.StartDate var fri []FundingRateInfoResponse - fri, err = b.GetFundingRateInfo(ctx) + fri, err = e.GetFundingRateInfo(ctx) if err != nil { return nil, err } @@ -2187,7 +2186,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } for { var frh []FundingRateHistory - frh, err = b.FuturesGetFundingHistory(ctx, fPair, int64(requestLimit), sd, r.EndDate) + frh, err = e.FuturesGetFundingHistory(ctx, fPair, int64(requestLimit), sd, r.EndDate) if err != nil { return nil, err } @@ -2203,7 +2202,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. sd = frh[len(frh)-1].FundingTime.Time() } var mp []IndexMarkPrice - mp, err = b.GetIndexAndMarkPrice(ctx, fPair.String(), "") + mp, err = e.GetIndexAndMarkPrice(ctx, fPair.String(), "") if err != nil { return nil, err } @@ -2214,7 +2213,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. pairRate.TimeOfNextRate = mp[len(mp)-1].NextFundingTime.Time() if r.IncludePayments { var income []FuturesIncomeHistoryData - income, err = b.FuturesIncomeHistory(ctx, fPair, "FUNDING_FEE", r.StartDate, r.EndDate, int64(requestLimit)) + income, err = e.FuturesIncomeHistory(ctx, fPair, "FUNDING_FEE", r.StartDate, r.EndDate, int64(requestLimit)) if err != nil { return nil, err } @@ -2240,7 +2239,7 @@ func (b *Binance) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (b *Binance) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { if a == asset.CoinMarginedFutures { return cp.Quote.Equal(currency.PERP), nil } @@ -2251,22 +2250,22 @@ func (b *Binance) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (boo } // SetCollateralMode sets the account's collateral mode for the asset type -func (b *Binance) SetCollateralMode(ctx context.Context, a asset.Item, collateralMode collateral.Mode) error { +func (e *Exchange) SetCollateralMode(ctx context.Context, a asset.Item, collateralMode collateral.Mode) error { if a != asset.USDTMarginedFutures { return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } if collateralMode != collateral.MultiMode && collateralMode != collateral.SingleMode { return fmt.Errorf("%w %v", order.ErrCollateralInvalid, collateralMode) } - return b.SetAssetsMode(ctx, collateralMode == collateral.MultiMode) + return e.SetAssetsMode(ctx, collateralMode == collateral.MultiMode) } // GetCollateralMode returns the account's collateral mode for the asset type -func (b *Binance) GetCollateralMode(ctx context.Context, a asset.Item) (collateral.Mode, error) { +func (e *Exchange) GetCollateralMode(ctx context.Context, a asset.Item) (collateral.Mode, error) { if a != asset.USDTMarginedFutures { return collateral.UnknownMode, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - isMulti, err := b.GetAssetsMode(ctx) + isMulti, err := e.GetAssetsMode(ctx) if err != nil { return collateral.UnknownMode, err } @@ -2277,22 +2276,22 @@ func (b *Binance) GetCollateralMode(ctx context.Context, a asset.Item) (collater } // SetMarginType sets the default margin type for when opening a new position -func (b *Binance) SetMarginType(ctx context.Context, item asset.Item, pair currency.Pair, tp margin.Type) error { +func (e *Exchange) SetMarginType(ctx context.Context, item asset.Item, pair currency.Pair, tp margin.Type) error { if item != asset.USDTMarginedFutures && item != asset.CoinMarginedFutures { return fmt.Errorf("%w %v", asset.ErrNotSupported, item) } if !tp.Valid() { return fmt.Errorf("%w %v", margin.ErrInvalidMarginType, tp) } - mt, err := b.marginTypeToString(tp) + mt, err := e.marginTypeToString(tp) if err != nil { return err } switch item { case asset.CoinMarginedFutures: - _, err = b.FuturesChangeMarginType(ctx, pair, mt) + _, err = e.FuturesChangeMarginType(ctx, pair, mt) case asset.USDTMarginedFutures: - err = b.UChangeInitialMarginType(ctx, pair, mt) + err = e.UChangeInitialMarginType(ctx, pair, mt) } if err != nil { return err @@ -2302,7 +2301,7 @@ func (b *Binance) SetMarginType(ctx context.Context, item asset.Item, pair curre } // ChangePositionMargin will modify a position/currencies margin parameters -func (b *Binance) ChangePositionMargin(ctx context.Context, req *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { +func (e *Exchange) ChangePositionMargin(ctx context.Context, req *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { if req == nil { return nil, fmt.Errorf("%w PositionChangeRequest", common.ErrNilPointer) } @@ -2330,16 +2329,16 @@ func (b *Binance) ChangePositionMargin(ctx context.Context, req *margin.Position var err error switch req.Asset { case asset.CoinMarginedFutures: - _, err = b.ModifyIsolatedPositionMargin(ctx, req.Pair, side, marginType, req.NewAllocatedMargin) + _, err = e.ModifyIsolatedPositionMargin(ctx, req.Pair, side, marginType, req.NewAllocatedMargin) case asset.USDTMarginedFutures: - _, err = b.UModifyIsolatedPositionMarginReq(ctx, req.Pair, side, marginType, req.NewAllocatedMargin) + _, err = e.UModifyIsolatedPositionMarginReq(ctx, req.Pair, side, marginType, req.NewAllocatedMargin) } if err != nil { return nil, err } return &margin.PositionChangeResponse{ - Exchange: b.Name, + Exchange: e.Name, Pair: req.Pair, Asset: req.Asset, MarginType: req.MarginType, @@ -2348,7 +2347,7 @@ func (b *Binance) ChangePositionMargin(ctx context.Context, req *margin.Position } // marginTypeToString converts the GCT margin type to Binance's string -func (b *Binance) marginTypeToString(mt margin.Type) (string, error) { +func (e *Exchange) marginTypeToString(mt margin.Type) (string, error) { switch mt { case margin.Isolated: return margin.Isolated.Upper(), nil @@ -2360,20 +2359,20 @@ func (b *Binance) marginTypeToString(mt margin.Type) (string, error) { // GetFuturesPositionSummary returns the account's position summary for the asset type and pair // it can be used to calculate potential positions -func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { +func (e *Exchange) GetFuturesPositionSummary(ctx context.Context, req *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { if req == nil { return nil, fmt.Errorf("%w GetFuturesPositionSummary", common.ErrNilPointer) } if req.CalculateOffline { return nil, common.ErrCannotCalculateOffline } - fPair, err := b.FormatExchangeCurrency(req.Pair, req.Asset) + fPair, err := e.FormatExchangeCurrency(req.Pair, req.Asset) if err != nil { return nil, err } switch req.Asset { case asset.USDTMarginedFutures: - ai, err := b.UAccountInformationV2(ctx) + ai, err := e.UAccountInformationV2(ctx) if err != nil { return nil, err } @@ -2425,7 +2424,7 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } var contracts []futures.Contract - contracts, err = b.GetFuturesContractDetails(ctx, req.Asset) + contracts, err = e.GetFuturesContractDetails(ctx, req.Asset) if err != nil { return nil, err } @@ -2476,7 +2475,7 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } // binance so fun, some prices exclusively here - positionsInfo, err := b.UPositionsInfoV2(ctx, fPair) + positionsInfo, err := e.UPositionsInfoV2(ctx, fPair) if err != nil { return nil, err } @@ -2515,7 +2514,7 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po NotionalSize: decimal.NewFromFloat(positionSize).Mul(decimal.NewFromFloat(markPrice)), }, nil case asset.CoinMarginedFutures: - ai, err := b.GetFuturesAccountInfo(ctx) + ai, err := e.GetFuturesAccountInfo(ctx) if err != nil { return nil, err } @@ -2572,7 +2571,7 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } // binance so fun, some prices exclusively here - positionsInfo, err := b.FuturesPositionsInfo(ctx, "", req.Pair.Base.String()) + positionsInfo, err := e.FuturesPositionsInfo(ctx, "", req.Pair.Base.String()) if err != nil { return nil, err } @@ -2599,7 +2598,7 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } var contracts []futures.Contract - contracts, err = b.GetFuturesContractDetails(ctx, req.Asset) + contracts, err = e.GetFuturesContractDetails(ctx, req.Asset) if err != nil { return nil, err } @@ -2641,18 +2640,18 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } // GetFuturesPositionOrders returns the orders for futures positions -func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.PositionsRequest) ([]futures.PositionResponse, error) { +func (e *Exchange) GetFuturesPositionOrders(ctx context.Context, req *futures.PositionsRequest) ([]futures.PositionResponse, error) { if req == nil { return nil, fmt.Errorf("%w GetFuturesPositionOrders", common.ErrNilPointer) } if len(req.Pairs) == 0 { return nil, currency.ErrCurrencyPairsEmpty } - if time.Since(req.StartDate) > b.Features.Supports.MaximumOrderHistory+time.Hour { + if time.Since(req.StartDate) > e.Features.Supports.MaximumOrderHistory+time.Hour { if req.RespectOrderHistoryLimits { - req.StartDate = time.Now().Add(-b.Features.Supports.MaximumOrderHistory) + req.StartDate = time.Now().Add(-e.Features.Supports.MaximumOrderHistory) } else { - return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-b.Features.Supports.MaximumOrderHistory)) + return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-e.Features.Supports.MaximumOrderHistory)) } } if req.EndDate.IsZero() { @@ -2665,11 +2664,11 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos case asset.USDTMarginedFutures: orderLimit := 1000 for x := range req.Pairs { - fPair, err := b.FormatExchangeCurrency(req.Pairs[x], req.Asset) + fPair, err := e.FormatExchangeCurrency(req.Pairs[x], req.Asset) if err != nil { return nil, err } - result, err := b.UPositionsInfoV2(ctx, fPair) + result, err := e.UPositionsInfoV2(ctx, fPair) if err != nil { return nil, err } @@ -2680,7 +2679,7 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos } for { var orders []UFuturesOrderData - orders, err = b.UAllAccountOrders(ctx, fPair, 0, int64(orderLimit), sd, req.EndDate) + orders, err = e.UAllAccountOrders(ctx, fPair, 0, int64(orderLimit), sd, req.EndDate) if err != nil { return nil, err } @@ -2706,7 +2705,7 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos RemainingAmount: orders[i].OrigQty - orders[i].ExecutedQty, CostAsset: req.Pairs[x].Quote, Leverage: result[y].Leverage, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(orders[i].OrderID, 10), ClientOrderID: orders[i].ClientOrderID, Type: orderVars.OrderType, @@ -2730,13 +2729,13 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos case asset.CoinMarginedFutures: orderLimit := 100 for x := range req.Pairs { - fPair, err := b.FormatExchangeCurrency(req.Pairs[x], req.Asset) + fPair, err := e.FormatExchangeCurrency(req.Pairs[x], req.Asset) if err != nil { return nil, err } // "pair" for coinmarginedfutures is the pair.Base // eg ADAUSD_PERP the pair is ADAUSD - result, err := b.FuturesPositionsInfo(ctx, "", fPair.Base.String()) + result, err := e.FuturesPositionsInfo(ctx, "", fPair.Base.String()) if err != nil { return nil, err } @@ -2750,7 +2749,7 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos } for { var orders []FuturesOrderData - orders, err = b.GetAllFuturesOrders(ctx, fPair, currency.EMPTYPAIR, sd, req.EndDate, 0, int64(orderLimit)) + orders, err = e.GetAllFuturesOrders(ctx, fPair, currency.EMPTYPAIR, sd, req.EndDate, 0, int64(orderLimit)) if err != nil { return nil, err } @@ -2781,7 +2780,7 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos RemainingAmount: orders[i].OrigQty - orders[i].ExecutedQty, Leverage: result[y].Leverage, CostAsset: orderPair.Base, - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(orders[i].OrderID, 10), ClientOrderID: orders[i].ClientOrderID, Type: orderVars.OrderType, @@ -2809,13 +2808,13 @@ func (b *Binance) GetFuturesPositionOrders(ctx context.Context, req *futures.Pos } // SetLeverage sets the account's initial leverage for the asset type and pair -func (b *Binance) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, amount float64, _ order.Side) error { +func (e *Exchange) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, amount float64, _ order.Side) error { switch item { case asset.USDTMarginedFutures: - _, err := b.UChangeInitialLeverageRequest(ctx, pair, amount) + _, err := e.UChangeInitialLeverageRequest(ctx, pair, amount) return err case asset.CoinMarginedFutures: - _, err := b.FuturesChangeInitialLeverage(ctx, pair, amount) + _, err := e.FuturesChangeInitialLeverage(ctx, pair, amount) return err default: return fmt.Errorf("%w %v", asset.ErrNotSupported, item) @@ -2823,13 +2822,13 @@ func (b *Binance) SetLeverage(ctx context.Context, item asset.Item, pair currenc } // GetLeverage gets the account's initial leverage for the asset type and pair -func (b *Binance) GetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, _ order.Side) (float64, error) { +func (e *Exchange) GetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, _ order.Side) (float64, error) { if pair.IsEmpty() { return -1, currency.ErrCurrencyPairEmpty } switch item { case asset.USDTMarginedFutures: - resp, err := b.UPositionsInfoV2(ctx, pair) + resp, err := e.UPositionsInfoV2(ctx, pair) if err != nil { return -1, err } @@ -2839,7 +2838,7 @@ func (b *Binance) GetLeverage(ctx context.Context, item asset.Item, pair currenc // leverage is the same across positions return resp[0].Leverage, nil case asset.CoinMarginedFutures: - resp, err := b.FuturesPositionsInfo(ctx, "", pair.Base.String()) + resp, err := e.FuturesPositionsInfo(ctx, "", pair.Base.String()) if err != nil { return -1, err } @@ -2854,17 +2853,17 @@ func (b *Binance) GetLeverage(ctx context.Context, item asset.Item, pair currenc } // GetFuturesContractDetails returns details about futures contracts -func (b *Binance) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } switch item { case asset.USDTMarginedFutures: - fri, err := b.UGetFundingRateInfo(ctx) + fri, err := e.UGetFundingRateInfo(ctx) if err != nil { return nil, err } - ei, err := b.UExchangeInfo(ctx) + ei, err := e.UExchangeInfo(ctx) if err != nil { return nil, err } @@ -2893,7 +2892,7 @@ func (b *Binance) GetFuturesContractDetails(ctx context.Context, item asset.Item ed = ei.Symbols[i].DeliveryDate.Time() } resp = append(resp, futures.Contract{ - Exchange: b.Name, + Exchange: e.Name, Name: cp, Underlying: currency.NewPair(currency.NewCode(ei.Symbols[i].BaseAsset), currency.NewCode(ei.Symbols[i].QuoteAsset)), Asset: item, @@ -2910,11 +2909,11 @@ func (b *Binance) GetFuturesContractDetails(ctx context.Context, item asset.Item } return resp, nil case asset.CoinMarginedFutures: - fri, err := b.GetFundingRateInfo(ctx) + fri, err := e.GetFundingRateInfo(ctx) if err != nil { return nil, err } - ei, err := b.FuturesExchangeInfo(ctx) + ei, err := e.FuturesExchangeInfo(ctx) if err != nil { return nil, err } @@ -2945,7 +2944,7 @@ func (b *Binance) GetFuturesContractDetails(ctx context.Context, item asset.Item ed = ei.Symbols[i].DeliveryDate.Time() } resp = append(resp, futures.Contract{ - Exchange: b.Name, + Exchange: e.Name, Name: cp, Underlying: currency.NewPair(currency.NewCode(ei.Symbols[i].BaseAsset), currency.NewCode(ei.Symbols[i].QuoteAsset)), Asset: item, @@ -2965,7 +2964,7 @@ func (b *Binance) GetFuturesContractDetails(ctx context.Context, item asset.Item } // GetOpenInterest returns the open interest rate for a given asset pair -func (b *Binance) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { if len(k) == 0 { return nil, fmt.Errorf("%w requires pair", common.ErrFunctionNotSupported) } @@ -2979,13 +2978,13 @@ func (b *Binance) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu for i := range k { switch k[i].Asset { case asset.USDTMarginedFutures: - oi, err := b.UOpenInterest(ctx, k[i].Pair()) + oi, err := e.UOpenInterest(ctx, k[i].Pair()) if err != nil { return nil, err } result[i] = futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: b.Name, + Exchange: e.Name, Base: k[i].Base, Quote: k[i].Quote, Asset: k[i].Asset, @@ -2993,13 +2992,13 @@ func (b *Binance) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu OpenInterest: oi.OpenInterest, } case asset.CoinMarginedFutures: - oi, err := b.OpenInterest(ctx, k[i].Pair()) + oi, err := e.OpenInterest(ctx, k[i].Pair()) if err != nil { return nil, err } result[i] = futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: b.Name, + Exchange: e.Name, Base: k[i].Base, Quote: k[i].Quote, Asset: k[i].Asset, @@ -3012,12 +3011,12 @@ func (b *Binance) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Binance) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } - symbol, err := b.FormatSymbol(cp, a) + symbol, err := e.FormatSymbol(cp, a) if err != nil { return "", err } @@ -3025,7 +3024,7 @@ func (b *Binance) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp curr case asset.USDTMarginedFutures: var ct string if !cp.Quote.Equal(currency.USDT) && !cp.Quote.Equal(currency.BUSD) { - ei, err := b.UExchangeInfo(ctx) + ei, err := e.UExchangeInfo(ctx) if err != nil { return "", err } @@ -3047,7 +3046,7 @@ func (b *Binance) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp curr case asset.CoinMarginedFutures: var ct string if !cp.Quote.Equal(currency.USDT) && !cp.Quote.Equal(currency.BUSD) { - ei, err := b.FuturesExchangeInfo(ctx) + ei, err := e.FuturesExchangeInfo(ctx) if err != nil { return "", err } diff --git a/exchanges/binanceus/binanceus.go b/exchanges/binanceus/binanceus.go index 8d80f03f5ca..140b08856d1 100644 --- a/exchanges/binanceus/binanceus.go +++ b/exchanges/binanceus/binanceus.go @@ -23,8 +23,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" ) -// Binanceus is the overarching type across this package -type Binanceus struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Binanceus +type Exchange struct { exchange.Base obm *orderbookManager } @@ -146,35 +146,35 @@ var ( // General Data Endpoints // GetServerTime this endpoint returns the exchange server time. -func (bi *Binanceus) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { var response ServerTime - err := bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, serverTime, spotDefaultRate, &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, serverTime, spotDefaultRate, &response) return response.Timestamp.Time(), err } // GetSystemStatus endpoint to fetch whether the system status is normal or under maintenance. -func (bi *Binanceus) GetSystemStatus(ctx context.Context) (int, error) { +func (e *Exchange) GetSystemStatus(ctx context.Context) (int, error) { resp := struct { Status int `json:"status"` }{} - return resp.Status, bi.SendAuthHTTPRequest( + return resp.Status, e.SendAuthHTTPRequest( ctx, exchange.RestSpotSupplementary, http.MethodGet, systemStatus, nil, spotDefaultRate, &resp) } // GetExchangeInfo to get the current exchange trading rules and trading pair information. -func (bi *Binanceus) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { +func (e *Exchange) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { var respo ExchangeInfo - return respo, bi.SendHTTPRequest(ctx, + return respo, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, exchangeInfo, spotExchangeInfo, &respo) } // GetMostRecentTrades to get older trades. maximum limit in the RecentTradeRequestParams is 1,000 trades. -func (bi *Binanceus) GetMostRecentTrades(ctx context.Context, rtr RecentTradeRequestParams) ([]RecentTrade, error) { +func (e *Exchange) GetMostRecentTrades(ctx context.Context, rtr RecentTradeRequestParams) ([]RecentTrade, error) { params := url.Values{} - symbol, err := bi.FormatSymbol(rtr.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(rtr.Symbol, asset.Spot) if err != nil { return nil, err } @@ -182,13 +182,13 @@ func (bi *Binanceus) GetMostRecentTrades(ctx context.Context, rtr RecentTradeReq params.Set("limit", strconv.FormatInt(rtr.Limit, 10)) path := common.EncodeURLValues(recentTrades, params) var resp []RecentTrade - return resp, bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetHistoricalTrades returns historical trade activity // symbol: string of currency pair // limit: Optional. Default 500; max 1000. -func (bi *Binanceus) GetHistoricalTrades(ctx context.Context, hist HistoricalTradeParams) ([]HistoricalTrade, error) { +func (e *Exchange) GetHistoricalTrades(ctx context.Context, hist HistoricalTradeParams) ([]HistoricalTrade, error) { var resp []HistoricalTrade params := url.Values{} params.Set("symbol", hist.Symbol) @@ -197,13 +197,13 @@ func (bi *Binanceus) GetHistoricalTrades(ctx context.Context, hist HistoricalTra params.Set("fromId", strconv.FormatUint(hist.FromID, 10)) } path := common.EncodeURLValues(historicalTrades, params) - return resp, bi.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotHistoricalTradesRate, &resp) + return resp, e.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotHistoricalTradesRate, &resp) } // GetAggregateTrades to get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated. -func (bi *Binanceus) GetAggregateTrades(ctx context.Context, agg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { +func (e *Exchange) GetAggregateTrades(ctx context.Context, agg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { params := url.Values{} - symbol, err := bi.FormatSymbol(agg.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(agg.Symbol, asset.Spot) if err != nil { return nil, err } @@ -237,7 +237,7 @@ func (bi *Binanceus) GetAggregateTrades(ctx context.Context, agg *AggregatedTrad // fromId xor start time must be set canBatch := agg.FromID == 0 != startTime.IsZero() if canBatch { - return bi.batchAggregateTrades(ctx, agg, params) + return e.batchAggregateTrades(ctx, agg, params) } // Can't handle this request locally or remotely // We would receive {"code":-1128,"msg":"Combination of optional parameters invalid."} @@ -245,14 +245,14 @@ func (bi *Binanceus) GetAggregateTrades(ctx context.Context, agg *AggregatedTrad } var resp []AggregatedTrade path := common.EncodeURLValues(aggregatedTrades, params) - return resp, bi.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // batchAggregateTrades fetches trades in multiple requests <-- copied and amended from the binance // first phase, hourly requests until the first trade (or end time) is reached // second phase, limit requests from previous trade until end time (or limit) is reached -func (bi *Binanceus) batchAggregateTrades(ctx context.Context, arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { +func (e *Exchange) batchAggregateTrades(ctx context.Context, arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { var resp []AggregatedTrade // prepare first request with only first hour and max limit if arg.Limit == 0 || arg.Limit > 1000 { @@ -277,7 +277,7 @@ func (bi *Binanceus) batchAggregateTrades(ctx context.Context, arg *AggregatedTr params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("endTime", strconv.FormatInt(startTime.Add(increment).UnixMilli(), 10)) path := common.EncodeURLValues(aggregatedTrades, params) - err := bi.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) if err != nil { return resp, err @@ -295,7 +295,7 @@ func (bi *Binanceus) batchAggregateTrades(ctx context.Context, arg *AggregatedTr params.Set("fromId", strconv.FormatInt(fromID, 10)) path := common.EncodeURLValues(aggregatedTrades, params) var additionalTrades []AggregatedTrade - err := bi.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, @@ -325,9 +325,9 @@ func (bi *Binanceus) batchAggregateTrades(ctx context.Context, arg *AggregatedTr } // GetOrderBookDepth to get the order book depth. Please note the limits in the table below. -func (bi *Binanceus) GetOrderBookDepth(ctx context.Context, arg *OrderBookDataRequestParams) (*OrderBook, error) { +func (e *Exchange) GetOrderBookDepth(ctx context.Context, arg *OrderBookDataRequestParams) (*OrderBook, error) { params := url.Values{} - symbol, err := bi.FormatSymbol(arg.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return nil, err } @@ -335,7 +335,7 @@ func (bi *Binanceus) GetOrderBookDepth(ctx context.Context, arg *OrderBookDataRe params.Set("limit", strconv.FormatInt(arg.Limit, 10)) var resp *OrderBookData - if err := bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(orderBookDepth, params), orderbookLimit(arg.Limit), &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(orderBookDepth, params), orderbookLimit(arg.Limit), &resp); err != nil { return nil, err } @@ -356,7 +356,7 @@ func (bi *Binanceus) GetOrderBookDepth(ctx context.Context, arg *OrderBookDataRe } // GetIntervalEnum allowed interval params by Binanceus -func (bi *Binanceus) GetIntervalEnum(interval kline.Interval) string { +func (e *Exchange) GetIntervalEnum(interval kline.Interval) string { switch interval { case kline.OneMin: return "1m" @@ -394,8 +394,8 @@ func (bi *Binanceus) GetIntervalEnum(interval kline.Interval) string { } // GetSpotKline to get Kline/candlestick bars for a token symbol. Klines are uniquely identified by their open time. -func (bi *Binanceus) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([]CandleStick, error) { - symbol, err := bi.FormatSymbol(arg.Symbol, asset.Spot) +func (e *Exchange) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([]CandleStick, error) { + symbol, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return nil, err } @@ -413,35 +413,35 @@ func (bi *Binanceus) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) } path := common.EncodeURLValues(candleStick, params) var resp []CandleStick - return resp, bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetSinglePriceData to get the latest price for a token symbol or symbols. -func (bi *Binanceus) GetSinglePriceData(ctx context.Context, symbol currency.Pair) (SymbolPrice, error) { +func (e *Exchange) GetSinglePriceData(ctx context.Context, symbol currency.Pair) (SymbolPrice, error) { var res SymbolPrice params := url.Values{} - symbolValue, err := bi.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return res, err } params.Set("symbol", symbolValue) path := common.EncodeURLValues(tickerPrice, params) - return res, bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &res) + return res, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &res) } // GetPriceDatas to get the latest price for symbols. -func (bi *Binanceus) GetPriceDatas(ctx context.Context) (SymbolPrices, error) { +func (e *Exchange) GetPriceDatas(ctx context.Context) (SymbolPrices, error) { var res SymbolPrices - return res, bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, tickerPrice, spotSymbolPriceAllRate, &res) + return res, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, tickerPrice, spotSymbolPriceAllRate, &res) } // GetAveragePrice returns current average price for a symbol. // // symbol: string of currency pair -func (bi *Binanceus) GetAveragePrice(ctx context.Context, symbol currency.Pair) (AveragePrice, error) { +func (e *Exchange) GetAveragePrice(ctx context.Context, symbol currency.Pair) (AveragePrice, error) { resp := AveragePrice{} params := url.Values{} - symbolValue, err := bi.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -449,19 +449,19 @@ func (bi *Binanceus) GetAveragePrice(ctx context.Context, symbol currency.Pair) path := common.EncodeURLValues(averagePrice, params) - return resp, bi.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetBestPrice returns the latest best price for symbol // symbol: string of currency pair -func (bi *Binanceus) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestPrice, error) { +func (e *Exchange) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestPrice, error) { resp := BestPrice{} params := url.Values{} rateLimit := spotOrderbookTickerAllRate if !symbol.IsEmpty() { rateLimit = spotDefaultRate - symbolValue, err := bi.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -470,18 +470,18 @@ func (bi *Binanceus) GetBestPrice(ctx context.Context, symbol currency.Pair) (Be path := common.EncodeURLValues(bestPrice, params) return resp, - bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) + e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetPriceChangeStats returns price change statistics for the last 24 hours // symbol: string of currency pair -func (bi *Binanceus) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) (PriceChangeStats, error) { +func (e *Exchange) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) (PriceChangeStats, error) { resp := PriceChangeStats{} params := url.Values{} rateLimit := spotPriceChangeAllRate if !symbol.IsEmpty() { rateLimit = spotDefaultRate - symbolValue, err := bi.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } @@ -489,26 +489,26 @@ func (bi *Binanceus) GetPriceChangeStats(ctx context.Context, symbol currency.Pa } path := common.EncodeURLValues(priceChange, params) - return resp, bi.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetTickers returns the ticker data for the last 24 hrs -func (bi *Binanceus) GetTickers(ctx context.Context) ([]PriceChangeStats, error) { +func (e *Exchange) GetTickers(ctx context.Context) ([]PriceChangeStats, error) { var resp []PriceChangeStats - return resp, bi.SendHTTPRequest(ctx, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, priceChange, spotPriceChangeAllRate, &resp) } // GetAccount returns binance user accounts -func (bi *Binanceus) GetAccount(ctx context.Context) (*Account, error) { +func (e *Exchange) GetAccount(ctx context.Context) (*Account, error) { type response struct { Response Account } var resp response params := url.Values{} - if err := bi.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, accountInfo, params, spotAccountInformationRate, @@ -524,7 +524,7 @@ func (bi *Binanceus) GetAccount(ctx context.Context) (*Account, error) { } // GetUserAccountStatus to fetch account status detail. -func (bi *Binanceus) GetUserAccountStatus(ctx context.Context, recvWindow uint64) (*AccountStatusResponse, error) { +func (e *Exchange) GetUserAccountStatus(ctx context.Context, recvWindow uint64) (*AccountStatusResponse, error) { var resp AccountStatusResponse params := url.Values{} timestamp := time.Now().UnixMilli() @@ -537,7 +537,7 @@ func (bi *Binanceus) GetUserAccountStatus(ctx context.Context, recvWindow uint64 } return &resp, - bi.SendAuthHTTPRequest(ctx, + e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, accountStatus, @@ -547,7 +547,7 @@ func (bi *Binanceus) GetUserAccountStatus(ctx context.Context, recvWindow uint64 } // GetUserAPITradingStatus to fetch account API trading status details. -func (bi *Binanceus) GetUserAPITradingStatus(ctx context.Context, recvWindow uint64) (*TradeStatus, error) { +func (e *Exchange) GetUserAPITradingStatus(ctx context.Context, recvWindow uint64) (*TradeStatus, error) { type response struct { Success bool `json:"success"` TC TradeStatus `json:"status"` @@ -561,7 +561,7 @@ func (bi *Binanceus) GetUserAPITradingStatus(ctx context.Context, recvWindow uin } params.Set("recvWindow", strconv.FormatUint(recvWindow, 10)) return &resp.TC, - bi.SendAuthHTTPRequest(ctx, + e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, tradingStatus, @@ -571,17 +571,17 @@ func (bi *Binanceus) GetUserAPITradingStatus(ctx context.Context, recvWindow uin } // GetFee to fetch trading fees. -func (bi *Binanceus) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - multiplier, er := bi.getMultiplier(ctx, feeBuilder.IsMaker, feeBuilder) + multiplier, er := e.getMultiplier(ctx, feeBuilder.IsMaker, feeBuilder) if er != nil { return 0, er } fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, multiplier) case exchange.CryptocurrencyWithdrawalFee: - wallet, er := bi.GetAssetFeesAndWalletStatus(ctx) + wallet, er := e.GetAssetFeesAndWalletStatus(ctx) if er != nil { return fee, er } @@ -602,12 +602,12 @@ func (bi *Binanceus) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder } // getMultiplier retrieves account based taker/maker fees -func (bi *Binanceus) getMultiplier(ctx context.Context, isMaker bool, feeBuilder *exchange.FeeBuilder) (float64, error) { - symbol, er := bi.FormatSymbol(feeBuilder.Pair, asset.Spot) +func (e *Exchange) getMultiplier(ctx context.Context, isMaker bool, feeBuilder *exchange.FeeBuilder) (float64, error) { + symbol, er := e.FormatSymbol(feeBuilder.Pair, asset.Spot) if er != nil { return 0, er } - trades, er := bi.GetTradeFee(ctx, 0, symbol) + trades, er := e.GetTradeFee(ctx, 0, symbol) if er != nil { return 0, er } @@ -633,7 +633,7 @@ func calculateTradingFee(purchasePrice, amount, multiplier float64) float64 { } // GetTradeFee to fetch trading fees. -func (bi *Binanceus) GetTradeFee(ctx context.Context, recvWindow uint64, symbol string) (TradeFeeList, error) { +func (e *Exchange) GetTradeFee(ctx context.Context, recvWindow uint64, symbol string) (TradeFeeList, error) { timestamp := time.Now().UnixMilli() params := url.Values{} var resp TradeFeeList @@ -649,7 +649,7 @@ func (bi *Binanceus) GetTradeFee(ctx context.Context, recvWindow uint64, symbol if symbol != "" { params.Set("symbol", symbol) } - return resp, bi.SendAuthHTTPRequest(ctx, + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, tradeFee, @@ -663,7 +663,7 @@ func (bi *Binanceus) GetTradeFee(ctx context.Context, recvWindow uint64, symbol // // INPUTS: // asset: string , startTime & endTime unix time in Milli seconds, recvWindow(duration in milli seconds > 2000 to < 6000) -func (bi *Binanceus) GetAssetDistributionHistory(ctx context.Context, asset string, startTime, endTime int64, recvWindow uint64) (*AssetDistributionHistories, error) { +func (e *Exchange) GetAssetDistributionHistory(ctx context.Context, asset string, startTime, endTime int64, recvWindow uint64) (*AssetDistributionHistories, error) { params := url.Values{} timestamp := time.Now().UnixMilli() var resp AssetDistributionHistories @@ -686,7 +686,7 @@ func (bi *Binanceus) GetAssetDistributionHistory(ctx context.Context, asset stri if asset != "" { params.Set("asset", asset) } - return &resp, bi.SendAuthHTTPRequest(ctx, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, assetDistributionHistory, params, @@ -694,28 +694,28 @@ func (bi *Binanceus) GetAssetDistributionHistory(ctx context.Context, asset stri } // QuickEnableCryptoWithdrawal use this endpoint to enable crypto withdrawals. -func (bi *Binanceus) QuickEnableCryptoWithdrawal(ctx context.Context) error { +func (e *Exchange) QuickEnableCryptoWithdrawal(ctx context.Context) error { params := url.Values{} response := struct { Data any }{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - return bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, accountEnableCryptoWithdrawalEndpoint, params, spotDefaultRate, &(response.Data)) } // QuickDisableCryptoWithdrawal use this endpoint to disable crypto withdrawals. -func (bi *Binanceus) QuickDisableCryptoWithdrawal(ctx context.Context) error { +func (e *Exchange) QuickDisableCryptoWithdrawal(ctx context.Context) error { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - return bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, accountDisableCryptoWithdrawalEndpoint, params, spotDefaultRate, nil) } // GetUsersSpotAssetSnapshot retrieves a snapshot of list of assets in the account. -func (bi *Binanceus) GetUsersSpotAssetSnapshot(ctx context.Context, startTime, endTime time.Time, limit, offset uint64) (*SpotAssetsSnapshotResponse, error) { +func (e *Exchange) GetUsersSpotAssetSnapshot(ctx context.Context, startTime, endTime time.Time, limit, offset uint64) (*SpotAssetsSnapshotResponse, error) { params := url.Values{} params.Set("type", "SPOT") params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) @@ -732,13 +732,13 @@ func (bi *Binanceus) GetUsersSpotAssetSnapshot(ctx context.Context, startTime, e params.Set("offset", strconv.FormatUint(offset, 10)) } var resp SpotAssetsSnapshotResponse - return &resp, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, usersSpotAssetsSnapshot, params, spotDefaultRate, &resp) } // GetSubaccountInformation to fetch your sub-account list. -func (bi *Binanceus) GetSubaccountInformation(ctx context.Context, page, limit uint64, status, email string) ([]SubAccount, error) { +func (e *Exchange) GetSubaccountInformation(ctx context.Context, page, limit uint64, status, email string) ([]SubAccount, error) { params := url.Values{} type response struct { Success bool `json:"success"` @@ -760,7 +760,7 @@ func (bi *Binanceus) GetSubaccountInformation(ctx context.Context, page, limit u } timestamp := time.Now().UnixMilli() params.Set("timestamp", strconv.FormatInt(timestamp, 10)) - return resp.Subaccounts, bi.SendAuthHTTPRequest(ctx, + return resp.Subaccounts, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subaccountsInformation, @@ -770,7 +770,7 @@ func (bi *Binanceus) GetSubaccountInformation(ctx context.Context, page, limit u } // GetSubaccountTransferHistory to fetch sub-account asset transfer history. -func (bi *Binanceus) GetSubaccountTransferHistory(ctx context.Context, email string, startTime, endTime, page, limit int64) ([]TransferHistory, error) { +func (e *Exchange) GetSubaccountTransferHistory(ctx context.Context, email string, startTime, endTime, page, limit int64) ([]TransferHistory, error) { if !common.MatchesEmailPattern(email) { return nil, errNotValidEmailAddress } @@ -799,7 +799,7 @@ func (bi *Binanceus) GetSubaccountTransferHistory(ctx context.Context, email str Success bool `json:"success"` Transfers []TransferHistory `json:"transfers"` } - return resp.Transfers, bi.SendAuthHTTPRequest(ctx, + return resp.Transfers, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subaccountTransferHistory, @@ -809,7 +809,7 @@ func (bi *Binanceus) GetSubaccountTransferHistory(ctx context.Context, email str } // ExecuteSubAccountTransfer to execute sub-account asset transfers. -func (bi *Binanceus) ExecuteSubAccountTransfer(ctx context.Context, arg *SubAccountTransferRequestParams) (*SubAccountTransferResponse, error) { +func (e *Exchange) ExecuteSubAccountTransfer(ctx context.Context, arg *SubAccountTransferRequestParams) (*SubAccountTransferResponse, error) { params := url.Values{} var response SubAccountTransferResponse if !common.MatchesEmailPattern(arg.FromEmail) { @@ -829,11 +829,11 @@ func (bi *Binanceus) ExecuteSubAccountTransfer(ctx context.Context, arg *SubAcco params.Set("asset", arg.Asset) params.Set("amount", strconv.FormatFloat(arg.Amount, 'f', 0, 64)) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, subaccountTransfer, params, spotDefaultRate, &response) + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, subaccountTransfer, params, spotDefaultRate, &response) } // GetSubaccountAssets to fetch sub-account assets. -func (bi *Binanceus) GetSubaccountAssets(ctx context.Context, email string) (*SubAccountAssets, error) { +func (e *Exchange) GetSubaccountAssets(ctx context.Context, email string) (*SubAccountAssets, error) { var resp SubAccountAssets if !common.MatchesEmailPattern(email) { return nil, errNotValidEmailAddress @@ -843,7 +843,7 @@ func (bi *Binanceus) GetSubaccountAssets(ctx context.Context, email string) (*Su params.Set("timestamp", strconv.FormatInt(timestamp, 10)) params.Set("email", email) // - return &resp, bi.SendAuthHTTPRequest(ctx, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subaccountAssets, params, spotDefaultRate, @@ -851,7 +851,7 @@ func (bi *Binanceus) GetSubaccountAssets(ctx context.Context, email string) (*Su } // GetMasterAccountTotalUSDValue this endpoint to get the total value of assets in the master account in USD. -func (bi *Binanceus) GetMasterAccountTotalUSDValue(ctx context.Context, email string, page, size int) (*SpotUSDMasterAccounts, error) { +func (e *Exchange) GetMasterAccountTotalUSDValue(ctx context.Context, email string, page, size int) (*SpotUSDMasterAccounts, error) { var response SpotUSDMasterAccounts params := url.Values{} if email != "" { @@ -864,13 +864,13 @@ func (bi *Binanceus) GetMasterAccountTotalUSDValue(ctx context.Context, email st params.Set("size", strconv.Itoa(size)) } params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, masterAccounts, params, spotDefaultRate, &response) } // GetSubaccountStatusList this endpoint retrieves a status list of sub-accounts. -func (bi *Binanceus) GetSubaccountStatusList(ctx context.Context, email string) ([]SubAccountStatus, error) { +func (e *Exchange) GetSubaccountStatusList(ctx context.Context, email string) ([]SubAccountStatus, error) { params := url.Values{} if !common.MatchesEmailPattern(email) { return nil, errMissingSubAccountEmail @@ -878,7 +878,7 @@ func (bi *Binanceus) GetSubaccountStatusList(ctx context.Context, email string) params.Set("email", email) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response []SubAccountStatus - return response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subAccountStatusList, params, spotDefaultRate, &response) } @@ -887,7 +887,7 @@ func (bi *Binanceus) GetSubaccountStatusList(ctx context.Context, email string) // GetOrderRateLimits get the current trade order count rate limits for all time intervals. // INPUTS: recvWindow <= 60000 -func (bi *Binanceus) GetOrderRateLimits(ctx context.Context, recvWindow uint) ([]OrderRateLimit, error) { +func (e *Exchange) GetOrderRateLimits(ctx context.Context, recvWindow uint) ([]OrderRateLimit, error) { params := url.Values{} timestamp := time.Now().UnixMilli() params.Set("timestamp", strconv.Itoa(int(timestamp))) @@ -897,13 +897,13 @@ func (bi *Binanceus) GetOrderRateLimits(ctx context.Context, recvWindow uint) ([ params.Set("recvWindow", strconv.Itoa(30000)) } var resp []OrderRateLimit - return resp, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, orderRateLimit, params, spotOrderRateLimitRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, orderRateLimit, params, spotOrderRateLimitRate, &resp) } // NewOrder sends a new order to Binanceus -func (bi *Binanceus) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderResponse, error) { +func (e *Exchange) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderResponse, error) { var resp NewOrderResponse - if err := bi.newOrder(ctx, orderRequest, o, &resp); err != nil { + if err := e.newOrder(ctx, orderRequest, o, &resp); err != nil { return resp, err } if resp.Code != 0 { @@ -914,15 +914,15 @@ func (bi *Binanceus) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrder // NewOrderTest sends a new test order to Binanceus // to test new order creation and signature/recvWindow long. The endpoint creates and validates a new order but does not send it into the matching engine. -func (bi *Binanceus) NewOrderTest(ctx context.Context, o *NewOrderRequest) (*NewOrderResponse, error) { +func (e *Exchange) NewOrderTest(ctx context.Context, o *NewOrderRequest) (*NewOrderResponse, error) { var resp NewOrderResponse - return &resp, bi.newOrder(ctx, testCreateNeworder, o, &resp) + return &resp, e.newOrder(ctx, testCreateNeworder, o, &resp) } // newOrder this endpoint is used by both new order and NewOrderTest passing their route and order information to send new order. -func (bi *Binanceus) newOrder(ctx context.Context, api string, o *NewOrderRequest, resp *NewOrderResponse) error { +func (e *Exchange) newOrder(ctx context.Context, api string, o *NewOrderRequest, resp *NewOrderResponse) error { params := url.Values{} - symbol, err := bi.FormatSymbol(o.Symbol, asset.Spot) + symbol, err := e.FormatSymbol(o.Symbol, asset.Spot) if err != nil { return err } @@ -952,14 +952,14 @@ func (bi *Binanceus) newOrder(ctx context.Context, api string, o *NewOrderReques if o.NewOrderRespType != "" { params.Set("newOrderRespType", o.NewOrderRespType) } - return bi.SendAuthHTTPRequest(ctx, + return e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, api, params, spotOrderRate, resp) } // GetOrder to check a trade order's status. -func (bi *Binanceus) GetOrder(ctx context.Context, arg *OrderRequestParams) (*Order, error) { +func (e *Exchange) GetOrder(ctx context.Context, arg *OrderRequestParams) (*Order, error) { var resp Order params := url.Values{} if arg.Symbol == "" { @@ -977,7 +977,7 @@ func (bi *Binanceus) GetOrder(ctx context.Context, arg *OrderRequestParams) (*Or if arg.recvWindow > 200 && arg.recvWindow <= 6000 { params.Set("recvWindow", strconv.Itoa(int(arg.recvWindow))) } - return &resp, bi.SendAuthHTTPRequest(ctx, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, orderRequest, params, spotOrderQueryRate, @@ -985,7 +985,7 @@ func (bi *Binanceus) GetOrder(ctx context.Context, arg *OrderRequestParams) (*Or } // GetAllOpenOrders to get all open trade orders on a token symbol. Do not access this without a token symbol as this would return all pair data. -func (bi *Binanceus) GetAllOpenOrders(ctx context.Context, symbol string) ([]Order, error) { +func (e *Exchange) GetAllOpenOrders(ctx context.Context, symbol string) ([]Order, error) { var response []Order params := url.Values{} @@ -1001,18 +1001,18 @@ func (bi *Binanceus) GetAllOpenOrders(ctx context.Context, symbol string) ([]Ord } else { rateLimit = spotOpenOrdersAllRate } - return response, bi.SendAuthHTTPRequest(ctx, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, openOrders, params, rateLimit, &response) } // CancelExistingOrder to cancel an active trade order. -func (bi *Binanceus) CancelExistingOrder(ctx context.Context, arg *CancelOrderRequestParams) (*Order, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, arg *CancelOrderRequestParams) (*Order, error) { params := url.Values{} var response Order params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - symbolValue, err := bi.FormatSymbol(arg.Symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil || symbolValue == "" { return nil, errMissingCurrencySymbol } @@ -1026,14 +1026,14 @@ func (bi *Binanceus) CancelExistingOrder(ctx context.Context, arg *CancelOrderRe params.Set("orderId", arg.OrderID) } params.Set("recvWindow", recvWindowSize5000String) - return &response, bi.SendAuthHTTPRequest(ctx, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodDelete, orderRequest, params, spotOrderRate, &response) } // CancelOpenOrdersForSymbol request to cancel an open orders. -func (bi *Binanceus) CancelOpenOrdersForSymbol(ctx context.Context, symbol string) ([]Order, error) { +func (e *Exchange) CancelOpenOrdersForSymbol(ctx context.Context, symbol string) ([]Order, error) { params := url.Values{} if symbol == "" || len(symbol) < 4 { return nil, errMissingCurrencySymbol @@ -1042,13 +1042,13 @@ func (bi *Binanceus) CancelOpenOrdersForSymbol(ctx context.Context, symbol strin params.Set("timestamp", strconv.Itoa(int(time.Now().UnixMilli()))) params.Set("recvWindow", "5000") var response []Order - return response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodDelete, openOrders, params, spotOrderRate, response) } // GetTrades to get trade data for a specific account and token symbol. -func (bi *Binanceus) GetTrades(ctx context.Context, arg *GetTradesParams) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, arg *GetTradesParams) ([]Trade, error) { var resp []Trade params := url.Values{} if arg.Symbol == "" || len(arg.Symbol) <= 2 { @@ -1073,13 +1073,13 @@ func (bi *Binanceus) GetTrades(ctx context.Context, arg *GetTradesParams) ([]Tra } else if arg.Limit > 1000 { params.Set("limit", strconv.Itoa(1000)) } - return resp, bi.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, myTrades, params, spotTradesQueryRate, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, myTrades, params, spotTradesQueryRate, &resp) } // OCO Orders // CreateNewOCOOrder o place a new OCO(one-cancels-the-other) order. -func (bi *Binanceus) CreateNewOCOOrder(ctx context.Context, arg *OCOOrderInputParams) (*OCOFullOrderResponse, error) { +func (e *Exchange) CreateNewOCOOrder(ctx context.Context, arg *OCOOrderInputParams) (*OCOFullOrderResponse, error) { params := url.Values{} if arg == nil || arg.Symbol == "" || len(arg.Symbol) <= 2 || arg.Quantity == 0 || arg.Side == "" || arg.Price == 0 || arg.StopPrice == 0 { return nil, errIncompleteArguments @@ -1120,14 +1120,14 @@ func (bi *Binanceus) CreateNewOCOOrder(ctx context.Context, arg *OCOOrderInputPa } params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response OCOFullOrderResponse - return &response, bi.SendAuthHTTPRequest(ctx, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, ocoOrder, params, spotOrderRate, &response) } // GetOCOOrder to retrieve a specific OCO order based on provided optional parameters. -func (bi *Binanceus) GetOCOOrder(ctx context.Context, arg *GetOCOOrderRequestParams) (*OCOOrderResponse, error) { +func (e *Exchange) GetOCOOrder(ctx context.Context, arg *GetOCOOrderRequestParams) (*OCOOrderResponse, error) { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) switch { @@ -1140,11 +1140,11 @@ func (bi *Binanceus) GetOCOOrder(ctx context.Context, arg *GetOCOOrderRequestPar } params.Set("recvWindow", "60000") var response OCOOrderResponse - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocoOrderList, params, spotSingleOCOOrderRate, &response) + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocoOrderList, params, spotSingleOCOOrderRate, &response) } // GetAllOCOOrder to retrieve all OCO orders based on provided optional parameters. Please note the maximum limit is 1,000 orders. -func (bi *Binanceus) GetAllOCOOrder(ctx context.Context, arg *OCOOrdersRequestParams) ([]OCOOrderResponse, error) { +func (e *Exchange) GetAllOCOOrder(ctx context.Context, arg *OCOOrdersRequestParams) ([]OCOOrderResponse, error) { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response []OCOOrderResponse @@ -1164,14 +1164,14 @@ func (bi *Binanceus) GetAllOCOOrder(ctx context.Context, arg *OCOOrdersRequestPa if arg.RecvWindow > 0 { params.Set("recvWindow", strconv.FormatUint(arg.RecvWindow, 10)) } - return response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocoAllOrderList, params, spotAllOCOOrdersRate, &response) } // GetOpenOCOOrders to query open OCO orders. -func (bi *Binanceus) GetOpenOCOOrders(ctx context.Context, recvWindow uint64) ([]OCOOrderResponse, error) { +func (e *Exchange) GetOpenOCOOrders(ctx context.Context, recvWindow uint64) ([]OCOOrderResponse, error) { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) if recvWindow > 0 { @@ -1180,13 +1180,13 @@ func (bi *Binanceus) GetOpenOCOOrders(ctx context.Context, recvWindow uint64) ([ params.Set("recvWindow", "30000") } var response []OCOOrderResponse - return response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocoOpenOrders, params, spotOpenOrdersSpecificRate, &response) } // CancelOCOOrder to cancel an entire order list. -func (bi *Binanceus) CancelOCOOrder(ctx context.Context, arg *OCOOrdersDeleteRequestParams) (*OCOFullOrderResponse, error) { +func (e *Exchange) CancelOCOOrder(ctx context.Context, arg *OCOOrdersDeleteRequestParams) (*OCOFullOrderResponse, error) { var response OCOFullOrderResponse params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) @@ -1201,7 +1201,7 @@ func (bi *Binanceus) CancelOCOOrder(ctx context.Context, arg *OCOOrdersDeleteReq if arg.RecvWindow > 0 { params.Set("recvWindow", strconv.FormatUint(arg.RecvWindow, 10)) } - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocoOrderList, params, spotOrderRate, &response) } @@ -1210,20 +1210,20 @@ func (bi *Binanceus) CancelOCOOrder(ctx context.Context, arg *OCOOrdersDeleteReq // GetSupportedCoinPairs to get a list of supported coin pairs for convert. // returns list of CoinPairInfo -func (bi *Binanceus) GetSupportedCoinPairs(ctx context.Context, symbol currency.Pair) ([]CoinPairInfo, error) { +func (e *Exchange) GetSupportedCoinPairs(ctx context.Context, symbol currency.Pair) ([]CoinPairInfo, error) { params := url.Values{} if !symbol.IsEmpty() { params.Set("fromCoin", symbol.Base.String()) params.Set("toCoin", symbol.Quote.String()) } var resp []CoinPairInfo - return resp, bi.SendAuthHTTPRequest(ctx, + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, otcSelectors, params, spotDefaultRate, &resp) } // RequestForQuote endpoint to request a quote for a from-to coin pair. -func (bi *Binanceus) RequestForQuote(ctx context.Context, arg *RequestQuoteParams) (*Quote, error) { +func (e *Exchange) RequestForQuote(ctx context.Context, arg *RequestQuoteParams) (*Quote, error) { params := url.Values{} var resp Quote if arg.FromCoin == "" { @@ -1243,7 +1243,7 @@ func (bi *Binanceus) RequestForQuote(ctx context.Context, arg *RequestQuoteParam params.Set("requestAmount", strconv.FormatFloat(arg.RequestAmount, 'f', 0, 64)) params.Set("requestCoin", arg.RequestCoin) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - return &resp, bi.SendAuthHTTPRequest(ctx, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, otcQuotes, params, spotDefaultRate, &resp) @@ -1251,7 +1251,7 @@ func (bi *Binanceus) RequestForQuote(ctx context.Context, arg *RequestQuoteParam // PlaceOTCTradeOrder to place an order using an acquired quote. // returns OTCTradeOrderResponse response containing the OrderID,OrderStatus, and CreateTime information of an order. -func (bi *Binanceus) PlaceOTCTradeOrder(ctx context.Context, quoteID string) (*OTCTradeOrderResponse, error) { +func (e *Exchange) PlaceOTCTradeOrder(ctx context.Context, quoteID string) (*OTCTradeOrderResponse, error) { params := url.Values{} if strings.Trim(quoteID, " ") == "" { return nil, errMissingQuoteID @@ -1259,14 +1259,14 @@ func (bi *Binanceus) PlaceOTCTradeOrder(ctx context.Context, quoteID string) (*O params.Set("quoteId", quoteID) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response OTCTradeOrderResponse - return &response, bi.SendAuthHTTPRequest(ctx, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, otcTradeOrder, params, spotOrderRate, &response) } // GetOTCTradeOrder returns a single OTC Trade Order instance. -func (bi *Binanceus) GetOTCTradeOrder(ctx context.Context, orderID uint64) (*OTCTradeOrder, error) { +func (e *Exchange) GetOTCTradeOrder(ctx context.Context, orderID uint64) (*OTCTradeOrder, error) { var response OTCTradeOrder params := url.Values{} if orderID <= 0 { @@ -1276,7 +1276,7 @@ func (bi *Binanceus) GetOTCTradeOrder(ctx context.Context, orderID uint64) (*OTC params.Set("orderId", orderIDStr) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) path := otcTradeOrders + orderIDStr - return &response, bi.SendAuthHTTPRequest(ctx, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, path, params, @@ -1284,7 +1284,7 @@ func (bi *Binanceus) GetOTCTradeOrder(ctx context.Context, orderID uint64) (*OTC } // GetAllOTCTradeOrders returns list of OTC Trade Orders -func (bi *Binanceus) GetAllOTCTradeOrders(ctx context.Context, arg *OTCTradeOrderRequestParams) ([]OTCTradeOrder, error) { +func (e *Exchange) GetAllOTCTradeOrders(ctx context.Context, arg *OTCTradeOrderRequestParams) ([]OTCTradeOrder, error) { params := url.Values{} if arg.OrderID != "" { params.Set("orderId", arg.OrderID) @@ -1305,14 +1305,14 @@ func (bi *Binanceus) GetAllOTCTradeOrders(ctx context.Context, arg *OTCTradeOrde params.Set("limit", strconv.Itoa(int(arg.Limit))) } var response []OTCTradeOrder - return response, bi.SendAuthHTTPRequest(ctx, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, otcTradeOrder, params, spotOrderRate, &response) } // GetAllOCBSTradeOrders use this endpoint to query all OCBS orders by condition. -func (bi *Binanceus) GetAllOCBSTradeOrders(ctx context.Context, arg OCBSOrderRequestParams) (*OCBSTradeOrdersResponse, error) { +func (e *Exchange) GetAllOCBSTradeOrders(ctx context.Context, arg OCBSOrderRequestParams) (*OCBSTradeOrdersResponse, error) { var resp OCBSTradeOrdersResponse params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) @@ -1328,7 +1328,7 @@ func (bi *Binanceus) GetAllOCBSTradeOrders(ctx context.Context, arg OCBSOrderReq if arg.Limit > 0 && arg.Limit < 100 { params.Set("limit", strconv.Itoa(int(arg.Limit))) } - return &resp, bi.SendAuthHTTPRequest(ctx, + return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, ocbsTradeOrders, params, spotOrderRate, &resp) @@ -1338,18 +1338,18 @@ func (bi *Binanceus) GetAllOCBSTradeOrders(ctx context.Context, arg OCBSOrderReq // GetAssetFeesAndWalletStatus to fetch the details of all crypto assets, including fees, withdrawal limits and network status. // returns the asset wallet detail as a list. -func (bi *Binanceus) GetAssetFeesAndWalletStatus(ctx context.Context) (AssetWalletList, error) { +func (e *Exchange) GetAssetFeesAndWalletStatus(ctx context.Context) (AssetWalletList, error) { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response AssetWalletList - return response, bi.SendAuthHTTPRequest(ctx, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, assetFeeAndWalletStatus, params, spotDefaultRate, &response) } // WithdrawCrypto method to withdraw crypto -func (bi *Binanceus) WithdrawCrypto(ctx context.Context, arg *withdraw.Request) (string, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, arg *withdraw.Request) (string, error) { params := url.Values{} params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) if arg.Currency.String() == "" { @@ -1375,7 +1375,7 @@ func (bi *Binanceus) WithdrawCrypto(ctx context.Context, arg *withdraw.Request) } params.Set("amount", strconv.FormatFloat(arg.Amount, 'f', 0, 64)) var response WithdrawalResponse - if err := bi.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, applyWithdrawal, params, spotDefaultRate, &response); err != nil { @@ -1386,7 +1386,7 @@ func (bi *Binanceus) WithdrawCrypto(ctx context.Context, arg *withdraw.Request) // WithdrawalHistory gets the status of recent withdrawals // status `param` used as string to prevent default value 0 (for int) interpreting as EmailSent status -func (bi *Binanceus) WithdrawalHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]WithdrawStatusResponse, error) { +func (e *Exchange) WithdrawalHistory(ctx context.Context, c currency.Code, status string, startTime, endTime time.Time, offset, limit int) ([]WithdrawStatusResponse, error) { params := url.Values{} if !c.IsEmpty() { params.Set("coin", c.String()) @@ -1416,7 +1416,7 @@ func (bi *Binanceus) WithdrawalHistory(ctx context.Context, c currency.Code, sta params.Set("limit", strconv.Itoa(limit)) } var withdrawStatus []WithdrawStatusResponse - if err := bi.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, withdrawalHistory, @@ -1430,7 +1430,7 @@ func (bi *Binanceus) WithdrawalHistory(ctx context.Context, c currency.Code, sta // FiatWithdrawalHistory to fetch your fiat (USD) withdrawal history. // returns FiatAssetHistory containing list of fiat asset records. -func (bi *Binanceus) FiatWithdrawalHistory(ctx context.Context, arg *FiatWithdrawalRequestParams) (FiatAssetsHistory, error) { +func (e *Exchange) FiatWithdrawalHistory(ctx context.Context, arg *FiatWithdrawalRequestParams) (FiatAssetsHistory, error) { var response FiatAssetsHistory params := url.Values{} if !(arg.EndTime.IsZero()) && !(arg.EndTime.Before(time.Now())) { @@ -1452,7 +1452,7 @@ func (bi *Binanceus) FiatWithdrawalHistory(ctx context.Context, arg *FiatWithdra params.Set("paymentMethod", arg.PaymentMethod) } params.Set("timestamp", strconv.Itoa(int(time.Now().UnixMilli()))) - return response, bi.SendAuthHTTPRequest(ctx, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, fiatWithdrawalHistory, params, spotDefaultRate, &response) @@ -1460,7 +1460,7 @@ func (bi *Binanceus) FiatWithdrawalHistory(ctx context.Context, arg *FiatWithdra // WithdrawFiat to submit a USD withdraw request via Silvergate Exchange Network (SEN). // returns the Order ID as string -func (bi *Binanceus) WithdrawFiat(ctx context.Context, arg *WithdrawFiatRequestParams) (string, error) { +func (e *Exchange) WithdrawFiat(ctx context.Context, arg *WithdrawFiatRequestParams) (string, error) { params := url.Values{} timestamp := strconv.Itoa(int(time.Now().UnixMilli())) if arg == nil { @@ -1486,7 +1486,7 @@ func (bi *Binanceus) WithdrawFiat(ctx context.Context, arg *WithdrawFiatRequestP OrderID string `json:"orderId"` } var resp response - return resp.OrderID, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, withdrawFiat, params, spotDefaultRate, &resp, ) @@ -1498,7 +1498,7 @@ func (bi *Binanceus) WithdrawFiat(ctx context.Context, arg *WithdrawFiatRequestP */ // GetDepositAddressForCurrency retrieves the wallet address for a given currency -func (bi *Binanceus) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { +func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { params := url.Values{} if currency == "" { return nil, errMissingRequiredArgumentCoin @@ -1510,12 +1510,12 @@ func (bi *Binanceus) GetDepositAddressForCurrency(ctx context.Context, currency, params.Set("recvWindow", "10000") var d DepositAddress return &d, - bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositAddress, params, spotDefaultRate, &d) + e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositAddress, params, spotDefaultRate, &d) } // DepositHistory returns the deposit history based on the supplied params // status `param` used as string to prevent default value 0 (for int) interpreting as EmailSent status -func (bi *Binanceus) DepositHistory(ctx context.Context, c currency.Code, status uint8, startTime, endTime time.Time, offset, limit int) ([]DepositHistory, error) { +func (e *Exchange) DepositHistory(ctx context.Context, c currency.Code, status uint8, startTime, endTime time.Time, offset, limit int) ([]DepositHistory, error) { var response []DepositHistory params := url.Values{} if !c.IsEmpty() { @@ -1546,7 +1546,7 @@ func (bi *Binanceus) DepositHistory(ctx context.Context, c currency.Code, status params.Set("limit", strconv.Itoa(limit)) } - if err := bi.SendAuthHTTPRequest(ctx, + if err := e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, depositHistory, @@ -1560,7 +1560,7 @@ func (bi *Binanceus) DepositHistory(ctx context.Context, c currency.Code, status } // FiatDepositHistory fetch your fiat (USD) deposit history as Fiat Assets History -func (bi *Binanceus) FiatDepositHistory(ctx context.Context, arg *FiatWithdrawalRequestParams) (FiatAssetsHistory, error) { +func (e *Exchange) FiatDepositHistory(ctx context.Context, arg *FiatWithdrawalRequestParams) (FiatAssetsHistory, error) { params := url.Values{} if !(arg.EndTime.IsZero()) && !(arg.EndTime.Before(time.Now())) { params.Set("endTime", strconv.FormatInt(arg.EndTime.UnixMilli(), 10)) @@ -1582,13 +1582,13 @@ func (bi *Binanceus) FiatDepositHistory(ctx context.Context, arg *FiatWithdrawal } params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response FiatAssetsHistory - return response, bi.SendAuthHTTPRequest(ctx, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, fiatDepositHistory, params, spotDefaultRate, &response) } // GetSubAccountDepositAddress retrieves sub-account’s deposit address. -func (bi *Binanceus) GetSubAccountDepositAddress(ctx context.Context, arg SubAccountDepositAddressRequestParams) (*SubAccountDepositAddress, error) { +func (e *Exchange) GetSubAccountDepositAddress(ctx context.Context, arg SubAccountDepositAddressRequestParams) (*SubAccountDepositAddress, error) { params := url.Values{} if !common.MatchesEmailPattern(arg.Email) { return nil, errMissingSubAccountEmail @@ -1598,12 +1598,12 @@ func (bi *Binanceus) GetSubAccountDepositAddress(ctx context.Context, arg SubAcc params.Set("email", arg.Email) params.Set("coin", arg.Coin.String()) var response SubAccountDepositAddress - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subAccountDepositAddress, params, spotDefaultRate, &response) } // GetSubAccountDepositHistory retrieves sub-account deposit history. -func (bi *Binanceus) GetSubAccountDepositHistory(ctx context.Context, email string, coin currency.Code, status int, startTime, endTime time.Time, limit, offset int) ([]SubAccountDepositItem, error) { +func (e *Exchange) GetSubAccountDepositHistory(ctx context.Context, email string, coin currency.Code, status int, startTime, endTime time.Time, limit, offset int) ([]SubAccountDepositItem, error) { params := url.Values{} if !common.MatchesEmailPattern(email) { return nil, errMissingSubAccountEmail @@ -1628,14 +1628,14 @@ func (bi *Binanceus) GetSubAccountDepositHistory(ctx context.Context, email stri params.Set("offset", strconv.Itoa(offset)) } var response []SubAccountDepositItem - return response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, + return response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, subAccountDepositHistory, params, spotDefaultRate, &response) } // Referral Endpoints // GetReferralRewardHistory retrieves the user’s referral reward history. -func (bi *Binanceus) GetReferralRewardHistory(ctx context.Context, userBusinessType, page, rows int) (*ReferralRewardHistoryResponse, error) { +func (e *Exchange) GetReferralRewardHistory(ctx context.Context, userBusinessType, page, rows int) (*ReferralRewardHistoryResponse, error) { params := url.Values{} switch { case userBusinessType != 0 && userBusinessType != 1: @@ -1650,12 +1650,12 @@ func (bi *Binanceus) GetReferralRewardHistory(ctx context.Context, userBusinessT params.Set("rows", strconv.Itoa(rows)) params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) var response ReferralRewardHistoryResponse - return &response, bi.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, referralRewardHistory, params, spotDefaultRate, &response) + return &response, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, referralRewardHistory, params, spotDefaultRate, &response) } // SendHTTPRequest sends an unauthenticated request -func (bi *Binanceus) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { - endpointPath, err := bi.API.Endpoints.GetURL(ePath) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } @@ -1663,23 +1663,23 @@ func (bi *Binanceus) SendHTTPRequest(ctx context.Context, ePath exchange.URL, pa Method: http.MethodGet, Path: endpointPath + path, Result: result, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return bi.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAPIKeyHTTPRequest is a special API request where the api key is // appended to the headers without a secret -func (bi *Binanceus) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { - endpointPath, err := bi.API.Endpoints.GetURL(ePath) +func (e *Exchange) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } - creds, err := bi.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1691,23 +1691,23 @@ func (bi *Binanceus) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.U Path: endpointPath + path, Headers: headers, Result: result, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return bi.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) } // SendAuthHTTPRequest sends an authenticated HTTP request -func (bi *Binanceus) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error { - creds, err := bi.GetCredentials(ctx) +func (e *Exchange) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpointPath, err := bi.API.Endpoints.GetURL(ePath) + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } @@ -1718,7 +1718,7 @@ func (bi *Binanceus) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL params.Set("recvWindow", strconv.FormatInt(defaultRecvWindow.Milliseconds(), 10)) } interim := json.RawMessage{} - err = bi.SendPayload(ctx, f, func() (*request.Item, error) { + err = e.SendPayload(ctx, f, func() (*request.Item, error) { params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) hmacSigned, err := crypto.GetHMAC(crypto.HashSHA256, []byte(params.Encode()), []byte(creds.Secret)) if err != nil { @@ -1732,9 +1732,9 @@ func (bi *Binanceus) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL Path: fullPath, Headers: headers, Result: &interim, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -1760,13 +1760,13 @@ func (bi *Binanceus) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL // Start a new user data websocket. The stream will close after 60 minutes unless a keepalive is sent. // If the account has an active listenKey, // that listenKey will be returned and its validity will be extended for 60 minutes. -func (bi *Binanceus) GetWsAuthStreamKey(ctx context.Context) (string, error) { - endpointPath, err := bi.API.Endpoints.GetURL(exchange.RestSpotSupplementary) +func (e *Exchange) GetWsAuthStreamKey(ctx context.Context) (string, error) { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return "", err } - creds, err := bi.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return "", err } @@ -1779,12 +1779,12 @@ func (bi *Binanceus) GetWsAuthStreamKey(ctx context.Context) (string, error) { Path: endpointPath + userAccountStream, Headers: headers, Result: &resp, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - err = bi.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { + err = e.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) if err != nil { @@ -1798,17 +1798,17 @@ func (bi *Binanceus) GetWsAuthStreamKey(ctx context.Context) (string, error) { // Keepalive a user data stream to prevent a time out. // User data streams will close after 60 minutes. // It's recommended to send a ping about every 30 minutes. -func (bi *Binanceus) MaintainWsAuthStreamKey(ctx context.Context) error { - endpointPath, err := bi.API.Endpoints.GetURL(exchange.RestSpotSupplementary) +func (e *Exchange) MaintainWsAuthStreamKey(ctx context.Context) error { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return err } if listenKey == "" { - listenKey, err = bi.GetWsAuthStreamKey(ctx) + listenKey, err = e.GetWsAuthStreamKey(ctx) return err } - creds, err := bi.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1823,28 +1823,28 @@ func (bi *Binanceus) MaintainWsAuthStreamKey(ctx context.Context) error { Method: http.MethodPut, Path: path, Headers: headers, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return bi.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { + return e.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) } // CloseUserDataStream Close out a user data websocket. -func (bi *Binanceus) CloseUserDataStream(ctx context.Context) error { - endpointPath, err := bi.API.Endpoints.GetURL(exchange.RestSpotSupplementary) +func (e *Exchange) CloseUserDataStream(ctx context.Context) error { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return err } if listenKey == "" { - listenKey, err = bi.GetWsAuthStreamKey(ctx) + listenKey, err = e.GetWsAuthStreamKey(ctx) return err } - creds, err := bi.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1859,12 +1859,12 @@ func (bi *Binanceus) CloseUserDataStream(ctx context.Context) error { Method: http.MethodDelete, Path: path, Headers: headers, - Verbose: bi.Verbose, - HTTPDebugging: bi.HTTPDebugging, - HTTPRecording: bi.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return bi.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { + return e.SendPayload(ctx, spotDefaultRate, func() (*request.Item, error) { return item, nil }, request.AuthenticatedRequest) } diff --git a/exchanges/binanceus/binanceus_test.go b/exchanges/binanceus/binanceus_test.go index 739c5a7b883..6ddd8b0601d 100644 --- a/exchanges/binanceus/binanceus_test.go +++ b/exchanges/binanceus/binanceus_test.go @@ -31,46 +31,46 @@ const ( ) var ( - bi *Binanceus + e = &Exchange{} testPairMapping = currency.NewBTCUSDT() // this lock guards against orderbook tests race binanceusOrderBookLock = &sync.Mutex{} ) func TestMain(m *testing.M) { - bi = new(Binanceus) - if err := testexch.Setup(bi); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Binanceus Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - bi.API.AuthenticatedSupport = true - bi.API.AuthenticatedWebsocketSupport = true - bi.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } - bi.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit os.Exit(m.Run()) } func TestServerTime(t *testing.T) { t.Parallel() - if _, er := bi.GetServerTime(t.Context(), asset.Spot); er != nil { + if _, er := e.GetServerTime(t.Context(), asset.Spot); er != nil { t.Error("Binanceus SystemTime() error", er) } } func TestServerStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetSystemStatus(t.Context()); er != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetSystemStatus(t.Context()); er != nil { t.Error("Binanceus GetSystemStatus() error", er) } } func TestGetExchangeInfo(t *testing.T) { t.Parallel() - _, err := bi.GetExchangeInfo(t.Context()) + _, err := e.GetExchangeInfo(t.Context()) if err != nil { t.Error("Binanceus GetExchangeInfo() error", err) } @@ -78,7 +78,7 @@ func TestGetExchangeInfo(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - r, err := bi.UpdateTicker(t.Context(), testPairMapping, asset.Spot) + r, err := e.UpdateTicker(t.Context(), testPairMapping, asset.Spot) if err != nil { t.Error(err) } @@ -89,7 +89,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := bi.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) if err != nil { t.Error(err) } @@ -97,7 +97,7 @@ func TestUpdateTickers(t *testing.T) { func TestUpdateOrderBook(t *testing.T) { t.Parallel() - _, er := bi.UpdateOrderbook(t.Context(), testPairMapping, asset.Spot) + _, er := e.UpdateOrderbook(t.Context(), testPairMapping, asset.Spot) if er != nil { t.Error("Binanceus UpdateOrderBook() error", er) } @@ -105,8 +105,8 @@ func TestUpdateOrderBook(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err := bi.FetchTradablePairs(t.Context(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Error("Binanceus FetchTradablePairs() error", err) } @@ -114,7 +114,7 @@ func TestFetchTradablePairs(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - err := bi.UpdateTradablePairs(t.Context(), false) + err := e.UpdateTradablePairs(t.Context(), false) if err != nil { t.Error("Binanceus UpdateTradablePairs() error", err) } @@ -122,8 +122,8 @@ func TestUpdateTradablePairs(t *testing.T) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err := bi.UpdateAccountInfo(t.Context(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err != nil { t.Error("Binanceus UpdateAccountInfo() error", err) } @@ -132,7 +132,7 @@ func TestUpdateAccountInfo(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() pair := currency.Pair{Base: currency.BTC, Quote: currency.USD} - _, err := bi.GetRecentTrades(t.Context(), pair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), pair, asset.Spot) if err != nil { t.Error("Binanceus GetRecentTrades() error", err) } @@ -141,7 +141,7 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() pair := currency.Pair{Base: currency.BTC, Quote: currency.USD} - _, err := bi.GetHistoricTrades(t.Context(), pair, asset.Spot, time.Time{}, time.Time{}) + _, err := e.GetHistoricTrades(t.Context(), pair, asset.Spot, time.Time{}, time.Time{}) if err != nil { t.Error("Binanceus GetHistoricTrades() error", err) } @@ -149,15 +149,15 @@ func TestGetHistoricTrades(t *testing.T) { func TestGetFeeByType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetFeeByType(t.Context(), &exchange.FeeBuilder{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetFeeByType(t.Context(), &exchange.FeeBuilder{ IsMaker: true, Pair: currency.NewPair(currency.USD, currency.BTC), FeeType: exchange.CryptocurrencyTradeFee, }); er != nil { t.Error("Binanceus GetFeeByType() error", er) } - if _, er := bi.GetFeeByType(t.Context(), &exchange.FeeBuilder{ + if _, er := e.GetFeeByType(t.Context(), &exchange.FeeBuilder{ IsMaker: true, Pair: currency.NewPair(currency.USD, currency.BTC), FeeType: exchange.CryptocurrencyWithdrawalFee, @@ -168,7 +168,7 @@ func TestGetFeeByType(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ Pair: currency.Pair{ Base: currency.XRP, @@ -180,17 +180,17 @@ func TestSubmitOrder(t *testing.T) { Price: 1000, Amount: 20, ClientID: "binanceSamOrder", - Exchange: bi.Name, + Exchange: e.Name, } - response, err := bi.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) switch { - case sharedtestvalues.AreAPICredentialsSet(bi) && err != nil && strings.Contains(err.Error(), "{\"code\":-1013,\"msg\":\"Market is closed.\""): + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil && strings.Contains(err.Error(), "{\"code\":-1013,\"msg\":\"Market is closed.\""): t.Skip("Binanceus SubmitOrder() Market is Closed") - case sharedtestvalues.AreAPICredentialsSet(bi) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Binanceus SubmitOrder() Could not place order: %v", err) - case sharedtestvalues.AreAPICredentialsSet(bi) && response.Status != order.Filled: + case sharedtestvalues.AreAPICredentialsSet(e) && response.Status != order.Filled: t.Error("Binanceus SubmitOrder() Order not placed") - case !sharedtestvalues.AreAPICredentialsSet(bi) && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil: t.Error("Binanceus SubmitOrder() Expecting an error when no keys are set") } } @@ -199,50 +199,50 @@ func TestCancelOrder(t *testing.T) { t.Parallel() pair := currency.NewBTCUSD() - err := bi.CancelOrder(t.Context(), &order.Cancel{ + err := e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.Spot, OrderID: "1337", }) require.ErrorIs(t, err, errMissingCurrencySymbol) - err = bi.CancelOrder(t.Context(), &order.Cancel{ + err = e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.Futures, OrderID: "69", Pair: pair, }) require.ErrorIs(t, err, asset.ErrNotSupported) - err = bi.CancelOrder(t.Context(), &order.Cancel{ + err = e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.Spot, OrderID: "", Pair: pair, }) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) cancellationOrder := &order.Cancel{ OrderID: "1", Pair: pair, AssetType: asset.Spot, } - err = bi.CancelOrder(t.Context(), cancellationOrder) + err = e.CancelOrder(t.Context(), cancellationOrder) assert.ErrorContains(t, err, "Unknown order sent.") } func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ Pair: currency.NewPair(currency.LTC, currency.BTC), AssetType: asset.Spot, } - if _, err := bi.CancelAllOrders(t.Context(), orderCancellation); err != nil { + if _, err := e.CancelAllOrders(t.Context(), orderCancellation); err != nil { t.Error("Binanceus CancelAllOrders() error", err) } } func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - tradablePairs, err := bi.FetchTradablePairs(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + tradablePairs, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Error(err) @@ -250,7 +250,7 @@ func TestGetOrderInfo(t *testing.T) { if len(tradablePairs) == 0 { t.Fatal("Binanceus GetOrderInfo() no tradable pairs") } - _, err = bi.GetOrderInfo(t.Context(), + _, err = e.GetOrderInfo(t.Context(), "123", tradablePairs[0], asset.Spot) @@ -261,29 +261,29 @@ func TestGetOrderInfo(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := bi.GetDepositAddress(t.Context(), currency.EMPTYCODE, "", currency.BNB.String()) + _, err := e.GetDepositAddress(t.Context(), currency.EMPTYCODE, "", currency.BNB.String()) assert.ErrorIs(t, err, errMissingRequiredArgumentCoin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err = bi.GetDepositAddress(t.Context(), currency.USDT, "", currency.BNB.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetDepositAddress(t.Context(), currency.USDT, "", currency.BNB.String()) assert.NoError(t, err) } func TestGetWithdrawalHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, bi, canManipulateRealOrders) - _, err := bi.GetWithdrawalsHistory(t.Context(), currency.ETH, asset.Spot) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.ETH, asset.Spot) switch { - case sharedtestvalues.AreAPICredentialsSet(bi) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("Binanceus GetWithdrawalsHistory() error", err) - case !sharedtestvalues.AreAPICredentialsSet(bi) && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil: t.Error("Binanceus GetWithdrawalsHistory() expecting an error when no keys are set") } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - if _, er := bi.WithdrawFiat(t.Context(), &WithdrawFiatRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, er := e.WithdrawFiat(t.Context(), &WithdrawFiatRequestParams{ PaymentChannel: "SILVERGATE", PaymentAccount: "myaccount", PaymentMethod: "SEN", @@ -295,13 +295,13 @@ func TestWithdrawFiat(t *testing.T) { func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, } - _, err := bi.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) if err != nil { t.Error("Binanceus GetActiveOrders() error", err) } @@ -309,9 +309,9 @@ func TestGetActiveOrders(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: bi.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -320,14 +320,14 @@ func TestWithdraw(t *testing.T) { Chain: "BSC", }, } - _, err := bi.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) if err != nil && !strings.EqualFold(errAmountValueMustBeGreaterThan0.Error(), err.Error()) { t.Errorf("Binanceus Withdraw() expecting %v, but found %v", errAmountValueMustBeGreaterThan0, err) - } else if !sharedtestvalues.AreAPICredentialsSet(bi) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Binanceus Withdraw() expecting an error when no keys are set") } withdrawCryptoRequest.Amount = 1 - _, err = bi.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) + _, err = e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) if err != nil && !strings.Contains(err.Error(), "You are not authorized to execute this request.") { t.Error("Binanceus WithdrawCryptocurrencyFunds() error", err) } @@ -335,14 +335,14 @@ func TestWithdraw(t *testing.T) { func TestGetFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) feeBuilder := &exchange.FeeBuilder{ Amount: 1, FeeType: exchange.CryptocurrencyTradeFee, Pair: currency.NewPair(currency.BTC, currency.LTC), PurchasePrice: 1, } - _, er := bi.GetFeeByType(t.Context(), feeBuilder) + _, er := e.GetFeeByType(t.Context(), feeBuilder) if er != nil { t.Fatal("Binanceus GetFeeByType() error", er) } @@ -352,7 +352,7 @@ func TestGetFee(t *testing.T) { Pair: currency.NewPair(currency.BTC, currency.LTC), PurchasePrice: 1, } - _, er = bi.GetFeeByType(t.Context(), withdrawalFeeBuilder) + _, er = e.GetFeeByType(t.Context(), withdrawalFeeBuilder) if er != nil { t.Fatal("Binanceus GetFeeByType() error", er) } @@ -362,7 +362,7 @@ func TestGetFee(t *testing.T) { Pair: currency.NewPair(currency.BTC, currency.LTC), PurchasePrice: 1, } - _, er = bi.GetFeeByType(t.Context(), offlineFeeTradeBuilder) + _, er = e.GetFeeByType(t.Context(), offlineFeeTradeBuilder) if er != nil { t.Fatal("Binanceus GetFeeByType() error", er) } @@ -374,10 +374,10 @@ func TestGetHistoricCandles(t *testing.T) { startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC) endTime := time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC) - _, err := bi.GetHistoricCandles(t.Context(), pair, asset.Spot, kline.Interval(time.Hour*5), startTime, endTime) + _, err := e.GetHistoricCandles(t.Context(), pair, asset.Spot, kline.Interval(time.Hour*5), startTime, endTime) require.ErrorIs(t, err, kline.ErrRequestExceedsExchangeLimits) - _, err = bi.GetHistoricCandles(t.Context(), pair, asset.Spot, kline.OneDay, startTime, endTime) + _, err = e.GetHistoricCandles(t.Context(), pair, asset.Spot, kline.OneDay, startTime, endTime) if err != nil { t.Error("Binanceus GetHistoricCandles() error", err) } @@ -389,7 +389,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC) endTime := time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC) - _, err := bi.GetHistoricCandlesExtended(t.Context(), pair, asset.Spot, kline.OneDay, startTime, endTime) + _, err := e.GetHistoricCandlesExtended(t.Context(), pair, asset.Spot, kline.OneDay, startTime, endTime) if err != nil { t.Fatal(err) } @@ -397,7 +397,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime = time.Now().Add(-time.Hour * 30) endTime = time.Now() - _, err = bi.GetHistoricCandlesExtended(t.Context(), pair, asset.Spot, kline.FourHour, startTime, endTime) + _, err = e.GetHistoricCandlesExtended(t.Context(), pair, asset.Spot, kline.FourHour, startTime, endTime) if err != nil { t.Error("Binanceus GetHistoricCandlesExtended() error", err) } @@ -408,7 +408,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { // TestGetMostRecentTrades -- test most recent trades end-point func TestGetMostRecentTrades(t *testing.T) { t.Parallel() - _, err := bi.GetMostRecentTrades(t.Context(), RecentTradeRequestParams{ + _, err := e.GetMostRecentTrades(t.Context(), RecentTradeRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 15, }) @@ -419,8 +419,8 @@ func TestGetMostRecentTrades(t *testing.T) { func TestGetHistoricalTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err := bi.GetHistoricalTrades(t.Context(), HistoricalTradeParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetHistoricalTrades(t.Context(), HistoricalTradeParams{ Symbol: "BTCUSDT", Limit: 5, FromID: 0, @@ -432,7 +432,7 @@ func TestGetHistoricalTrades(t *testing.T) { func TestGetAggregateTrades(t *testing.T) { t.Parallel() - _, err := bi.GetAggregateTrades(t.Context(), + _, err := e.GetAggregateTrades(t.Context(), &AggregatedTradeRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 5, @@ -444,7 +444,7 @@ func TestGetAggregateTrades(t *testing.T) { func TestGetOrderBookDepth(t *testing.T) { t.Parallel() - _, er := bi.GetOrderBookDepth(t.Context(), &OrderBookDataRequestParams{ + _, er := e.GetOrderBookDepth(t.Context(), &OrderBookDataRequestParams{ Symbol: currency.NewBTCUSDT(), Limit: 1000, }) @@ -455,7 +455,7 @@ func TestGetOrderBookDepth(t *testing.T) { func TestGetCandlestickData(t *testing.T) { t.Parallel() - _, er := bi.GetSpotKline(t.Context(), &KlinesRequestParams{ + _, er := e.GetSpotKline(t.Context(), &KlinesRequestParams{ Symbol: currency.NewBTCUSDT(), Interval: kline.FiveMin.Short(), Limit: 24, @@ -469,7 +469,7 @@ func TestGetCandlestickData(t *testing.T) { func TestGetPriceDatas(t *testing.T) { t.Parallel() - _, er := bi.GetPriceDatas(t.Context()) + _, er := e.GetPriceDatas(t.Context()) if er != nil { t.Error("Binanceus GetPriceDatas() error", er) } @@ -477,7 +477,7 @@ func TestGetPriceDatas(t *testing.T) { func TestGetSinglePriceData(t *testing.T) { t.Parallel() - _, er := bi.GetSinglePriceData(t.Context(), currency.Pair{ + _, er := e.GetSinglePriceData(t.Context(), currency.Pair{ Base: currency.BTC, Quote: currency.USDT, }) @@ -488,7 +488,7 @@ func TestGetSinglePriceData(t *testing.T) { func TestGetAveragePrice(t *testing.T) { t.Parallel() - _, err := bi.GetAveragePrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetAveragePrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetAveragePrice() error", err) } @@ -496,7 +496,7 @@ func TestGetAveragePrice(t *testing.T) { func TestGetBestPrice(t *testing.T) { t.Parallel() - _, err := bi.GetBestPrice(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetBestPrice(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binanceus GetBestPrice() error", err) } @@ -504,7 +504,7 @@ func TestGetBestPrice(t *testing.T) { func TestGetPriceChangeStats(t *testing.T) { t.Parallel() - _, err := bi.GetPriceChangeStats(t.Context(), currency.NewBTCUSDT()) + _, err := e.GetPriceChangeStats(t.Context(), currency.NewBTCUSDT()) if err != nil { t.Error("Binance GetPriceChangeStats() error", err) } @@ -512,7 +512,7 @@ func TestGetPriceChangeStats(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - _, err := bi.GetTickers(t.Context()) + _, err := e.GetTickers(t.Context()) if err != nil { t.Error("Binance TestGetTickers error", err) } @@ -520,8 +520,8 @@ func TestGetTickers(t *testing.T) { func TestGetAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetAccount(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetAccount(t.Context()) if er != nil { t.Error("Binanceus GetAccount() error", er) } @@ -529,8 +529,8 @@ func TestGetAccount(t *testing.T) { func TestGetUserAccountStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetUserAccountStatus(t.Context(), 3000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetUserAccountStatus(t.Context(), 3000) if er != nil { t.Error("Binanceus GetUserAccountStatus() error", er) } @@ -538,8 +538,8 @@ func TestGetUserAccountStatus(t *testing.T) { func TestGetUserAPITradingStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetUserAPITradingStatus(t.Context(), 3000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetUserAPITradingStatus(t.Context(), 3000) if er != nil { t.Error("Binanceus GetUserAPITradingStatus() error", er) } @@ -547,8 +547,8 @@ func TestGetUserAPITradingStatus(t *testing.T) { func TestGetTradeFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetTradeFee(t.Context(), 3000, "BTC-USDT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetTradeFee(t.Context(), 3000, "BTC-USDT") if er != nil { t.Error("Binanceus GetTradeFee() error", er) } @@ -556,8 +556,8 @@ func TestGetTradeFee(t *testing.T) { func TestGetAssetDistributionHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetAssetDistributionHistory(t.Context(), "", 0, 0, 3000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetAssetDistributionHistory(t.Context(), "", 0, 0, 3000) if er != nil { t.Error("Binanceus GetAssetDistributionHistory() error", er) } @@ -565,34 +565,34 @@ func TestGetAssetDistributionHistory(t *testing.T) { func TestGetMasterAccountTotalUSDValue(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetMasterAccountTotalUSDValue(t.Context(), "", 0, 0); er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetMasterAccountTotalUSDValue(t.Context(), "", 0, 0); er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") { t.Errorf("Binanceus GetMasterAccountTotalUSDValue() expecting %s, but found %v", "Sub-account function is not enabled.", er) } } func TestGetSubaccountStatusList(t *testing.T) { t.Parallel() - _, err := bi.GetSubaccountStatusList(t.Context(), "") + _, err := e.GetSubaccountStatusList(t.Context(), "") assert.ErrorIs(t, err, errMissingSubAccountEmail) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err = bi.GetSubaccountStatusList(t.Context(), "someone@thrasher.corp") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetSubaccountStatusList(t.Context(), "someone@thrasher.corp") assert.ErrorContains(t, err, "Sub-account function is not enabled.") } func TestGetSubAccountDepositAddress(t *testing.T) { t.Parallel() - _, err := bi.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{}) + _, err := e.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{}) assert.ErrorIs(t, err, errMissingSubAccountEmail) - _, err = bi.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{ + _, err = e.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{ Email: "someone@thrasher.io", }) assert.ErrorIs(t, err, errMissingCurrencyCoin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = bi.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{ + _, err = e.GetSubAccountDepositAddress(t.Context(), SubAccountDepositAddressRequestParams{ Email: "someone@thrasher.io", Coin: currency.BTC, }) @@ -616,12 +616,12 @@ func TestGetSubAccountDepositHistory(t *testing.T) { t.Parallel() var resp SubAccountDepositItem require.NoError(t, json.Unmarshal([]byte(subAccountDepositHistoryItemJSON), &resp)) - _, err := bi.GetSubAccountDepositHistory(t.Context(), "", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0) + _, err := e.GetSubAccountDepositHistory(t.Context(), "", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0) assert.ErrorIs(t, err, errMissingSubAccountEmail) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = bi.GetSubAccountDepositHistory(t.Context(), "someone@thrasher.io", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0) + _, err = e.GetSubAccountDepositHistory(t.Context(), "someone@thrasher.io", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0) assert.ErrorContains(t, err, "This parent sub have no relation") } @@ -640,8 +640,8 @@ func TestGetSubaccountInformation(t *testing.T) { if er := json.Unmarshal([]byte(subaccountItemJSON), &resp); er != nil { t.Error("Binanceus decerializing to SubAccount error", er) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetSubaccountInformation(t.Context(), 1, 100, "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetSubaccountInformation(t.Context(), 1, 100, "", "") if er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") { t.Error("Binanceus GetSubaccountInformation() error", er) } @@ -663,36 +663,36 @@ func TestGetReferralRewardHistory(t *testing.T) { t.Parallel() var resp ReferralRewardHistoryResponse require.NoError(t, json.Unmarshal([]byte(referalRewardHistoryResponse), &resp)) - _, err := bi.GetReferralRewardHistory(t.Context(), 9, 5, 50) + _, err := e.GetReferralRewardHistory(t.Context(), 9, 5, 50) assert.ErrorIs(t, err, errInvalidUserBusinessType) - _, err = bi.GetReferralRewardHistory(t.Context(), 1, 0, 50) + _, err = e.GetReferralRewardHistory(t.Context(), 1, 0, 50) assert.ErrorIs(t, err, errMissingPageNumber) - _, err = bi.GetReferralRewardHistory(t.Context(), 1, 5, 0) + _, err = e.GetReferralRewardHistory(t.Context(), 1, 5, 0) assert.ErrorIs(t, err, errInvalidRowNumber) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err = bi.GetReferralRewardHistory(t.Context(), 1, 5, 50) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetReferralRewardHistory(t.Context(), 1, 5, 50) assert.NoError(t, err) } func TestGetSubaccountTransferHistory(t *testing.T) { t.Parallel() - _, err := bi.GetSubaccountTransferHistory(t.Context(), "", 0, 0, 0, 0) + _, err := e.GetSubaccountTransferHistory(t.Context(), "", 0, 0, 0, 0) assert.ErrorIs(t, err, errNotValidEmailAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = bi.GetSubaccountTransferHistory(t.Context(), "example@golang.org", 0, 0, 0, 0) + _, err = e.GetSubaccountTransferHistory(t.Context(), "example@golang.org", 0, 0, 0, 0) assert.Error(t, err, "GetSubaccountTransferHistory should return an error on a bogus email") } func TestExecuteSubAccountTransfer(t *testing.T) { t.Parallel() - _, err := bi.ExecuteSubAccountTransfer(t.Context(), &SubAccountTransferRequestParams{}) + _, err := e.ExecuteSubAccountTransfer(t.Context(), &SubAccountTransferRequestParams{}) assert.ErrorIs(t, err, errUnacceptableSenderEmail) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, err = bi.ExecuteSubAccountTransfer(t.Context(), &SubAccountTransferRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.ExecuteSubAccountTransfer(t.Context(), &SubAccountTransferRequestParams{ FromEmail: "fromemail@thrasher.io", ToEmail: "toemail@thrasher.io", Asset: "BTC", @@ -703,17 +703,17 @@ func TestExecuteSubAccountTransfer(t *testing.T) { func TestGetSubaccountAssets(t *testing.T) { t.Parallel() - _, err := bi.GetSubaccountAssets(t.Context(), "") + _, err := e.GetSubaccountAssets(t.Context(), "") assert.ErrorIs(t, err, errNotValidEmailAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err = bi.GetSubaccountAssets(t.Context(), "subaccount@thrasher.io") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetSubaccountAssets(t.Context(), "subaccount@thrasher.io") assert.ErrorContains(t, err, "This account does not exist.") } func TestGetOrderRateLimits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetOrderRateLimits(t.Context(), 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetOrderRateLimits(t.Context(), 0) if er != nil { t.Error("Binanceus GetOrderRateLimits() error", er) } @@ -741,7 +741,7 @@ func TestNewOrderTest(t *testing.T) { if er := json.Unmarshal([]byte(testNewOrderResponseJSON), &resp); er != nil { t.Error("Binanceus decerializing to Order error", er) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req := &NewOrderRequest{ Symbol: currency.NewPair(currency.LTC, currency.BTC), Side: order.Buy.String(), @@ -750,7 +750,7 @@ func TestNewOrderTest(t *testing.T) { Quantity: 100000, TimeInForce: order.GoodTillCancel.String(), } - _, err := bi.NewOrderTest(t.Context(), req) + _, err := e.NewOrderTest(t.Context(), req) if err != nil { t.Error("Binanceus NewOrderTest() error", err) } @@ -761,7 +761,7 @@ func TestNewOrderTest(t *testing.T) { Price: 0.0045, QuoteOrderQty: 10, } - _, err = bi.NewOrderTest(t.Context(), req) + _, err = e.NewOrderTest(t.Context(), req) if err != nil { t.Error("NewOrderTest() error", err) } @@ -769,7 +769,7 @@ func TestNewOrderTest(t *testing.T) { func TestNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req := &NewOrderRequest{ Symbol: currency.NewPair(currency.LTC, currency.BTC), Side: order.Buy.String(), @@ -778,17 +778,17 @@ func TestNewOrder(t *testing.T) { Quantity: 100000, TimeInForce: order.GoodTillCancel.String(), } - if _, err := bi.NewOrder(t.Context(), req); err != nil && !strings.Contains(err.Error(), "Account has insufficient balance for requested action") { + if _, err := e.NewOrder(t.Context(), req); err != nil && !strings.Contains(err.Error(), "Account has insufficient balance for requested action") { t.Error("Binanceus NewOrder() error", err) } } func TestGetOrder(t *testing.T) { t.Parallel() - _, err := bi.GetOrder(t.Context(), &OrderRequestParams{}) + _, err := e.GetOrder(t.Context(), &OrderRequestParams{}) assert.ErrorIs(t, err, errIncompleteArguments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, err = bi.GetOrder(t.Context(), &OrderRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetOrder(t.Context(), &OrderRequestParams{ Symbol: "BTCUSDT", OrigClientOrderID: "something", }) @@ -823,9 +823,9 @@ func TestGetAllOpenOrders(t *testing.T) { if er := json.Unmarshal([]byte(openOrdersItemJSON), &resp); er != nil { t.Error("Binanceus decerializing to Order error", er) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, er := bi.GetAllOpenOrders(t.Context(), "") + _, er := e.GetAllOpenOrders(t.Context(), "") if er != nil { t.Error("Binanceus GetAllOpenOrders() error", er) } @@ -834,16 +834,16 @@ func TestGetAllOpenOrders(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Parallel() - _, err := bi.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{}) + _, err := e.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{}) assert.ErrorIs(t, err, errMissingCurrencySymbol) - _, err = bi.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{ + _, err = e.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{ Symbol: currency.NewBTCUSDT(), }) assert.ErrorIs(t, err, errEitherOrderIDOrClientOrderIDIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, err = bi.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.CancelExistingOrder(t.Context(), &CancelOrderRequestParams{ Symbol: currency.NewBTCUSDT(), ClientSuppliedOrderID: "1234", }) @@ -852,12 +852,12 @@ func TestCancelExistingOrder(t *testing.T) { func TestCancelOpenOrdersForSymbol(t *testing.T) { t.Parallel() - _, err := bi.CancelOpenOrdersForSymbol(t.Context(), "") + _, err := e.CancelOpenOrdersForSymbol(t.Context(), "") assert.ErrorIs(t, err, errMissingCurrencySymbol) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = bi.CancelOpenOrdersForSymbol(t.Context(), "BTCUSDT") + _, err = e.CancelOpenOrdersForSymbol(t.Context(), "BTCUSDT") assert.NoError(t, err) } @@ -865,18 +865,18 @@ func TestCancelOpenOrdersForSymbol(t *testing.T) { // trades attached with this account. func TestGetTrades(t *testing.T) { t.Parallel() - _, err := bi.GetTrades(t.Context(), &GetTradesParams{}) + _, err := e.GetTrades(t.Context(), &GetTradesParams{}) assert.ErrorIs(t, err, errIncompleteArguments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = bi.GetTrades(t.Context(), &GetTradesParams{Symbol: "BTCUSDT"}) + _, err = e.GetTrades(t.Context(), &GetTradesParams{Symbol: "BTCUSDT"}) assert.NoError(t, err) } func TestCreateNewOCOOrder(t *testing.T) { t.Parallel() - _, err := bi.CreateNewOCOOrder(t.Context(), + _, err := e.CreateNewOCOOrder(t.Context(), &OCOOrderInputParams{ StopPrice: 1000, Side: order.Buy.String(), @@ -885,9 +885,9 @@ func TestCreateNewOCOOrder(t *testing.T) { }) assert.ErrorIs(t, err, errIncompleteArguments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = bi.CreateNewOCOOrder(t.Context(), + _, err = e.CreateNewOCOOrder(t.Context(), &OCOOrderInputParams{ Symbol: "XTZUSD", Price: 100, @@ -927,12 +927,12 @@ func TestGetOCOOrder(t *testing.T) { t.Parallel() var resp OCOOrderResponse require.NoError(t, json.Unmarshal([]byte(ocoOrderJSON), &resp)) - _, err := bi.GetOCOOrder(t.Context(), &GetOCOOrderRequestParams{}) + _, err := e.GetOCOOrder(t.Context(), &GetOCOOrderRequestParams{}) assert.ErrorIs(t, err, errIncompleteArguments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = bi.GetOCOOrder(t.Context(), &GetOCOOrderRequestParams{ + _, err = e.GetOCOOrder(t.Context(), &GetOCOOrderRequestParams{ OrderListID: "123445", }) assert.ErrorContains(t, err, "Order list does not exist.") @@ -940,8 +940,8 @@ func TestGetOCOOrder(t *testing.T) { func TestGetAllOCOOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetAllOCOOrder(t.Context(), &OCOOrdersRequestParams{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetAllOCOOrder(t.Context(), &OCOOrdersRequestParams{}) if er != nil { t.Error("Binanceus GetAllOCOOrder() error", er) } @@ -949,8 +949,8 @@ func TestGetAllOCOOrder(t *testing.T) { func TestGetOpenOCOOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetOpenOCOOrders(t.Context(), 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetOpenOCOOrders(t.Context(), 0) if er != nil { t.Error("Binanceus GetOpenOCOOrders() error", er) } @@ -958,10 +958,10 @@ func TestGetOpenOCOOrders(t *testing.T) { func TestCancelOCOOrder(t *testing.T) { t.Parallel() - _, err := bi.CancelOCOOrder(t.Context(), &OCOOrdersDeleteRequestParams{}) + _, err := e.CancelOCOOrder(t.Context(), &OCOOrdersDeleteRequestParams{}) assert.ErrorIs(t, err, errIncompleteArguments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, err = bi.CancelOCOOrder(t.Context(), &OCOOrdersDeleteRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.CancelOCOOrder(t.Context(), &OCOOrdersDeleteRequestParams{ Symbol: "BTCUSDT", OrderListID: 123456, }) @@ -971,8 +971,8 @@ func TestCancelOCOOrder(t *testing.T) { // OTC end Points test code. func TestGetSupportedCoinPairs(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetSupportedCoinPairs(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetSupportedCoinPairs(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT}) if er != nil { t.Error("Binanceus GetSupportedCoinPairs() error", er) } @@ -980,18 +980,18 @@ func TestGetSupportedCoinPairs(t *testing.T) { func TestRequestForQuote(t *testing.T) { t.Parallel() - _, err := bi.RequestForQuote(t.Context(), &RequestQuoteParams{ToCoin: "BTC", RequestCoin: "USDT", RequestAmount: 1}) + _, err := e.RequestForQuote(t.Context(), &RequestQuoteParams{ToCoin: "BTC", RequestCoin: "USDT", RequestAmount: 1}) assert.ErrorIs(t, err, errMissingFromCoinName) - _, err = bi.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", RequestCoin: "USDT", RequestAmount: 1}) + _, err = e.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", RequestCoin: "USDT", RequestAmount: 1}) assert.ErrorIs(t, err, errMissingToCoinName) - _, err = bi.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestCoin: "USDT"}) + _, err = e.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestCoin: "USDT"}) assert.ErrorIs(t, err, errMissingRequestAmount) - _, err = bi.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestAmount: 1}) + _, err = e.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestAmount: 1}) assert.ErrorIs(t, err, errMissingRequestCoin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = bi.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "BTC", ToCoin: "USDT", RequestCoin: "BTC", RequestAmount: 1}) + _, err = e.RequestForQuote(t.Context(), &RequestQuoteParams{FromCoin: "BTC", ToCoin: "USDT", RequestCoin: "BTC", RequestAmount: 1}) assert.NoError(t, err) } @@ -1005,10 +1005,10 @@ func TestPlaceOTCTradeOrder(t *testing.T) { t.Parallel() var resp OTCTradeOrderResponse require.NoError(t, json.Unmarshal([]byte(testPlaceOTCTradeOrderJSON), &resp)) - _, err := bi.PlaceOTCTradeOrder(t.Context(), "") + _, err := e.PlaceOTCTradeOrder(t.Context(), "") assert.ErrorIs(t, err, errMissingQuoteID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, err = bi.PlaceOTCTradeOrder(t.Context(), "15848701022") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.PlaceOTCTradeOrder(t.Context(), "15848701022") assert.ErrorContains(t, err, "-9000") } @@ -1027,13 +1027,13 @@ var testGetOTCTradeOrderJSON = `{ func TestGetOTCTradeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) var val OTCTradeOrder er := json.Unmarshal([]byte(testGetOTCTradeOrderJSON), &val) if er != nil { t.Error("Binanceus JSON GetOTCTradeOrder() error", er) } - _, er = bi.GetOTCTradeOrder(t.Context(), 10002349) + _, er = e.GetOTCTradeOrder(t.Context(), 10002349) if er != nil && !strings.Contains(er.Error(), "status code: 400") { t.Error("Binanceus GetOTCTradeOrder() error ", er) } @@ -1069,13 +1069,13 @@ var getAllOTCTradeOrders = `[ func TestGetAllOTCTradeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) var orders []OTCTradeOrder er := json.Unmarshal([]byte(getAllOTCTradeOrders), &orders) if er != nil { t.Error(er) } - _, er = bi.GetAllOTCTradeOrders(t.Context(), &OTCTradeOrderRequestParams{}) + _, er = e.GetAllOTCTradeOrders(t.Context(), &OTCTradeOrderRequestParams{}) if er != nil { t.Error("Binanceus GetAllOTCTradeOrders() error", er) } @@ -1102,16 +1102,16 @@ func TestGetAllOCBSTradeOrders(t *testing.T) { if er := json.Unmarshal([]byte(ocbsTradeOrderJSON), &orderDetail); er != nil { t.Error("Binanceus decerializing to OCBSOrder error", er) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetAllOCBSTradeOrders(t.Context(), OCBSOrderRequestParams{}); er != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetAllOCBSTradeOrders(t.Context(), OCBSOrderRequestParams{}); er != nil { t.Error("Binanceus GetAllOCBSTradeOrders() error", er) } } func TestGetAssetFeesAndWalletStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetAssetFeesAndWalletStatus(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetAssetFeesAndWalletStatus(t.Context()) if er != nil { t.Error("Binanceus GetAssetFeesAndWalletStatus() error", er) } @@ -1120,9 +1120,9 @@ func TestGetAssetFeesAndWalletStatus(t *testing.T) { func TestWithdrawCrypto(t *testing.T) { t.Parallel() - _, err := bi.WithdrawCrypto(t.Context(), &withdraw.Request{}) + _, err := e.WithdrawCrypto(t.Context(), &withdraw.Request{}) assert.ErrorIs(t, err, errMissingRequiredArgumentCoin) - _, err = bi.WithdrawCrypto(t.Context(), &withdraw.Request{ + _, err = e.WithdrawCrypto(t.Context(), &withdraw.Request{ Currency: currency.BTC, }) assert.ErrorIs(t, err, errMissingRequiredArgumentNetwork) @@ -1132,32 +1132,32 @@ func TestWithdrawCrypto(t *testing.T) { Chain: "BSC", }, } - _, err = bi.WithdrawCrypto(t.Context(), params) + _, err = e.WithdrawCrypto(t.Context(), params) assert.ErrorIs(t, err, errMissingRequiredParameterAddress) params.Crypto.Address = "1234567" - _, err = bi.WithdrawCrypto(t.Context(), params) + _, err = e.WithdrawCrypto(t.Context(), params) assert.ErrorIs(t, err, errAmountValueMustBeGreaterThan0) params.Amount = 1 - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, err = bi.WithdrawCrypto(t.Context(), params) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.WithdrawCrypto(t.Context(), params) assert.ErrorContains(t, err, "You are not authorized to execute this request.") } func TestFiatWithdrawalHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.FiatWithdrawalHistory(t.Context(), &FiatWithdrawalRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.FiatWithdrawalHistory(t.Context(), &FiatWithdrawalRequestParams{ FiatCurrency: "USDT", }) if er != nil { - t.Errorf("%s FiatWithdrawalHistory() error %v", bi.Name, er) + t.Errorf("%s FiatWithdrawalHistory() error %v", e.Name, er) } } func TestDepositHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.DepositHistory(t.Context(), currency.USD, 1, time.Time{}, time.Time{}, 0, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.DepositHistory(t.Context(), currency.USD, 1, time.Time{}, time.Time{}, 0, 100) if er != nil { t.Error("Binanceus DepositHistory() error", er) } @@ -1165,8 +1165,8 @@ func TestDepositHistory(t *testing.T) { func TestFiatDepositHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.FiatDepositHistory(t.Context(), &FiatWithdrawalRequestParams{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.FiatDepositHistory(t.Context(), &FiatWithdrawalRequestParams{}) if er != nil { t.Error("Binanceus FiatDepositHistory() error", er) } @@ -1181,16 +1181,16 @@ func TestFiatDepositHistory(t *testing.T) { // all the three methods in one test methods. func TestWebsocketStreamKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetWsAuthStreamKey(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, er := e.GetWsAuthStreamKey(t.Context()) if er != nil { t.Error("Binanceus GetWsAuthStreamKey() error", er) } - er = bi.MaintainWsAuthStreamKey(t.Context()) + er = e.MaintainWsAuthStreamKey(t.Context()) if er != nil { t.Error("Binanceus MaintainWsAuthStreamKey() error", er) } - er = bi.CloseUserDataStream(t.Context()) + er = e.CloseUserDataStream(t.Context()) if er != nil { t.Error("Binanceus CloseUserDataStream() error", er) } @@ -1207,9 +1207,9 @@ var subscriptionRequestString = `{ func TestWebsocketSubscriptionHandling(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) rawData := []byte(subscriptionRequestString) - err := bi.wsHandleData(rawData) + err := e.wsHandleData(rawData) if err != nil { t.Error("Binanceus wsHandleData() error", err) } @@ -1223,7 +1223,7 @@ func TestWebsocketUnsubscriptionHandling(t *testing.T) { ], "id": 312 }`) - err := bi.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -1231,7 +1231,7 @@ func TestWebsocketUnsubscriptionHandling(t *testing.T) { func TestGetSubscriptions(t *testing.T) { t.Parallel() - if _, err := bi.GetSubscriptions(); err != nil { + if _, err := e.GetSubscriptions(); err != nil { t.Error("Binanceus GetSubscriptions() error", err) } } @@ -1267,7 +1267,7 @@ var ticker24hourChangeStream = `{ func TestWebsocketTickerUpdate(t *testing.T) { t.Parallel() - if err := bi.wsHandleData([]byte(ticker24hourChangeStream)); err != nil { + if err := e.wsHandleData([]byte(ticker24hourChangeStream)); err != nil { t.Error("Binanceus wsHandleData() for Ticker 24h Change Stream", err) } } @@ -1302,7 +1302,7 @@ func TestWebsocketKlineUpdate(t *testing.T) { } } }`) - if err := bi.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error("Binanceus wsHandleData() btcusdt@kline_1m stream data conversion ", err) } } @@ -1322,7 +1322,7 @@ func TestWebsocketStreamTradeUpdate(t *testing.T) { "m": true, "M": true }}`) - if err := bi.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error("Binanceus wsHandleData() error", err) } } @@ -1331,7 +1331,7 @@ func TestWebsocketStreamTradeUpdate(t *testing.T) { func TestWebsocketOrderBookDepthDiffStream(t *testing.T) { binanceusOrderBookLock.Lock() defer binanceusOrderBookLock.Unlock() - bi.setupOrderbookManager(t.Context()) + e.setupOrderbookManager(t.Context()) seedLastUpdateID := int64(161) book := OrderBook{ Asks: []OrderbookItem{ @@ -1375,14 +1375,14 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) { }}`) p := currency.NewPairWithDelimiter("BTC", "USDT", "-") - if err := bi.SeedLocalCacheWithBook(p, &book); err != nil { + if err := e.SeedLocalCacheWithBook(p, &book); err != nil { t.Fatal(err) } - if err := bi.wsHandleData(update1); err != nil { + if err := e.wsHandleData(update1); err != nil { t.Fatal(err) } - bi.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false - ob, err := bi.Websocket.Orderbook.GetOrderbook(p, asset.Spot) + e.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false + ob, err := e.Websocket.Orderbook.GetOrderbook(p, asset.Spot) if err != nil { t.Fatal(err) } @@ -1411,10 +1411,10 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) { ] } }`) - if err = bi.wsHandleData(update2); err != nil { + if err = e.wsHandleData(update2); err != nil { t.Error("Binanceus wshandlerData error", err) } - ob, err = bi.Websocket.Orderbook.GetOrderbook(p, asset.Spot) + ob, err = e.Websocket.Orderbook.GetOrderbook(p, asset.Spot) if err != nil { t.Fatal("Binanceus GetOrderBook error", err) } @@ -1430,7 +1430,7 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) { if exp, got := 0.163526, ob.Bids[1].Amount; got != exp { t.Fatalf("Binanceus Unexpected Bid amount. Exp: %f, got %f", exp, got) } - bi.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 + e.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 } // TestWebsocketPartialOrderBookDepthStream copied from the Binance Test @@ -1453,7 +1453,7 @@ func TestWebsocketPartialOrderBookDepthStream(t *testing.T) { ] }}`) var err error - if err = bi.wsHandleData(update1); err != nil { + if err = e.wsHandleData(update1); err != nil { t.Error("Binanceus Partial Order Book Depth Sream error", err) } update2 := []byte(`{ @@ -1474,7 +1474,7 @@ func TestWebsocketPartialOrderBookDepthStream(t *testing.T) { ] } }`) - if err = bi.wsHandleData(update2); err != nil { + if err = e.wsHandleData(update2); err != nil { t.Error("Binanceus Partial Order Book Depth Sream error", err) } } @@ -1493,7 +1493,7 @@ func TestWebsocketBookTicker(t *testing.T) { "A":"40.66000000" } }`) - if err := bi.wsHandleData(bookTickerJSON); err != nil { + if err := e.wsHandleData(bookTickerJSON); err != nil { t.Error("Binanceus Book Ticker error", err) } bookTickerForAllSymbols := []byte(` @@ -1508,7 +1508,7 @@ func TestWebsocketBookTicker(t *testing.T) { "A":"40.66000000" } }`) - if err := bi.wsHandleData(bookTickerForAllSymbols); err != nil { + if err := e.wsHandleData(bookTickerForAllSymbols); err != nil { t.Error("Binanceus Web socket Book ticker for all symbols error", err) } } @@ -1532,7 +1532,7 @@ func TestWebsocketAggTrade(t *testing.T) { "M": true } }`) - if err := bi.wsHandleData(aggTradejson); err != nil { + if err := e.wsHandleData(aggTradejson); err != nil { t.Error("Binanceus Aggregated Trade Order Json() error", err) } } @@ -1550,7 +1550,7 @@ var balanceUpdateInputJSON = ` func TestWebsocketBalanceUpdate(t *testing.T) { t.Parallel() thejson := []byte(balanceUpdateInputJSON) - if err := bi.wsHandleData(thejson); err != nil { + if err := e.wsHandleData(thejson); err != nil { t.Error(err) } } @@ -1586,7 +1586,7 @@ var listStatusUserDataStreamPayload = ` func TestWebsocketListStatus(t *testing.T) { t.Parallel() - if err := bi.wsHandleData([]byte(listStatusUserDataStreamPayload)); err != nil { + if err := e.wsHandleData([]byte(listStatusUserDataStreamPayload)); err != nil { t.Error(err) } } @@ -1640,25 +1640,26 @@ func TestProcessUpdate(t *testing.T) { t.Parallel() binanceusOrderBookLock.Lock() defer binanceusOrderBookLock.Unlock() + e.setupOrderbookManager(t.Context()) p := currency.NewBTCUSDT() var depth WebsocketDepthStream err := json.Unmarshal(websocketDepthUpdate, &depth) if err != nil { t.Fatal(err) } - err = bi.obm.stageWsUpdate(&depth, p, asset.Spot) + err = e.obm.stageWsUpdate(&depth, p, asset.Spot) if err != nil { t.Fatal(err) } - err = bi.obm.fetchBookViaREST(p) + err = e.obm.fetchBookViaREST(p) if err != nil { t.Fatal(err) } - err = bi.obm.cleanup(p) + err = e.obm.cleanup(p) if err != nil { t.Fatal(err) } - bi.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 + e.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0 } func TestWebsocketOrderExecutionReport(t *testing.T) { @@ -1680,14 +1681,14 @@ func TestWebsocketOrderExecutionReport(t *testing.T) { LastUpdated: time.UnixMilli(1616627567900), Pair: currency.NewBTCUSDT(), } - for len(bi.Websocket.DataHandler) > 0 { - <-bi.Websocket.DataHandler + for len(e.Websocket.DataHandler) > 0 { + <-e.Websocket.DataHandler } - err := bi.wsHandleData(payload) + err := e.wsHandleData(payload) if err != nil { t.Fatal(err) } - res := <-bi.Websocket.DataHandler + res := <-e.Websocket.DataHandler switch r := res.(type) { case *order.Detail: if !reflects.DeepEqual(expectedResult, *r) { @@ -1697,7 +1698,7 @@ func TestWebsocketOrderExecutionReport(t *testing.T) { t.Fatalf("Binanceus expected type order.Detail, found %T", res) } payload = []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616633041556,"s":"BTCUSDT","c":"YeULctvPAnHj5HXCQo9Mob","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028600","p":"52436.85000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"TRADE","X":"FILLED","r":"NONE","i":5341783271,"l":"0.00028600","z":"0.00028600","L":"52436.85000000","n":"0.00000029","N":"BTC","T":1616633041555,"t":726946523,"I":11390206312,"w":false,"m":false,"M":true,"O":1616633041555,"Z":"14.99693910","Y":"14.99693910","Q":"0.00000000"}}`) - err = bi.wsHandleData(payload) + err = e.wsHandleData(payload) if err != nil { t.Fatal("Binanceus OrderExecutionReport json conversion error", err) } @@ -1706,51 +1707,51 @@ func TestWebsocketOrderExecutionReport(t *testing.T) { func TestWebsocketOutboundAccountPosition(t *testing.T) { t.Parallel() payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"outboundAccountPosition","E":1616628815745,"u":1616628815745,"B":[{"a":"BTC","f":"0.00225109","l":"0.00123000"},{"a":"BNB","f":"0.00000000","l":"0.00000000"},{"a":"USDT","f":"54.43390661","l":"0.00000000"}]}}`) - if err := bi.wsHandleData(payload); err != nil { + if err := e.wsHandleData(payload); err != nil { t.Fatal("Binanceus testing \"outboundAccountPosition\" data conversion error", err) } } func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetAvailableTransferChains(t.Context(), currency.BTC); er != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetAvailableTransferChains(t.Context(), currency.BTC); er != nil { t.Error("Binanceus GetAvailableTransferChains() error", er) } } func TestQuickEnableCryptoWithdrawal(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if er := bi.QuickEnableCryptoWithdrawal(t.Context()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if er := e.QuickEnableCryptoWithdrawal(t.Context()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") { t.Errorf("Binanceus QuickEnableCryptoWithdrawal() expecting %s, but found %v", "unexpected end of JSON input", er) } } func TestQuickDisableCryptoWithdrawal(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if er := bi.QuickDisableCryptoWithdrawal(t.Context()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if er := e.QuickDisableCryptoWithdrawal(t.Context()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") { t.Errorf("Binanceus QuickDisableCryptoWithdrawal() expecting %s, but found %v", "unexpected end of JSON input", er) } } func TestGetUsersSpotAssetSnapshot(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - if _, er := bi.GetUsersSpotAssetSnapshot(t.Context(), time.Time{}, time.Time{}, 10, 6); er != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, er := e.GetUsersSpotAssetSnapshot(t.Context(), time.Time{}, time.Time{}, 10, 6); er != nil { t.Error("Binanceus GetUsersSpotAssetSnapshot() error", er) } } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, bi) - for _, a := range bi.GetAssetTypes(false) { - pairs, err := bi.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := bi.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/binanceus/binanceus_websocket.go b/exchanges/binanceus/binanceus_websocket.go index a4869d020c8..972440c9ab6 100644 --- a/exchanges/binanceus/binanceus_websocket.go +++ b/exchanges/binanceus/binanceus_websocket.go @@ -44,99 +44,99 @@ var ( ) // WsConnect initiates a websocket connection -func (bi *Binanceus) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !bi.Websocket.IsEnabled() || !bi.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - dialer.HandshakeTimeout = bi.Config.HTTPTimeout + dialer.HandshakeTimeout = e.Config.HTTPTimeout dialer.Proxy = http.ProxyFromEnvironment var err error - if bi.Websocket.CanUseAuthenticatedEndpoints() { - listenKey, err = bi.GetWsAuthStreamKey(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + listenKey, err = e.GetWsAuthStreamKey(ctx) if err != nil { - bi.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) log.Errorf(log.ExchangeSys, "%v unable to connect to authenticated Websocket. Error: %s", - bi.Name, + e.Name, err) } else { // cleans on failed connection - clean := strings.Split(bi.Websocket.GetWebsocketURL(), "?streams=") + clean := strings.Split(e.Websocket.GetWebsocketURL(), "?streams=") authPayload := clean[0] + "?streams=" + listenKey - err = bi.Websocket.SetWebsocketURL(authPayload, false, false) + err = e.Websocket.SetWebsocketURL(authPayload, false, false) if err != nil { return err } } } - err = bi.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err = e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", - bi.Name, + e.Name, err) } - if bi.Websocket.CanUseAuthenticatedEndpoints() { - bi.Websocket.Wg.Add(1) - go bi.KeepAuthKeyAlive(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + e.Websocket.Wg.Add(1) + go e.KeepAuthKeyAlive(ctx) } - bi.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ UseGorillaHandler: true, MessageType: gws.PongMessage, Delay: pingDelay, }) - bi.Websocket.Wg.Add(1) - go bi.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() - bi.setupOrderbookManager(ctx) + e.setupOrderbookManager(ctx) return nil } // KeepAuthKeyAlive will continuously send messages to // keep the WS auth key active -func (bi *Binanceus) KeepAuthKeyAlive(ctx context.Context) { - defer bi.Websocket.Wg.Done() +func (e *Exchange) KeepAuthKeyAlive(ctx context.Context) { + defer e.Websocket.Wg.Done() // ClosUserDataStream closes the User data stream and remove the listen key when closing the websocket. defer func() { - er := bi.CloseUserDataStream(ctx) + er := e.CloseUserDataStream(ctx) if er != nil { log.Errorf(log.WebsocketMgr, "%s closing user data stream error %v", - bi.Name, er) + e.Name, er) } }() // Looping in 30 Minutes and updating the listenKey ticks := time.NewTicker(time.Minute * 30) for { select { - case <-bi.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: ticks.Stop() return case <-ticks.C: - err := bi.MaintainWsAuthStreamKey(ctx) + err := e.MaintainWsAuthStreamKey(ctx) if err != nil { - bi.Websocket.DataHandler <- err - log.Warnf(log.ExchangeSys, "%s - Unable to renew auth websocket token, may experience shutdown", bi.Name) + e.Websocket.DataHandler <- err + log.Warnf(log.ExchangeSys, "%s - Unable to renew auth websocket token, may experience shutdown", e.Name) } } } } // wsReadData receives and passes on websocket messages for processing -func (bi *Binanceus) wsReadData() { - defer bi.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { - resp := bi.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := bi.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - bi.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } @@ -162,7 +162,7 @@ func stringToOrderStatus(status string) (order.Status, error) { } } -func (bi *Binanceus) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { var multiStreamData map[string]any err := json.Unmarshal(respRaw, &multiStreamData) if err != nil { @@ -184,34 +184,34 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { } } if newData, ok := multiStreamData["data"].(map[string]any); ok { - if e, ok := newData["e"].(string); ok { - switch e { + if event, ok := newData["e"].(string); ok { + switch event { case "outboundAccountPosition": var data wsAccountPosition err = json.Unmarshal(respRaw, &data) if err != nil { return fmt.Errorf("%v - Could not convert to outboundAccountPosition structure %s", - bi.Name, + e.Name, err) } - bi.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil case "balanceUpdate": var data wsBalanceUpdate err := json.Unmarshal(respRaw, &data) if err != nil { return fmt.Errorf("%v - Could not convert to balanceUpdate structure %s", - bi.Name, + e.Name, err) } - bi.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil case "executionReport": var data wsOrderUpdate err := json.Unmarshal(respRaw, &data) if err != nil { return fmt.Errorf("%v - Could not convert to executionReport structure %s", - bi.Name, + e.Name, err) } averagePrice := 0.0 @@ -219,7 +219,7 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { averagePrice = data.Data.CumulativeQuoteTransactedQuantity / data.Data.CumulativeFilledQuantity } remainingAmount := data.Data.Quantity - data.Data.CumulativeFilledQuantity - pair, assetType, err := bi.GetRequestFormattedPairAndAssetType(data.Data.Symbol) + pair, assetType, err := e.GetRequestFormattedPairAndAssetType(data.Data.Symbol) if err != nil { return err } @@ -230,8 +230,8 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { orderID := strconv.FormatInt(data.Data.OrderID, 10) orderStatus, err := stringToOrderStatus(data.Data.OrderStatus) if err != nil { - bi.Websocket.DataHandler <- order.ClassificationError{ - Exchange: bi.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -242,21 +242,21 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { } orderType, err := order.StringToOrderType(data.Data.OrderType) if err != nil { - bi.Websocket.DataHandler <- order.ClassificationError{ - Exchange: bi.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } orderSide, err := order.StringToOrderSide(data.Data.Side) if err != nil { - bi.Websocket.DataHandler <- order.ClassificationError{ - Exchange: bi.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } - bi.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: data.Data.Price, Amount: data.Data.Quantity, AverageExecutedPrice: averagePrice, @@ -266,7 +266,7 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { CostAsset: pair.Quote, Fee: data.Data.Commission, FeeAsset: feeAsset, - Exchange: bi.Name, + Exchange: e.Name, OrderID: orderID, ClientOrderID: clientOrderID, Type: orderType, @@ -283,10 +283,10 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err := json.Unmarshal(respRaw, &data) if err != nil { return fmt.Errorf("%v - Could not convert to listStatus structure %s", - bi.Name, + e.Name, err) } - bi.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil } } @@ -302,20 +302,20 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { return err } - pairs, err = bi.GetEnabledPairs(asset.Spot) + pairs, err = e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := bi.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } switch streamType[1] { case "trade": - saveTradeData := bi.IsSaveTradeDataEnabled() - if !saveTradeData && !bi.IsTradeFeedEnabled() { + saveTradeData := e.IsSaveTradeDataEnabled() + if !saveTradeData && !e.IsTradeFeedEnabled() { return nil } @@ -323,7 +323,7 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err = json.Unmarshal(rawData, &t) if err != nil { return fmt.Errorf("%v - Could not unmarshal trade data: %s", - bi.Name, + e.Name, err) } @@ -332,13 +332,13 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { return err } - return bi.Websocket.Trade.Update(saveTradeData, + return e.Websocket.Trade.Update(saveTradeData, trade.Data{ CurrencyPair: pair, Timestamp: t.TimeStamp.Time(), Price: t.Price.Float64(), Amount: t.Quantity.Float64(), - Exchange: bi.Name, + Exchange: e.Name, AssetType: asset.Spot, TID: strconv.FormatInt(t.TradeID, 10), }) @@ -347,7 +347,7 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err := json.Unmarshal(rawData, &t) if err != nil { return fmt.Errorf("%v - Could not convert to a TickerStream structure %s", - bi.Name, + e.Name, err.Error()) } @@ -356,8 +356,8 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { return err } - bi.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: bi.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Open: t.OpenPrice, Close: t.ClosePrice, Volume: t.TotalTradedVolume, @@ -378,7 +378,7 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err := json.Unmarshal(rawData, &kline) if err != nil { return fmt.Errorf("%v - Could not convert to a KlineStream structure %s", - bi.Name, + e.Name, err) } @@ -387,11 +387,11 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { return err } - bi.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: kline.EventTime.Time(), Pair: pair, AssetType: asset.Spot, - Exchange: bi.Name, + Exchange: e.Name, StartTime: kline.Kline.StartTime.Time(), CloseTime: kline.Kline.CloseTime.Time(), Interval: kline.Kline.Interval, @@ -407,16 +407,16 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err := json.Unmarshal(rawData, &depth) if err != nil { return fmt.Errorf("%v - Could not convert to depthStream structure %s", - bi.Name, + e.Name, err) } - init, err := bi.UpdateLocalBuffer(&depth) + init, err := e.UpdateLocalBuffer(&depth) if err != nil { if init { return nil } return fmt.Errorf("%v - UpdateLocalCache error: %s", - bi.Name, + e.Name, err) } return nil @@ -425,35 +425,35 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { err := json.Unmarshal(rawData, &depth) if err != nil { return fmt.Errorf("%v - Could not convert to depthStream structure %s", - bi.Name, + e.Name, err) } - bi.Websocket.DataHandler <- depth + e.Websocket.DataHandler <- depth return nil case "bookTicker": var bo OrderBookTickerStream err := json.Unmarshal(rawData, &bo) if err != nil { - return fmt.Errorf("%v - Could not convert to bookOrder structure %s ", err, bi.Name) + return fmt.Errorf("%v - Could not convert to bookOrder structure %s ", err, e.Name) } pair, err := currency.NewPairFromFormattedPairs(bo.S, pairs, format) if err != nil { return err } bo.Symbol = pair - bi.Websocket.DataHandler <- &bo + e.Websocket.DataHandler <- &bo return nil case "aggTrade": var agg WebsocketAggregateTradeStream err := json.Unmarshal(rawData, &agg) if err != nil { - return fmt.Errorf("%v - Could not convert to aggTrade structure %s ", err, bi.Name) + return fmt.Errorf("%v - Could not convert to aggTrade structure %s ", err, e.Name) } - bi.Websocket.DataHandler <- agg + e.Websocket.DataHandler <- agg return nil default: - bi.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: bi.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } } } @@ -464,25 +464,25 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { if err != nil { return err } - pairs, err := bi.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := bi.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } err = json.Unmarshal(rawData, &bt) if err != nil { - return fmt.Errorf("%v - Could not convert to bookOrder structure %s ", err, bi.Name) + return fmt.Errorf("%v - Could not convert to bookOrder structure %s ", err, e.Name) } pair, err := currency.NewPairFromFormattedPairs(bt.S, pairs, format) if err != nil { return err } bt.Symbol = pair - bi.Websocket.DataHandler <- &bt + e.Websocket.DataHandler <- &bt return nil } } @@ -491,13 +491,13 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error { } // UpdateLocalBuffer updates and returns the most recent iteration of the orderbook -func (bi *Binanceus) UpdateLocalBuffer(wsdp *WebsocketDepthStream) (bool, error) { - enabledPairs, err := bi.GetEnabledPairs(asset.Spot) +func (e *Exchange) UpdateLocalBuffer(wsdp *WebsocketDepthStream) (bool, error) { + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return false, err } - format, err := bi.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return false, err } @@ -509,29 +509,29 @@ func (bi *Binanceus) UpdateLocalBuffer(wsdp *WebsocketDepthStream) (bool, error) return false, err } - err = bi.obm.stageWsUpdate(wsdp, currencyPair, asset.Spot) + err = e.obm.stageWsUpdate(wsdp, currencyPair, asset.Spot) if err != nil { - init, err2 := bi.obm.checkIsInitialSync(currencyPair) + init, err2 := e.obm.checkIsInitialSync(currencyPair) if err2 != nil { return false, err2 } return init, err } - err = bi.applyBufferUpdate(currencyPair) + err = e.applyBufferUpdate(currencyPair) if err != nil { - bi.invalidateAndCleanupOrderbook(currencyPair) + e.invalidateAndCleanupOrderbook(currencyPair) } return false, err } // GenerateSubscriptions generates the default subscription set -func (bi *Binanceus) GenerateSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateSubscriptions() (subscription.List, error) { channels := []string{"@ticker", "@trade", "@kline_1m", "@depth@100ms"} var subscriptions subscription.List - pairs, err := bi.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } @@ -557,7 +557,7 @@ subs: } // Subscribe subscribes to a set of channels -func (bi *Binanceus) Subscribe(channelsToSubscribe subscription.List) error { +func (e *Exchange) Subscribe(channelsToSubscribe subscription.List) error { ctx := context.TODO() payload := WebsocketPayload{ Method: "SUBSCRIBE", @@ -565,7 +565,7 @@ func (bi *Binanceus) Subscribe(channelsToSubscribe subscription.List) error { for i := range channelsToSubscribe { payload.Params = append(payload.Params, channelsToSubscribe[i].Channel) if i%50 == 0 && i != 0 { - err := bi.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) if err != nil { return err } @@ -573,16 +573,16 @@ func (bi *Binanceus) Subscribe(channelsToSubscribe subscription.List) error { } } if len(payload.Params) > 0 { - err := bi.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) if err != nil { return err } } - return bi.Websocket.AddSuccessfulSubscriptions(bi.Websocket.Conn, channelsToSubscribe...) + return e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channelsToSubscribe...) } // Unsubscribe unsubscribes from a set of channels -func (bi *Binanceus) Unsubscribe(channelsToUnsubscribe subscription.List) error { +func (e *Exchange) Unsubscribe(channelsToUnsubscribe subscription.List) error { ctx := context.TODO() payload := WebsocketPayload{ Method: "UNSUBSCRIBE", @@ -590,7 +590,7 @@ func (bi *Binanceus) Unsubscribe(channelsToUnsubscribe subscription.List) error for i := range channelsToUnsubscribe { payload.Params = append(payload.Params, channelsToUnsubscribe[i].Channel) if i%50 == 0 && i != 0 { - err := bi.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) if err != nil { return err } @@ -598,24 +598,24 @@ func (bi *Binanceus) Unsubscribe(channelsToUnsubscribe subscription.List) error } } if len(payload.Params) > 0 { - err := bi.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payload) if err != nil { return err } } - return bi.Websocket.RemoveSubscriptions(bi.Websocket.Conn, channelsToUnsubscribe...) + return e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channelsToUnsubscribe...) } -func (bi *Binanceus) setupOrderbookManager(ctx context.Context) { - if bi.obm == nil { - bi.obm = &orderbookManager{ +func (e *Exchange) setupOrderbookManager(ctx context.Context) { + if e.obm == nil { + e.obm = &orderbookManager{ state: make(map[currency.Code]map[currency.Code]map[asset.Item]*update), jobs: make(chan job, maxWSOrderbookJobs), } } else { // Change state on reconnect for initial sync. - for x := range bi.obm.state { - for _, m2 := range bi.obm.state[x] { + for x := range e.obm.state { + for _, m2 := range e.obm.state[x] { for y := range m2 { m2[y].initialSync = true m2[y].needsFetchingBook = true @@ -626,31 +626,31 @@ func (bi *Binanceus) setupOrderbookManager(ctx context.Context) { } for range maxWSOrderbookWorkers { // 10 workers for synchronising book - bi.SynchroniseWebsocketOrderbook(ctx) + e.SynchroniseWebsocketOrderbook(ctx) } } // SynchroniseWebsocketOrderbook synchronises full orderbook for currency pair asset -func (bi *Binanceus) SynchroniseWebsocketOrderbook(ctx context.Context) { - bi.Websocket.Wg.Add(1) +func (e *Exchange) SynchroniseWebsocketOrderbook(ctx context.Context) { + e.Websocket.Wg.Add(1) go func() { - defer bi.Websocket.Wg.Done() + defer e.Websocket.Wg.Done() for { select { - case <-bi.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: for { select { - case <-bi.obm.jobs: + case <-e.obm.jobs: default: return } } - case j := <-bi.obm.jobs: - err := bi.processJob(ctx, j.Pair) + case j := <-e.obm.jobs: + err := e.processJob(ctx, j.Pair) if err != nil { log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", - bi.Name, err) + e.Name, err) } } } @@ -658,7 +658,7 @@ func (bi *Binanceus) SynchroniseWebsocketOrderbook(ctx context.Context) { } // ProcessOrderbookUpdate processes the websocket orderbook update -func (bi *Binanceus) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, wsDSUpdate *WebsocketDepthStream) error { +func (e *Exchange) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, wsDSUpdate *WebsocketDepthStream) error { updateBid := make([]orderbook.Level, len(wsDSUpdate.UpdateBids)) for i := range wsDSUpdate.UpdateBids { updateBid[i].Price = wsDSUpdate.UpdateBids[i][0].Float64() @@ -671,7 +671,7 @@ func (bi *Binanceus) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, wsDS updateAsk[i].Amount = wsDSUpdate.UpdateAsks[i][1].Float64() } - return bi.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Bids: updateBid, Asks: updateAsk, Pair: cp, @@ -708,8 +708,8 @@ func (o *orderbookManager) fetchBookViaREST(pair currency.Pair) error { // applyBufferUpdate applies the buffer to the orderbook or initiates a new // orderbook sync by the REST protocol which is off handed to go routine. -func (bi *Binanceus) applyBufferUpdate(pair currency.Pair) error { - fetching, needsFetching, err := bi.obm.handleFetchingBook(pair) +func (e *Exchange) applyBufferUpdate(pair currency.Pair) error { + fetching, needsFetching, err := e.obm.handleFetchingBook(pair) if err != nil { return err } @@ -717,30 +717,30 @@ func (bi *Binanceus) applyBufferUpdate(pair currency.Pair) error { return nil } if needsFetching { - if bi.Verbose { - log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", bi.Name) + if e.Verbose { + log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", e.Name) } - return bi.obm.fetchBookViaREST(pair) + return e.obm.fetchBookViaREST(pair) } - recent, err := bi.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) + recent, err := e.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) if err != nil { log.Errorf( log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", - bi.Name, + e.Name, err) } if recent != nil { - err = bi.obm.checkAndProcessOrderbookUpdate(bi.ProcessOrderbookUpdate, pair, recent) + err = e.obm.checkAndProcessOrderbookUpdate(e.ProcessOrderbookUpdate, pair, recent) if err != nil { log.Errorf( log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", - bi.Name, + e.Name, err) - err = bi.obm.setNeedsFetchingBook(pair) + err = e.obm.setNeedsFetchingBook(pair) if err != nil { return err } @@ -770,31 +770,31 @@ func (o *orderbookManager) stopFetchingBook(pair currency.Pair) error { } // processJob fetches and processes orderbook updates -func (bi *Binanceus) processJob(ctx context.Context, p currency.Pair) error { - err := bi.SeedLocalCache(ctx, p) +func (e *Exchange) processJob(ctx context.Context, p currency.Pair) error { + err := e.SeedLocalCache(ctx, p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) } - err = bi.obm.stopFetchingBook(p) + err = e.obm.stopFetchingBook(p) if err != nil { return err } // Immediately apply the buffer updates so we don't wait for a // new update to initiate this. - err = bi.applyBufferUpdate(p) + err = e.applyBufferUpdate(p) if err != nil { - bi.invalidateAndCleanupOrderbook(p) + e.invalidateAndCleanupOrderbook(p) return err } return nil } // SeedLocalCache seeds depth data -func (bi *Binanceus) SeedLocalCache(ctx context.Context, p currency.Pair) error { - ob, err := bi.GetOrderBookDepth(ctx, +func (e *Exchange) SeedLocalCache(ctx context.Context, p currency.Pair) error { + ob, err := e.GetOrderBookDepth(ctx, &OrderBookDataRequestParams{ Symbol: p, Limit: 1000, @@ -802,17 +802,17 @@ func (bi *Binanceus) SeedLocalCache(ctx context.Context, p currency.Pair) error if err != nil { return err } - return bi.SeedLocalCacheWithBook(p, ob) + return e.SeedLocalCacheWithBook(p, ob) } // SeedLocalCacheWithBook seeds the local orderbook cache -func (bi *Binanceus) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { +func (e *Exchange) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *OrderBook) error { newOrderBook := orderbook.Book{ Pair: p, Asset: asset.Spot, - Exchange: bi.Name, + Exchange: e.Name, LastUpdateID: orderbookNew.LastUpdateID, - ValidateOrderbook: bi.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(orderbookNew.Bids)), Asks: make(orderbook.Levels, len(orderbookNew.Asks)), LastUpdated: time.Now(), // Time not provided in REST book. @@ -829,7 +829,7 @@ func (bi *Binanceus) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *Order Price: orderbookNew.Asks[i].Price, } } - return bi.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } // handleFetchingBook checks if a full book is being fetched or needs to be @@ -859,12 +859,12 @@ func (o *orderbookManager) handleFetchingBook(pair currency.Pair) (fetching, nee } // invalidateAndCleanupOrderbook invalidaates orderbook and cleans local cache -func (bi *Binanceus) invalidateAndCleanupOrderbook(p currency.Pair) { - if err := bi.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { - log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", bi.Name, err) +func (e *Exchange) invalidateAndCleanupOrderbook(p currency.Pair) { + if err := e.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { + log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", e.Name, err) } - if err := bi.obm.cleanup(p); err != nil { - log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", bi.Name, err) + if err := e.obm.cleanup(p); err != nil { + log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", e.Name, err) } } diff --git a/exchanges/binanceus/binanceus_wrapper.go b/exchanges/binanceus/binanceus_wrapper.go index 157bd88b9c5..d7143f28a5d 100644 --- a/exchanges/binanceus/binanceus_wrapper.go +++ b/exchanges/binanceus/binanceus_wrapper.go @@ -31,12 +31,12 @@ import ( ) // SetDefaults sets the basic defaults for Binanceus -func (bi *Binanceus) SetDefaults() { - bi.Name = "Binanceus" - bi.Enabled = true - bi.Verbose = true - bi.API.CredentialsValidator.RequiresKey = true - bi.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Binanceus" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true fmt1 := currency.PairStore{ AssetEnabled: true, @@ -46,11 +46,11 @@ func (bi *Binanceus) SetDefaults() { Uppercase: true, }, } - if err := bi.SetAssetPairStore(asset.Spot, fmt1); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing `spot` default asset formats: %s", bi.Name, err) + if err := e.SetAssetPairStore(asset.Spot, fmt1); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing `spot` default asset formats: %s", e.Name, err) } - bi.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -123,15 +123,15 @@ func (bi *Binanceus) SetDefaults() { } var err error - bi.Requester, err = request.New(bi.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - bi.API.Endpoints = bi.NewEndpoints() - if err := bi.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + if err := e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: binanceusAPIURL, exchange.RestSpotSupplementary: binanceusAPIURL, exchange.WebsocketSpot: binanceusDefaultWebsocketURL, @@ -139,54 +139,54 @@ func (bi *Binanceus) SetDefaults() { }); err != nil { log.Errorf(log.ExchangeSys, "%s setting default endpoints error %v", - bi.Name, err) + e.Name, err) } - bi.Websocket = websocket.NewManager() - bi.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - bi.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - bi.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (bi *Binanceus) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - bi.SetEnabled(false) + e.SetEnabled(false) return nil } - err = bi.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - ePoint, err := bi.API.Endpoints.GetURL(exchange.WebsocketSpot) + ePoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = bi.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: binanceusDefaultWebsocketURL, RunningURL: ePoint, - Connector: bi.WsConnect, - Subscriber: bi.Subscribe, - Unsubscriber: bi.Unsubscribe, - GenerateSubscriptions: bi.GenerateSubscriptions, - Features: &bi.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.GenerateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, }, - TradeFeed: bi.Features.Enabled.TradeFeed, + TradeFeed: e.Features.Enabled.TradeFeed, }) if err != nil { return err } - return bi.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, RateLimit: request.NewWeightedRateLimitByDuration(300 * time.Millisecond), @@ -194,11 +194,11 @@ func (bi *Binanceus) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (bi *Binanceus) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !bi.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - info, err := bi.GetExchangeInfo(ctx) + info, err := e.GetExchangeInfo(ctx) if err != nil { return nil, err } @@ -221,27 +221,27 @@ func (bi *Binanceus) FetchTradablePairs(ctx context.Context, a asset.Item) (curr // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (bi *Binanceus) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := bi.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = bi.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return bi.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTicker updates and returns the ticker for a currency pair -func (bi *Binanceus) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } if a != asset.Spot { return nil, fmt.Errorf("%w '%v'", asset.ErrNotSupported, a) } - tick, err := bi.GetPriceChangeStats(ctx, p) + tick, err := e.GetPriceChangeStats(ctx, p) if err != nil { return nil, err } @@ -256,32 +256,32 @@ func (bi *Binanceus) UpdateTicker(ctx context.Context, p currency.Pair, a asset. Open: tick.OpenPrice, Close: tick.PrevClosePrice, Pair: p, - ExchangeName: bi.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(bi.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateTickers updates all currency pairs of a given asset type -func (bi *Binanceus) UpdateTickers(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { if a != asset.Spot { return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - tick, err := bi.GetTickers(ctx) + tick, err := e.GetTickers(ctx) if err != nil { return err } - pairs, err := bi.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { return err } for i := range pairs { for y := range tick { - pairFmt, err := bi.FormatExchangeCurrency(pairs[i], a) + pairFmt, err := e.FormatExchangeCurrency(pairs[i], a) if err != nil { return err } @@ -299,7 +299,7 @@ func (bi *Binanceus) UpdateTickers(ctx context.Context, a asset.Item) error { Open: tick[y].OpenPrice, Close: tick[y].PrevClosePrice, Pair: pairFmt, - ExchangeName: bi.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -311,21 +311,21 @@ func (bi *Binanceus) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (bi *Binanceus) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := bi.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: bi.Name, + Exchange: e.Name, Pair: pair, Asset: assetType, - ValidateOrderbook: bi.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - orderbookNew, err := bi.GetOrderBookDepth(ctx, &OrderBookDataRequestParams{ + orderbookNew, err := e.GetOrderBookDepth(ctx, &OrderBookDataRequestParams{ Symbol: pair, Limit: 1000, }) @@ -350,18 +350,18 @@ func (bi *Binanceus) UpdateOrderbook(ctx context.Context, pair currency.Pair, as if err != nil { return book, err } - return orderbook.Get(bi.Name, pair, assetType) + return orderbook.Get(e.Name, pair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies -func (bi *Binanceus) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount - info.Exchange = bi.Name + info.Exchange = e.Name if assetType != asset.Spot { return info, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - theAccount, err := bi.GetAccount(ctx) + theAccount, err := e.GetAccount(ctx) if err != nil { return info, err } @@ -380,7 +380,7 @@ func (bi *Binanceus) UpdateAccountInfo(ctx context.Context, assetType asset.Item acc.Currencies = currencyBalance acc.AssetType = assetType info.Accounts = append(info.Accounts, acc) - creds, err := bi.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return info, err } @@ -391,16 +391,16 @@ func (bi *Binanceus) UpdateAccountInfo(ctx context.Context, assetType asset.Item } // GetAccountFundingHistory returns funding history, deposits and withdrawals -func (bi *Binanceus) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (bi *Binanceus) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { if a != asset.Spot { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - withdrawals, err := bi.WithdrawalHistory(ctx, c, "", time.Time{}, time.Time{}, 0, 10000) + withdrawals, err := e.WithdrawalHistory(ctx, c, "", time.Time{}, time.Time{}, 0, 10000) if err != nil { return nil, err } @@ -422,15 +422,15 @@ func (bi *Binanceus) GetWithdrawalsHistory(ctx context.Context, c currency.Code, } // GetRecentTrades returns the most recent trades for a currency and asset -func (bi *Binanceus) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := bi.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } const limit = 1000 - tradeData, err := bi.GetMostRecentTrades(ctx, RecentTradeRequestParams{p, limit}) + tradeData, err := e.GetMostRecentTrades(ctx, RecentTradeRequestParams{p, limit}) if err != nil { return nil, err } @@ -438,7 +438,7 @@ func (bi *Binanceus) GetRecentTrades(ctx context.Context, p currency.Pair, asset for i := range tradeData { resp[i] = trade.Data{ TID: strconv.FormatInt(tradeData[i].ID, 10), - Exchange: bi.Name, + Exchange: e.Name, AssetType: assetType, CurrencyPair: p, Price: tradeData[i].Price, @@ -447,7 +447,7 @@ func (bi *Binanceus) GetRecentTrades(ctx context.Context, p currency.Pair, asset } } - if bi.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err := trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -458,11 +458,11 @@ func (bi *Binanceus) GetRecentTrades(ctx context.Context, p currency.Pair, asset } // GetHistoricTrades returns historic trade data within the timeframe provided -func (bi *Binanceus) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := bi.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } req := AggregatedTradeRequestParams{ @@ -470,12 +470,12 @@ func (bi *Binanceus) GetHistoricTrades(ctx context.Context, p currency.Pair, ass StartTime: timestampStart.UnixMilli(), EndTime: timestampEnd.UnixMilli(), } - trades, err := bi.GetAggregateTrades(ctx, &req) + trades, err := e.GetAggregateTrades(ctx, &req) if err != nil { return nil, err } result := make([]trade.Data, len(trades)) - exName := bi.Name + exName := e.Name for i := range trades { t := trades[i].toTradeData(p, exName, assetType) result[i] = *t @@ -484,11 +484,11 @@ func (bi *Binanceus) GetHistoricTrades(ctx context.Context, p currency.Pair, ass } // SubmitOrder submits a new order -func (bi *Binanceus) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse var timeInForce string var sideType string - err := s.Validate(bi.GetTradingRequirements()) + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } @@ -511,7 +511,7 @@ func (bi *Binanceus) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S return nil, fmt.Errorf("%w %v", order.ErrUnsupportedOrderType, s.Type) } var response NewOrderResponse - response, err = bi.NewOrder(ctx, &NewOrderRequest{ + response, err = e.NewOrder(ctx, &NewOrderRequest{ Symbol: s.Pair, Side: sideType, Price: s.Price, @@ -535,7 +535,7 @@ func (bi *Binanceus) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S Amount: response.Fills[i].Qty, Fee: response.Fills[i].Commission, FeeAsset: response.Fills[i].CommissionAsset, - Exchange: bi.Name, + Exchange: e.Name, }) } @@ -544,19 +544,19 @@ func (bi *Binanceus) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (bi *Binanceus) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (bi *Binanceus) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } if o.AssetType != asset.Spot { return fmt.Errorf("%w '%v'", asset.ErrNotSupported, o.AssetType) } - _, err := bi.CancelExistingOrder(ctx, + _, err := e.CancelExistingOrder(ctx, &CancelOrderRequestParams{ Symbol: o.Pair, OrderID: o.OrderID, @@ -566,23 +566,23 @@ func (bi *Binanceus) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func (bi *Binanceus) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (bi *Binanceus) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } var cancelAllOrdersResponse order.CancelAllResponse cancelAllOrdersResponse.Status = make(map[string]string) if orderCancellation.AssetType == asset.Spot { - symbolValue, err := bi.FormatSymbol(orderCancellation.Pair, asset.Spot) + symbolValue, err := e.FormatSymbol(orderCancellation.Pair, asset.Spot) if err != nil { return cancelAllOrdersResponse, err } - openOrders, err := bi.GetAllOpenOrders(ctx, symbolValue) + openOrders, err := e.GetAllOpenOrders(ctx, symbolValue) if err != nil { return cancelAllOrdersResponse, err } @@ -591,7 +591,7 @@ func (bi *Binanceus) CancelAllOrders(ctx context.Context, orderCancellation *ord if err != nil { return cancelAllOrdersResponse, err } - _, err = bi.CancelExistingOrder(ctx, &CancelOrderRequestParams{ + _, err = e.CancelExistingOrder(ctx, &CancelOrderRequestParams{ Symbol: pair, OrderID: strconv.FormatUint(openOrders[ind].OrderID, 10), ClientSuppliedOrderID: openOrders[ind].ClientOrderID, @@ -607,11 +607,11 @@ func (bi *Binanceus) CancelAllOrders(ctx context.Context, orderCancellation *ord } // GetOrderInfo returns order information based on order ID -func (bi *Binanceus) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := bi.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } @@ -619,7 +619,7 @@ func (bi *Binanceus) GetOrderInfo(ctx context.Context, orderID string, pair curr if err != nil { return nil, fmt.Errorf("invalid orderID %w", err) } - symbolValue, err := bi.FormatSymbol(pair, asset.Spot) + symbolValue, err := e.FormatSymbol(pair, asset.Spot) if err != nil { return nil, err } @@ -627,7 +627,7 @@ func (bi *Binanceus) GetOrderInfo(ctx context.Context, orderID string, pair curr return nil, fmt.Errorf("%s %w", assetType, asset.ErrNotSupported) } var orderType order.Type - resp, err := bi.GetOrder(ctx, &OrderRequestParams{ + resp, err := e.GetOrder(ctx, &OrderRequestParams{ Symbol: symbolValue, OrderID: orderIDInt, }) @@ -636,20 +636,20 @@ func (bi *Binanceus) GetOrderInfo(ctx context.Context, orderID string, pair curr } orderSide, err := order.StringToOrderSide(resp.Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } status, err := order.StringToOrderStatus(resp.Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderType, err = order.StringToOrderType(resp.Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } return &order.Detail{ Amount: resp.OrigQty, - Exchange: bi.Name, + Exchange: e.Name, OrderID: strconv.FormatUint(resp.OrderID, 10), ClientOrderID: resp.ClientOrderID, Side: orderSide, @@ -666,8 +666,8 @@ func (bi *Binanceus) GetOrderInfo(ctx context.Context, orderID string, pair curr } // GetDepositAddress returns a deposit address for a specified currency -func (bi *Binanceus) GetDepositAddress(ctx context.Context, c currency.Code, _ /*accountID*/, chain string) (*deposit.Address, error) { - address, err := bi.GetDepositAddressForCurrency(ctx, c.String(), chain) +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, _ /*accountID*/, chain string) (*deposit.Address, error) { + address, err := e.GetDepositAddressForCurrency(ctx, c.String(), chain) if err != nil { return nil, err } @@ -678,11 +678,11 @@ func (bi *Binanceus) GetDepositAddress(ctx context.Context, c currency.Code, _ / } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (bi *Binanceus) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - withdrawID, err := bi.WithdrawCrypto(ctx, withdrawRequest) + withdrawID, err := e.WithdrawCrypto(ctx, withdrawRequest) if err != nil { return nil, err } @@ -694,18 +694,18 @@ func (bi *Binanceus) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRe // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted. But, GCT has no concept of withdrawal via SEN // the fiat withdrawal end point of Binance.US is built to submit a USD withdraw request via Silvergate Exchange Network (SEN). // So, this method is not implemented. -func (bi *Binanceus) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted // But, GCT has no concept of withdrawal via SEN the fiat withdrawal end point of Binance.US is built to submit a USD withdraw request via Silvergate Exchange Network (SEN). -func (bi *Binanceus) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { err := getOrdersRequest.Validate() if err != nil { return nil, err @@ -719,12 +719,12 @@ func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *orde if len(getOrdersRequest.Pairs) != 1 { symbol = "" } else { - symbol, err = bi.FormatSymbol(getOrdersRequest.Pairs[0], asset.Spot) + symbol, err = e.FormatSymbol(getOrdersRequest.Pairs[0], asset.Spot) if err != nil { return nil, err } } - resp, err := bi.GetAllOpenOrders(ctx, symbol) + resp, err := e.GetAllOpenOrders(ctx, symbol) if err != nil { return nil, err } @@ -747,20 +747,20 @@ func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *orde var orderStatus order.Status orderSide, err = order.StringToOrderSide(strings.ToUpper(resp[x].Side)) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderType, err = order.StringToOrderType(strings.ToUpper(resp[x].Type)) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderStatus, err = order.StringToOrderStatus(resp[x].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", bi.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders[x] = order.Detail{ Amount: resp[x].OrigQty, Date: resp[x].Time.Time(), - Exchange: bi.Name, + Exchange: e.Name, OrderID: strconv.FormatUint(resp[x].OrderID, 10), ClientOrderID: resp[x].ClientOrderID, Side: orderSide, @@ -772,43 +772,43 @@ func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *orde LastUpdated: resp[x].UpdateTime.Time(), } } - return getOrdersRequest.Filter(bi.Name, orders), nil + return getOrdersRequest.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information Can Limit response to specific order status -func (bi *Binanceus) GetOrderHistory(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { // An endpoint like /api/v3/allOrders does not exist in the binance us // so This end point is left unimplemented return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on the type of transaction -func (bi *Binanceus) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if (!bi.AreCredentialsValid(ctx) || bi.SkipAuthCheck) && + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return bi.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // ValidateAPICredentials validates current credentials used for wrapper -func (bi *Binanceus) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := bi.UpdateAccountInfo(ctx, assetType) - return bi.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (bi *Binanceus) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := bi.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - candles, err := bi.GetSpotKline(ctx, &KlinesRequestParams{ - Interval: bi.GetIntervalEnum(req.ExchangeInterval), + candles, err := e.GetSpotKline(ctx, &KlinesRequestParams{ + Interval: e.GetIntervalEnum(req.ExchangeInterval), Symbol: req.Pair, StartTime: req.Start, EndTime: req.End, @@ -833,8 +833,8 @@ func (bi *Binanceus) GetHistoricCandles(ctx context.Context, pair currency.Pair, } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (bi *Binanceus) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := bi.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -842,8 +842,8 @@ func (bi *Binanceus) GetHistoricCandlesExtended(ctx context.Context, pair curren timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var candles []CandleStick - candles, err = bi.GetSpotKline(ctx, &KlinesRequestParams{ - Interval: bi.GetIntervalEnum(req.ExchangeInterval), + candles, err = e.GetSpotKline(ctx, &KlinesRequestParams{ + Interval: e.GetIntervalEnum(req.ExchangeInterval), Symbol: req.Pair, StartTime: req.RangeHolder.Ranges[x].Start.Time, EndTime: req.RangeHolder.Ranges[x].End.Time, @@ -867,10 +867,9 @@ func (bi *Binanceus) GetHistoricCandlesExtended(ctx context.Context, pair curren return req.ProcessResponse(timeSeries) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (bi *Binanceus) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - coinInfo, err := bi.GetAssetFeesAndWalletStatus(ctx) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + coinInfo, err := e.GetAssetFeesAndWalletStatus(ctx) if err != nil { return nil, err } @@ -889,27 +888,27 @@ func (bi *Binanceus) GetAvailableTransferChains(ctx context.Context, cryptocurre } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (bi *Binanceus) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (bi *Binanceus) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (bi *Binanceus) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (bi *Binanceus) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := bi.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } - symbol, err := bi.FormatSymbol(cp, a) + symbol, err := e.FormatSymbol(cp, a) if err != nil { return "", err } diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index 015f91505af..d47a1b041f5 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -111,15 +111,15 @@ const ( CandlesPeriodKey = "_period" ) -// Bitfinex is the overarching type across the bitfinex package -type Bitfinex struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bitfinex +type Exchange struct { exchange.Base } // GetPlatformStatus returns the Bifinex platform status -func (b *Bitfinex) GetPlatformStatus(ctx context.Context) (int, error) { +func (e *Exchange) GetPlatformStatus(ctx context.Context) (int, error) { var response []int - err := b.SendHTTPRequest(ctx, exchange.RestSpot, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, bitfinexAPIVersion2+ bitfinexPlatformStatus, &response, @@ -228,9 +228,9 @@ func defaultMarginV2Info(data []any) (MarginInfoV2, error) { // GetV2MarginInfo gets v2 margin info for a symbol provided // symbol: base, sym_all, any other trading symbol example tBTCUSD -func (b *Bitfinex) GetV2MarginInfo(ctx context.Context, symbol string) ([]MarginInfoV2, error) { +func (e *Exchange) GetV2MarginInfo(ctx context.Context, symbol string) ([]MarginInfoV2, error) { var data []any - err := b.SendAuthenticatedHTTPRequestV2(ctx, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2MarginInfo+symbol, nil, @@ -244,7 +244,7 @@ func (b *Bitfinex) GetV2MarginInfo(ctx context.Context, symbol string) ([]Margin case "base": tempResp, err = baseMarginInfo(data) if err != nil { - return nil, fmt.Errorf("%v - %s: %w", b.Name, symbol, err) + return nil, fmt.Errorf("%v - %s: %w", e.Name, symbol, err) } case "sym_all": var resp []MarginInfoV2 @@ -253,21 +253,21 @@ func (b *Bitfinex) GetV2MarginInfo(ctx context.Context, symbol string) ([]Margin default: tempResp, err = defaultMarginV2Info(data) if err != nil { - return nil, fmt.Errorf("%v - %s: %w", b.Name, symbol, err) + return nil, fmt.Errorf("%v - %s: %w", e.Name, symbol, err) } } return []MarginInfoV2{tempResp}, nil } // GetV2MarginFunding gets borrowing rates for margin trading -func (b *Bitfinex) GetV2MarginFunding(ctx context.Context, symbol, amount string, period int32) (MarginV2FundingData, error) { +func (e *Exchange) GetV2MarginFunding(ctx context.Context, symbol, amount string, period int32) (MarginV2FundingData, error) { var resp []any var response MarginV2FundingData params := make(map[string]any) params["symbol"] = symbol params["period"] = period params["amount"] = amount - err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2MarginFunding, params, &resp, @@ -293,10 +293,10 @@ func (b *Bitfinex) GetV2MarginFunding(ctx context.Context, symbol, amount string } // GetV2FundingInfo gets funding info for margin pairs -func (b *Bitfinex) GetV2FundingInfo(ctx context.Context, key string) (MarginFundingDataV2, error) { +func (e *Exchange) GetV2FundingInfo(ctx context.Context, key string) (MarginFundingDataV2, error) { var resp []any var response MarginFundingDataV2 - err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(bitfinexV2FundingInfo, key), nil, &resp, @@ -322,7 +322,7 @@ func (b *Bitfinex) GetV2FundingInfo(ctx context.Context, key string) (MarginFund response.Sym = sym response.Symbol = symbol if len(fundingData) < 4 { - return response, fmt.Errorf("%v GetV2FundingInfo: invalid length of fundingData", b.Name) + return response, fmt.Errorf("%v GetV2FundingInfo: invalid length of fundingData", e.Name) } if response.Data.YieldLoan, ok = fundingData[0].(float64); !ok { return response, errors.New("type conversion failed for YieldLoan") @@ -340,10 +340,10 @@ func (b *Bitfinex) GetV2FundingInfo(ctx context.Context, key string) (MarginFund } // GetAccountInfoV2 gets V2 account data -func (b *Bitfinex) GetAccountInfoV2(ctx context.Context) (AccountV2Data, error) { +func (e *Exchange) GetAccountInfoV2(ctx context.Context) (AccountV2Data, error) { var resp AccountV2Data var data []any - err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2AccountInfo, nil, &data, @@ -352,7 +352,7 @@ func (b *Bitfinex) GetAccountInfoV2(ctx context.Context) (AccountV2Data, error) return resp, err } if len(data) < 8 { - return resp, fmt.Errorf("%v GetAccountInfoV2: invalid length of data", b.Name) + return resp, fmt.Errorf("%v GetAccountInfoV2: invalid length of data", e.Name) } var ok bool var tempString string @@ -385,9 +385,9 @@ func (b *Bitfinex) GetAccountInfoV2(ctx context.Context) (AccountV2Data, error) } // GetV2Balances gets v2 balances -func (b *Bitfinex) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { +func (e *Exchange) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { var data [][4]any - err := b.SendAuthenticatedHTTPRequestV2(ctx, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2Balances, nil, @@ -425,14 +425,14 @@ func (b *Bitfinex) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { } // GetPairs gets pairs for different assets -func (b *Bitfinex) GetPairs(ctx context.Context, a asset.Item) ([]string, error) { +func (e *Exchange) GetPairs(ctx context.Context, a asset.Item) ([]string, error) { switch a { case asset.Spot: - list, err := b.GetSiteListConfigData(ctx, bitfinexSpotPairs) + list, err := e.GetSiteListConfigData(ctx, bitfinexSpotPairs) if err != nil { return nil, err } - filter, err := b.GetSiteListConfigData(ctx, bitfinexSecuritiesPairs) + filter, err := e.GetSiteListConfigData(ctx, bitfinexSecuritiesPairs) if err != nil { return nil, err } @@ -445,11 +445,11 @@ func (b *Bitfinex) GetPairs(ctx context.Context, a asset.Item) ([]string, error) } return filtered, nil case asset.Margin: - return b.GetSiteListConfigData(ctx, bitfinexMarginPairs) + return e.GetSiteListConfigData(ctx, bitfinexMarginPairs) case asset.Futures: - return b.GetSiteListConfigData(ctx, bitfinexFuturesPairs) + return e.GetSiteListConfigData(ctx, bitfinexFuturesPairs) case asset.MarginFunding: - funding, err := b.GetTickerBatch(ctx) + funding, err := e.GetTickerBatch(ctx) if err != nil { return nil, err } @@ -463,21 +463,21 @@ func (b *Bitfinex) GetPairs(ctx context.Context, a asset.Item) ([]string, error) } return pairs, nil default: - return nil, fmt.Errorf("%v GetPairs: %v %w", b.Name, a, asset.ErrNotSupported) + return nil, fmt.Errorf("%v GetPairs: %v %w", e.Name, a, asset.ErrNotSupported) } } // GetSiteListConfigData returns site configuration data by pub:list:{Object}:{Detail} // string sets. // NOTE: See https://docs.bitfinex.com/reference/rest-public-conf -func (b *Bitfinex) GetSiteListConfigData(ctx context.Context, set string) ([]string, error) { +func (e *Exchange) GetSiteListConfigData(ctx context.Context, set string) ([]string, error) { if set == "" { return nil, errSetCannotBeEmpty } var resp [][]string path := bitfinexAPIVersion2 + set - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, status) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, status) if err != nil { return nil, err } @@ -490,7 +490,7 @@ func (b *Bitfinex) GetSiteListConfigData(ctx context.Context, set string) ([]str // GetSiteInfoConfigData returns site configuration data by pub:info:{AssetType} as a map // path should be bitfinexInfoPairs or bitfinexInfoPairsFuture??? // NOTE: See https://docs.bitfinex.com/reference/rest-public-conf -func (b *Bitfinex) GetSiteInfoConfigData(ctx context.Context, assetType asset.Item) ([]order.MinMaxLevel, error) { +func (e *Exchange) GetSiteInfoConfigData(ctx context.Context, assetType asset.Item) ([]order.MinMaxLevel, error) { var path string switch assetType { case asset.Spot: @@ -503,7 +503,7 @@ func (b *Bitfinex) GetSiteInfoConfigData(ctx context.Context, assetType asset.It url := bitfinexAPIVersion2 + path var resp [][][]any - err := b.SendHTTPRequest(ctx, exchange.RestSpot, url, &resp, status) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, url, &resp, status) if err != nil { return nil, err } @@ -554,7 +554,7 @@ func (b *Bitfinex) GetSiteInfoConfigData(ctx context.Context, assetType asset.It } // GetDerivativeStatusInfo gets status data for the queried derivative -func (b *Bitfinex) GetDerivativeStatusInfo(ctx context.Context, keys, startTime, endTime string, sort, limit int64) ([]DerivativeDataResponse, error) { +func (e *Exchange) GetDerivativeStatusInfo(ctx context.Context, keys, startTime, endTime string, sort, limit int64) ([]DerivativeDataResponse, error) { params := url.Values{} params.Set("keys", keys) if startTime != "" { @@ -573,14 +573,14 @@ func (b *Bitfinex) GetDerivativeStatusInfo(ctx context.Context, keys, startTime, var result [][]any path := bitfinexAPIVersion2 + bitfinexDerivativeData + params.Encode() - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &result, status) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result, status) if err != nil { return nil, err } finalResp := make([]DerivativeDataResponse, len(result)) for z := range result { if len(result[z]) < 19 { - return finalResp, fmt.Errorf("%v GetDerivativeStatusInfo: invalid response, array length too small, check api docs for updates", b.Name) + return finalResp, fmt.Errorf("%v GetDerivativeStatusInfo: invalid response, array length too small, check api docs for updates", e.Name) } var response DerivativeDataResponse var ok bool @@ -629,13 +629,13 @@ func (b *Bitfinex) GetDerivativeStatusInfo(ctx context.Context, keys, startTime, } // GetTickerBatch returns all supported ticker information -func (b *Bitfinex) GetTickerBatch(ctx context.Context) (map[string]*Ticker, error) { +func (e *Exchange) GetTickerBatch(ctx context.Context) (map[string]*Ticker, error) { var response [][]any path := bitfinexAPIVersion2 + bitfinexTickerBatch + "?symbols=ALL" - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerBatch) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerBatch) if err != nil { return nil, err } @@ -661,12 +661,12 @@ func (b *Bitfinex) GetTickerBatch(ctx context.Context) (map[string]*Ticker, erro } // GetTicker returns ticker information for one symbol -func (b *Bitfinex) GetTicker(ctx context.Context, symbol string) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (*Ticker, error) { var response []any path := bitfinexAPIVersion2 + bitfinexTicker + symbol - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerFunction) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerFunction) if err != nil { return nil, err } @@ -750,7 +750,7 @@ func tickerFromFundingResp(symbol string, respAny []any) (*Ticker, error) { // timestampStart is a millisecond timestamp // timestampEnd is a millisecond timestamp // reOrderResp reorders the returned data. -func (b *Bitfinex) GetTrades(ctx context.Context, currencyPair string, limit uint64, start, end time.Time, reOrderResp bool) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, currencyPair string, limit uint64, start, end time.Time, reOrderResp bool) ([]Trade, error) { v := url.Values{} if limit > 0 { v.Set("limit", strconv.FormatUint(limit, 10)) @@ -769,7 +769,7 @@ func (b *Bitfinex) GetTrades(ctx context.Context, currencyPair string, limit uin path := common.EncodeURLValues(bitfinexAPIVersion2+bitfinexTrades+currencyPair+"/hist", v) var resp []Trade - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, tradeRateLimit) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, tradeRateLimit) } // GetOrderbook retrieves the orderbook bid and ask price points for a currency @@ -778,14 +778,14 @@ func (b *Bitfinex) GetTrades(ctx context.Context, currencyPair string, limit uin // precision - P0,P1,P2,P3,R0 // Values can contain limit amounts for both the asks and bids - Example // "len" = 100 -func (b *Bitfinex) GetOrderbook(ctx context.Context, symbol, precision string, limit int64) (Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, symbol, precision string, limit int64) (Orderbook, error) { u := url.Values{} if limit > 0 { u.Set("len", strconv.FormatInt(limit, 10)) } path := bitfinexAPIVersion2 + bitfinexOrderbook + symbol + "/" + precision + "?" + u.Encode() var response [][]any - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, orderbookFunction) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, orderbookFunction) if err != nil { return Orderbook{}, err } @@ -894,10 +894,10 @@ func (b *Bitfinex) GetOrderbook(ctx context.Context, symbol, precision string, l } // GetStats returns various statistics about the requested pair -func (b *Bitfinex) GetStats(ctx context.Context, symbol string) ([]Stat, error) { +func (e *Exchange) GetStats(ctx context.Context, symbol string) ([]Stat, error) { var response []Stat path := bitfinexAPIVersion + bitfinexStats + symbol - return response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, statsV1) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, statsV1) } // GetFundingBook the entire margin funding book for both bids and asks sides @@ -905,11 +905,11 @@ func (b *Bitfinex) GetStats(ctx context.Context, symbol string) ([]Stat, error) // symbol - example "USD" // WARNING: Orderbook now has this support, will be deprecated once a full // conversion to full V2 API update is done. -func (b *Bitfinex) GetFundingBook(ctx context.Context, symbol string) (FundingBook, error) { +func (e *Exchange) GetFundingBook(ctx context.Context, symbol string) (FundingBook, error) { response := FundingBook{} path := bitfinexAPIVersion + bitfinexLendbook + symbol - if err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, fundingbook); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, fundingbook); err != nil { return response, err } @@ -920,19 +920,19 @@ func (b *Bitfinex) GetFundingBook(ctx context.Context, symbol string) (FundingBo // currency: total amount provided and Flash Return Rate (in % by 365 days) // over time // Symbol - example "USD" -func (b *Bitfinex) GetLends(ctx context.Context, symbol string, values url.Values) ([]Lends, error) { +func (e *Exchange) GetLends(ctx context.Context, symbol string, values url.Values) ([]Lends, error) { var response []Lends path := common.EncodeURLValues(bitfinexAPIVersion+ bitfinexLends+ symbol, values) - return response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, lends) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, lends) } // GetCandles returns candle chart data // timeFrame values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '1W', '14D', '1M' // section values: last or hist -func (b *Bitfinex) GetCandles(ctx context.Context, symbol, timeFrame string, start, end time.Time, limit uint64, historic bool) ([]Candle, error) { +func (e *Exchange) GetCandles(ctx context.Context, symbol, timeFrame string, start, end time.Time, limit uint64, historic bool) ([]Candle, error) { var fundingPeriod string if symbol[0] == 'f' { fundingPeriod = ":p30" @@ -955,13 +955,13 @@ func (b *Bitfinex) GetCandles(ctx context.Context, symbol, timeFrame string, sta } var response []Candle - return response, b.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(path+"/hist", v), &response, candle) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(path+"/hist", v), &response, candle) } path += "/last" var c Candle - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &c, candle) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &c, candle) if err != nil { return nil, err } @@ -969,20 +969,20 @@ func (b *Bitfinex) GetCandles(ctx context.Context, symbol, timeFrame string, sta } // GetConfigurations fetches currency and symbol site configuration data. -func (b *Bitfinex) GetConfigurations() error { +func (e *Exchange) GetConfigurations() error { return common.ErrNotYetImplemented } // GetStatus returns different types of platform information - currently // supports derivatives pair status only. -func (b *Bitfinex) GetStatus() error { +func (e *Exchange) GetStatus() error { return common.ErrNotYetImplemented } // GetLiquidationFeed returns liquidations. By default it will retrieve the most // recent liquidations, but time-specific data can be retrieved using // timestamps. -func (b *Bitfinex) GetLiquidationFeed() error { +func (e *Exchange) GetLiquidationFeed() error { return common.ErrNotYetImplemented } @@ -993,7 +993,7 @@ func (b *Bitfinex) GetLiquidationFeed() error { // profit // Allowed time frames are 3h, 1w and 1M // Allowed symbols are trading pairs (e.g. tBTCUSD, tETHUSD and tGLOBAL:USD) -func (b *Bitfinex) GetLeaderboard(ctx context.Context, key, timeframe, symbol string, sort, limit int, start, end string) ([]LeaderboardEntry, error) { +func (e *Exchange) GetLeaderboard(ctx context.Context, key, timeframe, symbol string, sort, limit int, start, end string) ([]LeaderboardEntry, error) { validLeaderboardKey := func(input string) bool { switch input { case LeaderboardUnrealisedProfitPeriodDelta, @@ -1029,7 +1029,7 @@ func (b *Bitfinex) GetLeaderboard(ctx context.Context, key, timeframe, symbol st } path = common.EncodeURLValues(path, vals) var resp []any - if err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, leaderBoardReqRate); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, leaderBoardReqRate); err != nil { return nil, err } @@ -1079,19 +1079,19 @@ func (b *Bitfinex) GetLeaderboard(ctx context.Context, key, timeframe, symbol st // GetMarketAveragePrice calculates the average execution price for Trading or // rate for Margin funding -func (b *Bitfinex) GetMarketAveragePrice() error { +func (e *Exchange) GetMarketAveragePrice() error { return common.ErrNotYetImplemented } // GetForeignExchangeRate calculates the exchange rate between two currencies -func (b *Bitfinex) GetForeignExchangeRate() error { +func (e *Exchange) GetForeignExchangeRate() error { return common.ErrNotYetImplemented } // GetAccountFees returns information about your account trading fees -func (b *Bitfinex) GetAccountFees(ctx context.Context) ([]AccountInfo, error) { +func (e *Exchange) GetAccountFees(ctx context.Context) ([]AccountInfo, error) { var responses []AccountInfo - return responses, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return responses, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountInfo, nil, &responses, @@ -1099,9 +1099,9 @@ func (b *Bitfinex) GetAccountFees(ctx context.Context) ([]AccountInfo, error) { } // GetWithdrawalFees - Gets all fee rates for withdrawals -func (b *Bitfinex) GetWithdrawalFees(ctx context.Context) (AccountFees, error) { +func (e *Exchange) GetWithdrawalFees(ctx context.Context) (AccountFees, error) { response := AccountFees{} - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountFees, nil, &response, @@ -1110,10 +1110,10 @@ func (b *Bitfinex) GetWithdrawalFees(ctx context.Context) (AccountFees, error) { // GetAccountSummary returns a 30-day summary of your trading volume and return // on margin funding -func (b *Bitfinex) GetAccountSummary(ctx context.Context) (AccountSummary, error) { +func (e *Exchange) GetAccountSummary(ctx context.Context) (AccountSummary, error) { response := AccountSummary{} - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountSummary, nil, &response, @@ -1127,7 +1127,7 @@ func (b *Bitfinex) GetAccountSummary(ctx context.Context) (AccountSummary, error // which are "exchange", "trading" and "deposit" respectively). If none is set, // "funding" will be used by default // renew - Default is 0. If set to 1, will return a new unused deposit address -func (b *Bitfinex) NewDeposit(ctx context.Context, method, walletName string, renew uint8) (*Deposit, error) { +func (e *Exchange) NewDeposit(ctx context.Context, method, walletName string, renew uint8) (*Deposit, error) { if walletName == "" { walletName = "funding" } else if !slices.Contains(AcceptedWalletNames, walletName) { @@ -1143,7 +1143,7 @@ func (b *Bitfinex) NewDeposit(ctx context.Context, method, walletName string, re req["op_renew"] = renew var result []any - err := b.SendAuthenticatedHTTPRequestV2(ctx, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexDepositAddress, @@ -1197,9 +1197,9 @@ func (b *Bitfinex) NewDeposit(ctx context.Context, method, walletName string, re // GetKeyPermissions checks the permissions of the key being used to generate // this request. -func (b *Bitfinex) GetKeyPermissions(ctx context.Context) (KeyPermissions, error) { +func (e *Exchange) GetKeyPermissions(ctx context.Context) (KeyPermissions, error) { response := KeyPermissions{} - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexKeyPermissions, nil, &response, @@ -1207,9 +1207,9 @@ func (b *Bitfinex) GetKeyPermissions(ctx context.Context) (KeyPermissions, error } // GetMarginInfo shows your trading wallet information for margin trading -func (b *Bitfinex) GetMarginInfo(ctx context.Context) ([]MarginInfo, error) { +func (e *Exchange) GetMarginInfo(ctx context.Context) ([]MarginInfo, error) { var response []MarginInfo - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginInfo, nil, &response, @@ -1217,9 +1217,9 @@ func (b *Bitfinex) GetMarginInfo(ctx context.Context) ([]MarginInfo, error) { } // GetAccountBalance returns full wallet balance information -func (b *Bitfinex) GetAccountBalance(ctx context.Context) ([]Balance, error) { +func (e *Exchange) GetAccountBalance(ctx context.Context) ([]Balance, error) { var response []Balance - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexBalances, nil, &response, @@ -1231,7 +1231,7 @@ func (b *Bitfinex) GetAccountBalance(ctx context.Context) ([]Balance, error) { // Currency - example "BTC" // WalletFrom - example "exchange" // WalletTo - example "deposit" -func (b *Bitfinex) WalletTransfer(ctx context.Context, amount float64, currency, walletFrom, walletTo string) (WalletTransfer, error) { +func (e *Exchange) WalletTransfer(ctx context.Context, amount float64, currency, walletFrom, walletTo string) (WalletTransfer, error) { var response []WalletTransfer req := make(map[string]any) req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) @@ -1239,7 +1239,7 @@ func (b *Bitfinex) WalletTransfer(ctx context.Context, amount float64, currency, req["walletfrom"] = walletFrom req["walletto"] = walletTo - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexTransfer, req, &response, @@ -1256,7 +1256,7 @@ func (b *Bitfinex) WalletTransfer(ctx context.Context, amount float64, currency, // WithdrawCryptocurrency requests a withdrawal from one of your wallets. // For FIAT, use WithdrawFIAT -func (b *Bitfinex) WithdrawCryptocurrency(ctx context.Context, wallet, address, paymentID, curr string, amount float64) (Withdrawal, error) { +func (e *Exchange) WithdrawCryptocurrency(ctx context.Context, wallet, address, paymentID, curr string, amount float64) (Withdrawal, error) { var response []Withdrawal req := make(map[string]any) req["withdraw_type"] = strings.ToLower(curr) @@ -1267,7 +1267,7 @@ func (b *Bitfinex) WithdrawCryptocurrency(ctx context.Context, wallet, address, req["payment_id"] = paymentID } - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexWithdrawal, req, &response, @@ -1284,7 +1284,7 @@ func (b *Bitfinex) WithdrawCryptocurrency(ctx context.Context, wallet, address, } // WithdrawFIAT Sends an authenticated request to withdraw FIAT currency -func (b *Bitfinex) WithdrawFIAT(ctx context.Context, withdrawalType, walletType string, withdrawRequest *withdraw.Request) (Withdrawal, error) { +func (e *Exchange) WithdrawFIAT(ctx context.Context, withdrawalType, walletType string, withdrawRequest *withdraw.Request) (Withdrawal, error) { var response []Withdrawal req := make(map[string]any) @@ -1312,7 +1312,7 @@ func (b *Bitfinex) WithdrawFIAT(ctx context.Context, withdrawalType, walletType req["intermediary_bank_swift"] = withdrawRequest.Fiat.IntermediarySwiftCode } - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexWithdrawal, req, &response, @@ -1330,7 +1330,7 @@ func (b *Bitfinex) WithdrawFIAT(ctx context.Context, withdrawalType, walletType // NewOrder submits a new order and returns a order information // Major Upgrade needed on this function to include all query params -func (b *Bitfinex) NewOrder(ctx context.Context, currencyPair, orderType string, amount, price float64, buy, hidden bool) (Order, error) { +func (e *Exchange) NewOrder(ctx context.Context, currencyPair, orderType string, amount, price float64, buy, hidden bool) (Order, error) { if !slices.Contains(AcceptedOrderType, orderType) { return Order{}, fmt.Errorf("order type %s not accepted", orderType) } @@ -1347,7 +1347,7 @@ func (b *Bitfinex) NewOrder(ctx context.Context, currencyPair, orderType string, req["side"] = order.Buy.Lower() } - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderNew, req, &response, @@ -1356,7 +1356,7 @@ func (b *Bitfinex) NewOrder(ctx context.Context, currencyPair, orderType string, // OrderUpdate will send an update signal for an existing order // and attempt to modify it -func (b *Bitfinex) OrderUpdate(ctx context.Context, orderID, groupID, clientOrderID string, amount, price, leverage float64) (*Order, error) { +func (e *Exchange) OrderUpdate(ctx context.Context, orderID, groupID, clientOrderID string, amount, price, leverage float64) (*Order, error) { req := make(map[string]any) if orderID != "" { req["id"] = orderID @@ -1373,7 +1373,7 @@ func (b *Bitfinex) OrderUpdate(ctx context.Context, orderID, groupID, clientOrde req["lev"] = strconv.FormatFloat(leverage, 'f', -1, 64) } response := Order{} - return &response, b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, + return &response, e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderUpdate, req, &response, @@ -1381,12 +1381,12 @@ func (b *Bitfinex) OrderUpdate(ctx context.Context, orderID, groupID, clientOrde } // NewOrderMulti allows several new orders at once -func (b *Bitfinex) NewOrderMulti(ctx context.Context, orders []PlaceOrder) (OrderMultiResponse, error) { +func (e *Exchange) NewOrderMulti(ctx context.Context, orders []PlaceOrder) (OrderMultiResponse, error) { response := OrderMultiResponse{} req := make(map[string]any) req["orders"] = orders - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderNewMulti, req, &response, @@ -1394,12 +1394,12 @@ func (b *Bitfinex) NewOrderMulti(ctx context.Context, orders []PlaceOrder) (Orde } // CancelExistingOrder cancels a single order by OrderID -func (b *Bitfinex) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { response := Order{} req := make(map[string]any) req["order_id"] = orderID - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancel, req, &response, @@ -1407,11 +1407,11 @@ func (b *Bitfinex) CancelExistingOrder(ctx context.Context, orderID int64) (Orde } // CancelMultipleOrders cancels multiple orders -func (b *Bitfinex) CancelMultipleOrders(ctx context.Context, orderIDs []int64) (string, error) { +func (e *Exchange) CancelMultipleOrders(ctx context.Context, orderIDs []int64) (string, error) { response := GenericResponse{} req := make(map[string]any) req["order_ids"] = orderIDs - return response.Result, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response.Result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelMulti, req, nil, @@ -1419,7 +1419,7 @@ func (b *Bitfinex) CancelMultipleOrders(ctx context.Context, orderIDs []int64) ( } // CancelMultipleOrdersV2 cancels multiple orders -func (b *Bitfinex) CancelMultipleOrdersV2(ctx context.Context, orderID, clientOrderID, groupOrderID int64, clientOrderIDDate time.Time, allOrders bool) ([]CancelMultiOrderResponse, error) { +func (e *Exchange) CancelMultipleOrdersV2(ctx context.Context, orderID, clientOrderID, groupOrderID int64, clientOrderIDDate time.Time, allOrders bool) ([]CancelMultiOrderResponse, error) { var response []any req := make(map[string]any) if orderID > 0 { @@ -1438,7 +1438,7 @@ func (b *Bitfinex) CancelMultipleOrdersV2(ctx context.Context, orderID, clientOr req["all"] = 1 } - err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelMulti, req, &response, @@ -1565,10 +1565,10 @@ func (b *Bitfinex) CancelMultipleOrdersV2(ctx context.Context, orderID, clientOr } // CancelAllExistingOrders cancels all active and open orders -func (b *Bitfinex) CancelAllExistingOrders(ctx context.Context) (string, error) { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context) (string, error) { response := GenericResponse{} - return response.Result, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response.Result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelAll, nil, nil, @@ -1576,7 +1576,7 @@ func (b *Bitfinex) CancelAllExistingOrders(ctx context.Context) (string, error) } // ReplaceOrder replaces an older order with a new order -func (b *Bitfinex) ReplaceOrder(ctx context.Context, orderID int64, symbol string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { +func (e *Exchange) ReplaceOrder(ctx context.Context, orderID int64, symbol string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { response := Order{} req := make(map[string]any) req["order_id"] = orderID @@ -1593,7 +1593,7 @@ func (b *Bitfinex) ReplaceOrder(ctx context.Context, orderID int64, symbol strin req["side"] = order.Sell.Lower() } - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelReplace, req, &response, @@ -1601,12 +1601,12 @@ func (b *Bitfinex) ReplaceOrder(ctx context.Context, orderID int64, symbol strin } // GetOrderStatus returns order status information -func (b *Bitfinex) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { +func (e *Exchange) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { orderStatus := Order{} req := make(map[string]any) req["order_id"] = orderID - return orderStatus, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return orderStatus, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderStatus, req, &orderStatus, @@ -1614,14 +1614,14 @@ func (b *Bitfinex) GetOrderStatus(ctx context.Context, orderID int64) (Order, er } // GetInactiveOrders returns order status information -func (b *Bitfinex) GetInactiveOrders(ctx context.Context, symbol string, ids ...int64) ([]Order, error) { +func (e *Exchange) GetInactiveOrders(ctx context.Context, symbol string, ids ...int64) ([]Order, error) { var response []Order req := make(map[string]any) req["limit"] = 2500 if len(ids) > 0 { req["ids"] = ids } - return response, b.SendAuthenticatedHTTPRequestV2( + return response, e.SendAuthenticatedHTTPRequestV2( ctx, exchange.RestSpot, http.MethodPost, @@ -1632,13 +1632,13 @@ func (b *Bitfinex) GetInactiveOrders(ctx context.Context, symbol string, ids ... } // GetOpenOrders returns all active orders and statuses -func (b *Bitfinex) GetOpenOrders(ctx context.Context, ids ...int64) ([]Order, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, ids ...int64) ([]Order, error) { var response []Order req := make(map[string]any) if len(ids) > 0 { req["ids"] = ids } - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrders, req, &response, @@ -1646,10 +1646,10 @@ func (b *Bitfinex) GetOpenOrders(ctx context.Context, ids ...int64) ([]Order, er } // GetActivePositions returns an array of active positions -func (b *Bitfinex) GetActivePositions(ctx context.Context) ([]Position, error) { +func (e *Exchange) GetActivePositions(ctx context.Context) ([]Position, error) { var response []Position - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexPositions, nil, &response, @@ -1657,12 +1657,12 @@ func (b *Bitfinex) GetActivePositions(ctx context.Context) ([]Position, error) { } // ClaimPosition allows positions to be claimed -func (b *Bitfinex) ClaimPosition(ctx context.Context, positionID int) (Position, error) { +func (e *Exchange) ClaimPosition(ctx context.Context, positionID int) (Position, error) { response := Position{} req := make(map[string]any) req["position_id"] = positionID - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexClaimPosition, nil, nil, @@ -1670,7 +1670,7 @@ func (b *Bitfinex) ClaimPosition(ctx context.Context, positionID int) (Position, } // GetBalanceHistory returns balance history for the account -func (b *Bitfinex) GetBalanceHistory(ctx context.Context, symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { +func (e *Exchange) GetBalanceHistory(ctx context.Context, symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { var response []BalanceHistory req := make(map[string]any) req["currency"] = symbol @@ -1688,7 +1688,7 @@ func (b *Bitfinex) GetBalanceHistory(ctx context.Context, symbol string, timeSin req["wallet"] = wallet } - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexHistory, req, &response, @@ -1696,7 +1696,7 @@ func (b *Bitfinex) GetBalanceHistory(ctx context.Context, symbol string, timeSin } // GetMovementHistory returns an array of past deposits and withdrawals -func (b *Bitfinex) GetMovementHistory(ctx context.Context, symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { +func (e *Exchange) GetMovementHistory(ctx context.Context, symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { req := make(map[string]any) req["currency"] = symbol @@ -1715,11 +1715,11 @@ func (b *Bitfinex) GetMovementHistory(ctx context.Context, symbol, method string var resp []MovementHistory path := bitfinexV2Auth + "r/" + bitfinexHistoryMovements + "/" + symbol + "/" + bitfinexHistoryShort - return resp, b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, path, req, &resp, orderMulti) + return resp, e.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, path, req, &resp, orderMulti) } // GetTradeHistory returns past executed trades -func (b *Bitfinex) GetTradeHistory(ctx context.Context, currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { var response []TradeHistory req := make(map[string]any) req["currency"] = currencyPair @@ -1735,7 +1735,7 @@ func (b *Bitfinex) GetTradeHistory(ctx context.Context, currencyPair string, tim req["reverse"] = reverse } - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexTradeHistory, req, &response, @@ -1743,7 +1743,7 @@ func (b *Bitfinex) GetTradeHistory(ctx context.Context, currencyPair string, tim } // NewOffer submits a new offer -func (b *Bitfinex) NewOffer(ctx context.Context, symbol string, amount, rate float64, period int64, direction string) (Offer, error) { +func (e *Exchange) NewOffer(ctx context.Context, symbol string, amount, rate float64, period int64, direction string) (Offer, error) { response := Offer{} req := make(map[string]any) req["currency"] = symbol @@ -1752,7 +1752,7 @@ func (b *Bitfinex) NewOffer(ctx context.Context, symbol string, amount, rate flo req["period"] = period req["direction"] = direction - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOfferNew, req, &response, @@ -1760,12 +1760,12 @@ func (b *Bitfinex) NewOffer(ctx context.Context, symbol string, amount, rate flo } // CancelOffer cancels offer by offerID -func (b *Bitfinex) CancelOffer(ctx context.Context, offerID int64) (Offer, error) { +func (e *Exchange) CancelOffer(ctx context.Context, offerID int64) (Offer, error) { response := Offer{} req := make(map[string]any) req["offer_id"] = offerID - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOfferCancel, req, &response, @@ -1774,12 +1774,12 @@ func (b *Bitfinex) CancelOffer(ctx context.Context, offerID int64) (Offer, error // GetOfferStatus checks offer status whether it has been cancelled, execute or // is still active -func (b *Bitfinex) GetOfferStatus(ctx context.Context, offerID int64) (Offer, error) { +func (e *Exchange) GetOfferStatus(ctx context.Context, offerID int64) (Offer, error) { response := Offer{} req := make(map[string]any) req["offer_id"] = offerID - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderStatus, req, &response, @@ -1787,10 +1787,10 @@ func (b *Bitfinex) GetOfferStatus(ctx context.Context, offerID int64) (Offer, er } // GetActiveCredits returns all available credits -func (b *Bitfinex) GetActiveCredits(ctx context.Context) ([]Offer, error) { +func (e *Exchange) GetActiveCredits(ctx context.Context) ([]Offer, error) { var response []Offer - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexActiveCredits, nil, &response, @@ -1798,10 +1798,10 @@ func (b *Bitfinex) GetActiveCredits(ctx context.Context) ([]Offer, error) { } // GetActiveOffers returns all current active offers -func (b *Bitfinex) GetActiveOffers(ctx context.Context) ([]Offer, error) { +func (e *Exchange) GetActiveOffers(ctx context.Context) ([]Offer, error) { var response []Offer - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOffers, nil, &response, @@ -1809,10 +1809,10 @@ func (b *Bitfinex) GetActiveOffers(ctx context.Context) ([]Offer, error) { } // GetActiveMarginFunding returns an array of active margin funds -func (b *Bitfinex) GetActiveMarginFunding(ctx context.Context) ([]MarginFunds, error) { +func (e *Exchange) GetActiveMarginFunding(ctx context.Context) ([]MarginFunds, error) { var response []MarginFunds - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginActiveFunds, nil, &response, @@ -1821,10 +1821,10 @@ func (b *Bitfinex) GetActiveMarginFunding(ctx context.Context) ([]MarginFunds, e // GetUnusedMarginFunds returns an array of funding borrowed but not currently // used -func (b *Bitfinex) GetUnusedMarginFunds(ctx context.Context) ([]MarginFunds, error) { +func (e *Exchange) GetUnusedMarginFunds(ctx context.Context) ([]MarginFunds, error) { var response []MarginFunds - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginUnusedFunds, nil, &response, @@ -1833,10 +1833,10 @@ func (b *Bitfinex) GetUnusedMarginFunds(ctx context.Context) ([]MarginFunds, err // GetMarginTotalTakenFunds returns an array of active funding used in a // position -func (b *Bitfinex) GetMarginTotalTakenFunds(ctx context.Context) ([]MarginTotalTakenFunds, error) { +func (e *Exchange) GetMarginTotalTakenFunds(ctx context.Context) ([]MarginTotalTakenFunds, error) { var response []MarginTotalTakenFunds - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginTotalFunds, nil, &response, @@ -1844,12 +1844,12 @@ func (b *Bitfinex) GetMarginTotalTakenFunds(ctx context.Context) ([]MarginTotalT } // CloseMarginFunding closes an unused or used taken fund -func (b *Bitfinex) CloseMarginFunding(ctx context.Context, swapID int64) (Offer, error) { +func (e *Exchange) CloseMarginFunding(ctx context.Context, swapID int64) (Offer, error) { response := Offer{} req := make(map[string]any) req["swap_id"] = swapID - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginClose, req, &response, @@ -1857,8 +1857,8 @@ func (b *Bitfinex) CloseMarginFunding(ctx context.Context, swapID int64) (Offer, } // SendHTTPRequest sends an unauthenticated request -func (b *Bitfinex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any, e request.EndpointLimit) error { - endpoint, err := b.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any, epl request.EndpointLimit) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -1866,34 +1866,34 @@ func (b *Bitfinex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, e, func() (*request.Item, error) { + return e.SendPayload(ctx, epl, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated http request and json // unmarshals result to a supplied variable -func (b *Bitfinex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any, endpoint request.EndpointLimit) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any, endpoint request.EndpointLimit) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := b.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } fullPath := ePoint + bitfinexAPIVersion + path - return b.SendPayload(ctx, endpoint, func() (*request.Item, error) { + return e.SendPayload(ctx, endpoint, func() (*request.Item, error) { req := make(map[string]any) req["request"] = bitfinexAPIVersion + path - req["nonce"] = b.Requester.GetNonce(nonce.UnixNano).String() + req["nonce"] = e.Requester.GetNonce(nonce.UnixNano).String() maps.Copy(req, params) @@ -1919,26 +1919,26 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange Headers: headers, Result: result, NonceEnabled: true, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) } // SendAuthenticatedHTTPRequestV2 sends an authenticated http request and json // unmarshals result to a supplied variable -func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any, endpoint request.EndpointLimit) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequestV2(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any, endpoint request.EndpointLimit) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := b.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } - return b.SendPayload(ctx, endpoint, func() (*request.Item, error) { + return e.SendPayload(ctx, endpoint, func() (*request.Item, error) { var body io.Reader var payload []byte if len(params) != 0 { @@ -1969,24 +1969,24 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ctx context.Context, ep exchan Body: body, Result: result, NonceEnabled: true, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *Bitfinex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - accountInfos, err := b.GetAccountFees(ctx) + accountInfos, err := e.GetAccountFees(ctx) if err != nil { return 0, err } - fee, err = b.CalculateTradingFee(accountInfos, + fee, err = e.CalculateTradingFee(accountInfos, feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.Pair.Base, @@ -1998,11 +1998,11 @@ func (b *Bitfinex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) // TODO: fee is charged when < $1000USD is transferred, need to infer value in some way fee = 0 case exchange.CryptocurrencyWithdrawalFee: - acc, err := b.GetWithdrawalFees(ctx) + acc, err := e.GetWithdrawalFees(ctx) if err != nil { return 0, err } - fee, err = b.GetCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base, acc) + fee, err = e.GetCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base, acc) if err != nil { return 0, err } @@ -2026,7 +2026,7 @@ func getOfflineTradeFee(price, amount float64) float64 { } // GetCryptocurrencyWithdrawalFee returns an estimate of fee based on type of transaction -func (b *Bitfinex) GetCryptocurrencyWithdrawalFee(c currency.Code, accountFees AccountFees) (float64, error) { +func (e *Exchange) GetCryptocurrencyWithdrawalFee(c currency.Code, accountFees AccountFees) (float64, error) { fee, ok := accountFees.Withdraw[c.String()] if !ok { return 0, fmt.Errorf("withdrawal fee for %s not found", c.String()) @@ -2043,7 +2043,7 @@ func getInternationalBankWithdrawalFee(amount float64) float64 { } // CalculateTradingFee returns an estimate of fee based on type of whether is maker or taker fee -func (b *Bitfinex) CalculateTradingFee(i []AccountInfo, purchasePrice, amount float64, c currency.Code, isMaker bool) (fee float64, err error) { +func (e *Exchange) CalculateTradingFee(i []AccountInfo, purchasePrice, amount float64, c currency.Code, isMaker bool) (fee float64, err error) { for x := range i { for y := range i[x].Fees { if c.String() == i[x].Fees[y].Pairs { @@ -2064,13 +2064,13 @@ func (b *Bitfinex) CalculateTradingFee(i []AccountInfo, purchasePrice, amount fl // PopulateAcceptableMethods retrieves all accepted currency strings and // populates a map to check -func (b *Bitfinex) PopulateAcceptableMethods(ctx context.Context) error { +func (e *Exchange) PopulateAcceptableMethods(ctx context.Context) error { if acceptableMethods.loaded() { return nil } var response [][][]any - err := b.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpot, bitfinexAPIVersion2+bitfinexDepositMethod, &response, diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index 5a03c35b00e..2432514fecc 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -38,21 +38,21 @@ const ( ) var ( - b *Bitfinex + e *Exchange btcusdPair = currency.NewBTCUSD() ) func TestMain(m *testing.M) { - b = new(Bitfinex) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bitfinex Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - b.API.AuthenticatedSupport = true - b.API.AuthenticatedWebsocketSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -60,8 +60,8 @@ func TestMain(m *testing.M) { func TestGetV2MarginFunding(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetV2MarginFunding(t.Context(), "fUSD", "2", 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetV2MarginFunding(t.Context(), "fUSD", "2", 2) if err != nil { t.Error(err) } @@ -69,16 +69,16 @@ func TestGetV2MarginFunding(t *testing.T) { func TestGetV2MarginInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetV2MarginInfo(t.Context(), "base") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetV2MarginInfo(t.Context(), "base") if err != nil { t.Error(err) } - _, err = b.GetV2MarginInfo(t.Context(), "tBTCUSD") + _, err = e.GetV2MarginInfo(t.Context(), "tBTCUSD") if err != nil { t.Error(err) } - _, err = b.GetV2MarginInfo(t.Context(), "sym_all") + _, err = e.GetV2MarginInfo(t.Context(), "sym_all") if err != nil { t.Error(err) } @@ -86,8 +86,8 @@ func TestGetV2MarginInfo(t *testing.T) { func TestGetAccountInfoV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAccountInfoV2(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountInfoV2(t.Context()) if err != nil { t.Error(err) } @@ -95,8 +95,8 @@ func TestGetAccountInfoV2(t *testing.T) { func TestGetV2FundingInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetV2FundingInfo(t.Context(), "fUST") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetV2FundingInfo(t.Context(), "fUST") if err != nil { t.Error(err) } @@ -104,8 +104,8 @@ func TestGetV2FundingInfo(t *testing.T) { func TestGetV2Balances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetV2Balances(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetV2Balances(t.Context()) if err != nil { t.Error(err) } @@ -113,7 +113,7 @@ func TestGetV2Balances(t *testing.T) { func TestGetDerivativeStatusInfo(t *testing.T) { t.Parallel() - _, err := b.GetDerivativeStatusInfo(t.Context(), "ALL", "", "", 0, 0) + _, err := e.GetDerivativeStatusInfo(t.Context(), "ALL", "", "", 0, 0) if err != nil { t.Error(err) } @@ -122,12 +122,12 @@ func TestGetDerivativeStatusInfo(t *testing.T) { func TestGetPairs(t *testing.T) { t.Parallel() - _, err := b.GetPairs(t.Context(), asset.Binary) + _, err := e.GetPairs(t.Context(), asset.Binary) require.ErrorIs(t, err, asset.ErrNotSupported) - assets := b.GetAssetTypes(false) + assets := e.GetAssetTypes(false) for x := range assets { - _, err := b.GetPairs(t.Context(), assets[x]) + _, err := e.GetPairs(t.Context(), assets[x]) if err != nil { t.Error(err) } @@ -136,7 +136,7 @@ func TestGetPairs(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) + testexch.UpdatePairsOnce(t, e) } func TestUpdateOrderExecutionLimits(t *testing.T) { @@ -148,12 +148,12 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { }, } for assetItem, pairs := range tests { - if err := b.UpdateOrderExecutionLimits(t.Context(), assetItem); err != nil { + if err := e.UpdateOrderExecutionLimits(t.Context(), assetItem); err != nil { t.Errorf("Error fetching %s pairs for test: %v", assetItem, err) continue } for _, pair := range pairs { - limits, err := b.GetOrderExecutionLimits(assetItem, pair) + limits, err := e.GetOrderExecutionLimits(assetItem, pair) if err != nil { t.Errorf("GetOrderExecutionLimits() error during TestExecutionLimits; Asset: %s Pair: %s Err: %v", assetItem, pair, err) continue @@ -172,7 +172,7 @@ func TestAppendOptionalDelimiter(t *testing.T) { t.Fatal(err) } - b.appendOptionalDelimiter(&curr1) + e.appendOptionalDelimiter(&curr1) if curr1.Delimiter != "" { t.Errorf("Expected no delimiter, received %v", curr1.Delimiter) } @@ -182,7 +182,7 @@ func TestAppendOptionalDelimiter(t *testing.T) { } curr2.Delimiter = "" - b.appendOptionalDelimiter(&curr2) + e.appendOptionalDelimiter(&curr2) if curr2.Delimiter != ":" { t.Errorf("Expected \":\" as a delimiter, received %v", curr2.Delimiter) } @@ -190,7 +190,7 @@ func TestAppendOptionalDelimiter(t *testing.T) { func TestGetPlatformStatus(t *testing.T) { t.Parallel() - result, err := b.GetPlatformStatus(t.Context()) + result, err := e.GetPlatformStatus(t.Context()) if err != nil { t.Errorf("TestGetPlatformStatus error: %s", err) } @@ -202,7 +202,7 @@ func TestGetPlatformStatus(t *testing.T) { func TestGetTickerBatch(t *testing.T) { t.Parallel() - ticks, err := b.GetTickerBatch(t.Context()) + ticks, err := e.GetTickerBatch(t.Context()) require.NoError(t, err, "GetTickerBatch must not error") require.NotEmpty(t, ticks, "GetTickerBatch must return some ticks") require.Contains(t, ticks, "tBTCUSD", "Ticker batch must contain tBTCUSD") @@ -213,7 +213,7 @@ func TestGetTickerBatch(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - tick, err := b.GetTicker(t.Context(), "tBTCUSD") + tick, err := e.GetTicker(t.Context(), "tBTCUSD") require.NoError(t, err, "GetTicker must not error") checkTradeTick(t, tick) } @@ -278,7 +278,7 @@ func TestTickerFromFundingResp(t *testing.T) { func TestGetTickerFunding(t *testing.T) { t.Parallel() - tick, err := b.GetTicker(t.Context(), "fUSD") + tick, err := e.GetTicker(t.Context(), "fUSD") require.NoError(t, err, "GetTicker must not error") checkFundingTick(t, tick) } @@ -309,34 +309,34 @@ func checkFundingTick(tb testing.TB, tick *Ticker) { func TestGetTrades(t *testing.T) { t.Parallel() - r, err := b.GetTrades(t.Context(), "tBTCUSD", 5, time.Time{}, time.Time{}, false) + r, err := e.GetTrades(t.Context(), "tBTCUSD", 5, time.Time{}, time.Time{}, false) require.NoError(t, err, "GetTrades must not error") assert.NotEmpty(t, r, "GetTrades should return some trades") } func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(t.Context(), "tBTCUSD", "R0", 1) + _, err := e.GetOrderbook(t.Context(), "tBTCUSD", "R0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook(t.Context(), "fUSD", "R0", 1) + _, err = e.GetOrderbook(t.Context(), "fUSD", "R0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook(t.Context(), "tBTCUSD", "P0", 1) + _, err = e.GetOrderbook(t.Context(), "tBTCUSD", "P0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook(t.Context(), "fUSD", "P0", 1) + _, err = e.GetOrderbook(t.Context(), "fUSD", "P0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook(t.Context(), "tLINK:UST", "P0", 1) + _, err = e.GetOrderbook(t.Context(), "tLINK:UST", "P0", 1) if err != nil { t.Error(err) } @@ -344,7 +344,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetStats(t *testing.T) { t.Parallel() - _, err := b.GetStats(t.Context(), "btcusd") + _, err := e.GetStats(t.Context(), "btcusd") if err != nil { t.Error(err) } @@ -352,7 +352,7 @@ func TestGetStats(t *testing.T) { func TestGetFundingBook(t *testing.T) { t.Parallel() - _, err := b.GetFundingBook(t.Context(), "usd") + _, err := e.GetFundingBook(t.Context(), "usd") if err != nil { t.Error(err) } @@ -360,7 +360,7 @@ func TestGetFundingBook(t *testing.T) { func TestGetLends(t *testing.T) { t.Parallel() - _, err := b.GetLends(t.Context(), "usd", nil) + _, err := e.GetLends(t.Context(), "usd", nil) if err != nil { t.Error(err) } @@ -368,7 +368,7 @@ func TestGetLends(t *testing.T) { func TestGetCandles(t *testing.T) { t.Parallel() - c, err := b.GetCandles(t.Context(), "fUST", "1D", time.Now().AddDate(0, 0, -1), time.Now(), 10000, true) + c, err := e.GetCandles(t.Context(), "fUST", "1D", time.Now().AddDate(0, -1, 0), time.Now(), 10000, true) require.NoError(t, err, "GetCandles must not error") assert.NotEmpty(t, c, "GetCandles should return some candles") } @@ -376,12 +376,12 @@ func TestGetCandles(t *testing.T) { func TestGetLeaderboard(t *testing.T) { t.Parallel() // Test invalid key - _, err := b.GetLeaderboard(t.Context(), "", "", "", 0, 0, "", "") + _, err := e.GetLeaderboard(t.Context(), "", "", "", 0, 0, "", "") if err == nil { t.Error("an error should have been thrown for an invalid key") } // Test default - _, err = b.GetLeaderboard(t.Context(), + _, err = e.GetLeaderboard(t.Context(), LeaderboardUnrealisedProfitInception, "1M", "tGLOBAL:USD", @@ -394,7 +394,7 @@ func TestGetLeaderboard(t *testing.T) { } // Test params var result []LeaderboardEntry - result, err = b.GetLeaderboard(t.Context(), + result, err = e.GetLeaderboard(t.Context(), LeaderboardUnrealisedProfitInception, "1M", "tGLOBAL:USD", @@ -412,9 +412,9 @@ func TestGetLeaderboard(t *testing.T) { func TestGetAccountFees(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err != nil { t.Error("GetAccountInfo error", err) } @@ -422,8 +422,8 @@ func TestGetAccountFees(t *testing.T) { func TestGetWithdrawalFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWithdrawalFees(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWithdrawalFees(t.Context()) if err != nil { t.Error("GetAccountInfo error", err) } @@ -431,8 +431,8 @@ func TestGetWithdrawalFee(t *testing.T) { func TestGetAccountSummary(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAccountSummary(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountSummary(t.Context()) if err != nil { t.Error(err) } @@ -440,18 +440,18 @@ func TestGetAccountSummary(t *testing.T) { func TestNewDeposit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.NewDeposit(t.Context(), "blabla", "testwallet", 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.NewDeposit(t.Context(), "blabla", "testwallet", 0) if err != nil { t.Error(err) } - _, err = b.NewDeposit(t.Context(), "bitcoin", "testwallet", 0) + _, err = e.NewDeposit(t.Context(), "bitcoin", "testwallet", 0) if err != nil { t.Error(err) } - _, err = b.NewDeposit(t.Context(), "ripple", "", 0) + _, err = e.NewDeposit(t.Context(), "ripple", "", 0) if err != nil { t.Error(err) } @@ -459,8 +459,8 @@ func TestNewDeposit(t *testing.T) { func TestGetKeyPermissions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetKeyPermissions(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetKeyPermissions(t.Context()) if err != nil { t.Error(err) } @@ -468,8 +468,8 @@ func TestGetKeyPermissions(t *testing.T) { func TestGetMarginInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetMarginInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginInfo(t.Context()) if err != nil { t.Error(err) } @@ -477,8 +477,8 @@ func TestGetMarginInfo(t *testing.T) { func TestGetAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAccountBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountBalance(t.Context()) if err != nil { t.Error(err) } @@ -486,8 +486,8 @@ func TestGetAccountBalance(t *testing.T) { func TestWalletTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.WalletTransfer(t.Context(), 0.01, "btc", "bla", "bla") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.WalletTransfer(t.Context(), 0.01, "btc", "bla", "bla") if err != nil { t.Error(err) } @@ -495,8 +495,8 @@ func TestWalletTransfer(t *testing.T) { func TestNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.NewOrder(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.NewOrder(t.Context(), "BTCUSD", order.Limit.Lower(), -1, @@ -511,25 +511,25 @@ func TestNewOrder(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := b.UpdateTicker(t.Context(), btcusdPair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), btcusdPair, asset.Spot) assert.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTicker may only error about locked markets") } func TestUpdateTickers(t *testing.T) { t.Parallel() - b := new(Bitfinex) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - testexch.UpdatePairsOnce(t, b) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + testexch.UpdatePairsOnce(t, e) - for _, a := range b.GetAssetTypes(true) { - avail, err := b.GetAvailablePairs(a) + for _, a := range e.GetAssetTypes(true) { + avail, err := e.GetAvailablePairs(a) require.NoError(t, err, "GetAvailablePairs must not error") - err = b.CurrencyPairs.StorePairs(a, avail, true) + err = e.CurrencyPairs.StorePairs(a, avail, true) require.NoError(t, err, "StorePairs must not error") - err = b.UpdateTickers(t.Context(), a) + err = e.UpdateTickers(t.Context(), a) require.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTickers must only error about locked markets") // Bitfinex leaves delisted pairs in Available info/conf endpoints @@ -538,7 +538,7 @@ func TestUpdateTickers(t *testing.T) { okay := 0.0 var errs error for _, p := range avail { - if _, err = ticker.GetTicker(b.Name, p, a); err != nil { + if _, err = ticker.GetTicker(e.Name, p, a); err != nil { errs = common.AppendError(errs, err) } else { okay++ @@ -552,7 +552,7 @@ func TestUpdateTickers(t *testing.T) { func TestNewOrderMulti(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) newOrder := []PlaceOrder{ { Symbol: "BTCUSD", @@ -564,7 +564,7 @@ func TestNewOrderMulti(t *testing.T) { }, } - _, err := b.NewOrderMulti(t.Context(), newOrder) + _, err := e.NewOrderMulti(t.Context(), newOrder) if err != nil { t.Error(err) } @@ -572,8 +572,8 @@ func TestNewOrderMulti(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CancelExistingOrder(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CancelExistingOrder(t.Context(), 1337) if err != nil { t.Error(err) } @@ -581,8 +581,8 @@ func TestCancelOrder(t *testing.T) { func TestCancelMultipleOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CancelMultipleOrders(t.Context(), []int64{1337, 1336}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CancelMultipleOrders(t.Context(), []int64{1337, 1336}) if err != nil { t.Error(err) } @@ -590,8 +590,8 @@ func TestCancelMultipleOrders(t *testing.T) { func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CancelAllExistingOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CancelAllExistingOrders(t.Context()) if err != nil { t.Error(err) } @@ -599,8 +599,8 @@ func TestCancelAllOrders(t *testing.T) { func TestReplaceOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.ReplaceOrder(t.Context(), 1337, "BTCUSD", + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.ReplaceOrder(t.Context(), 1337, "BTCUSD", 1, 1, true, order.Limit.Lower(), false) if err != nil { t.Error(err) @@ -609,8 +609,8 @@ func TestReplaceOrder(t *testing.T) { func TestGetOrderStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOrderStatus(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrderStatus(t.Context(), 1337) if err != nil { t.Error(err) } @@ -618,13 +618,13 @@ func TestGetOrderStatus(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOpenOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOpenOrders(t.Context()) if err != nil { t.Error(err) } - _, err = b.GetOpenOrders(t.Context(), 1, 2, 3, 4) + _, err = e.GetOpenOrders(t.Context(), 1, 2, 3, 4) if err != nil { t.Error(err) } @@ -632,8 +632,8 @@ func TestGetOpenOrders(t *testing.T) { func TestGetActivePositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetActivePositions(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetActivePositions(t.Context()) if err != nil { t.Error(err) } @@ -641,8 +641,8 @@ func TestGetActivePositions(t *testing.T) { func TestClaimPosition(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.ClaimPosition(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.ClaimPosition(t.Context(), 1337) if err != nil { t.Error(err) } @@ -650,8 +650,8 @@ func TestClaimPosition(t *testing.T) { func TestGetBalanceHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetBalanceHistory(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetBalanceHistory(t.Context(), "USD", time.Time{}, time.Time{}, 1, "deposit") if err != nil { t.Error(err) @@ -660,8 +660,8 @@ func TestGetBalanceHistory(t *testing.T) { func TestGetMovementHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetMovementHistory(t.Context(), "USD", "bitcoin", time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMovementHistory(t.Context(), "USD", "bitcoin", time.Time{}, time.Time{}, 1) if err != nil { t.Error(err) } @@ -710,8 +710,8 @@ func TestMovementHistoryUnmarshalJSON(t *testing.T) { func TestNewOffer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.NewOffer(t.Context(), "BTC", 1, 1, 1, "loan") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.NewOffer(t.Context(), "BTC", 1, 1, 1, "loan") if err != nil { t.Error(err) } @@ -719,8 +719,8 @@ func TestNewOffer(t *testing.T) { func TestCancelOffer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CancelOffer(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CancelOffer(t.Context(), 1337) if err != nil { t.Error(err) } @@ -728,8 +728,8 @@ func TestCancelOffer(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) if err != nil { t.Error(err) } @@ -737,8 +737,8 @@ func TestGetWithdrawalsHistory(t *testing.T) { func TestGetOfferStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOfferStatus(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOfferStatus(t.Context(), 1337) if err != nil { t.Error(err) } @@ -746,8 +746,8 @@ func TestGetOfferStatus(t *testing.T) { func TestGetActiveCredits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetActiveCredits(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetActiveCredits(t.Context()) if err != nil { t.Error(err) } @@ -755,8 +755,8 @@ func TestGetActiveCredits(t *testing.T) { func TestGetActiveOffers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetActiveOffers(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetActiveOffers(t.Context()) if err != nil { t.Error(err) } @@ -764,8 +764,8 @@ func TestGetActiveOffers(t *testing.T) { func TestGetActiveMarginFunding(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetActiveMarginFunding(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetActiveMarginFunding(t.Context()) if err != nil { t.Error(err) } @@ -773,8 +773,8 @@ func TestGetActiveMarginFunding(t *testing.T) { func TestGetUnusedMarginFunds(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetUnusedMarginFunds(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetUnusedMarginFunds(t.Context()) if err != nil { t.Error(err) } @@ -782,8 +782,8 @@ func TestGetUnusedMarginFunds(t *testing.T) { func TestGetMarginTotalTakenFunds(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetMarginTotalTakenFunds(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginTotalTakenFunds(t.Context()) if err != nil { t.Error(err) } @@ -791,8 +791,8 @@ func TestGetMarginTotalTakenFunds(t *testing.T) { func TestCloseMarginFunding(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CloseMarginFunding(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CloseMarginFunding(t.Context(), 1337) if err != nil { t.Error(err) } @@ -810,11 +810,11 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(b) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -829,9 +829,9 @@ func TestGetFee(t *testing.T) { feeBuilder := setFeeBuilder() t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(b) { + if sharedtestvalues.AreAPICredentialsSet(e) { // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -839,28 +839,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -868,7 +868,7 @@ func TestGetFee(t *testing.T) { // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -876,7 +876,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -884,7 +884,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -892,7 +892,7 @@ func TestGetFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -900,30 +900,30 @@ func TestFormatWithdrawPermissions(t *testing.T) { func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -933,9 +933,9 @@ func TestGetOrderHistory(t *testing.T) { // ---------------------------------------------------------------------------------------------------------------------------- func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "_", Base: currency.XRP, @@ -948,22 +948,22 @@ func TestSubmitOrder(t *testing.T) { Amount: 20, ClientID: "meowOrder", } - response, err := b.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Fatalf("Could not place order: %v", err) } - if sharedtestvalues.AreAPICredentialsSet(b) && response.Status != order.New { + if sharedtestvalues.AreAPICredentialsSet(e) && response.Status != order.New { t.Error("Order not placed") } - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -973,18 +973,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -994,12 +994,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } @@ -1010,8 +1010,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifyOrder( + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder( t.Context(), &order.Modify{ OrderID: "1337", @@ -1025,10 +1025,10 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: b.Name, + Exchange: e.Name, Amount: -1, Currency: currency.USDT, Description: "WITHDRAW IT ALL", @@ -1038,19 +1038,19 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: -1, @@ -1061,18 +1061,18 @@ func TestWithdrawFiat(t *testing.T) { }, } - _, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: -1, @@ -1091,25 +1091,25 @@ func TestWithdrawInternationalBank(t *testing.T) { }, } - _, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestGetDepositAddress(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(b) { - _, err := b.GetDepositAddress(t.Context(), currency.USDT, "", "TETHERUSE") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", "TETHERUSE") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := b.GetDepositAddress(t.Context(), currency.BTC, "deposit", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "deposit", "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -1118,20 +1118,20 @@ func TestGetDepositAddress(t *testing.T) { // TestWSAuth dials websocket, sends login request. func TestWSAuth(t *testing.T) { - if !b.Websocket.IsEnabled() { + if !e.Websocket.IsEnabled() { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - if !b.API.AuthenticatedWebsocketSupport { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if !e.API.AuthenticatedWebsocketSupport { t.Skip("Authentecated API support not enabled") } - testexch.SetupWs(t, b) - require.True(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must be turned on") + testexch.SetupWs(t, e) + require.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must be turned on") var resp map[string]any catcher := func() (ok bool) { select { - case v := <-b.Websocket.ToRoutine: + case v := <-e.Websocket.ToRoutine: resp, ok = v.(map[string]any) default: } @@ -1148,19 +1148,19 @@ func TestWSAuth(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(Bitfinex) //nolint:govet // Intentional shadow of b to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Setup must not error") - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - require.True(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") - subs, err := b.generateSubscriptions() + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup must not error") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + require.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - for _, baseSub := range b.Features.Subscriptions { - for _, a := range b.GetAssetTypes(true) { + for _, baseSub := range e.Features.Subscriptions { + for _, a := range e.GetAssetTypes(true) { if baseSub.Asset != asset.All && baseSub.Asset != a { continue } - pairs, err := b.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) for _, p := range pairs.Format(currency.PairFormat{Uppercase: true}) { s := baseSub.Clone() @@ -1194,47 +1194,47 @@ func TestGenerateSubscriptions(t *testing.T) { // TestWSSubscribe tests Subscribe and Unsubscribe functionality // See also TestSubscribeReq which covers key and symbol conversion func TestWSSubscribe(t *testing.T) { - b := new(Bitfinex) //nolint:govet // Intentional shadow of b to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "TestInstance must not error") - testexch.SetupWs(t, b) - err := b.Subscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewBTCUSD()}, Asset: asset.Spot}}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "TestInstance must not error") + testexch.SetupWs(t, e) + err := e.Subscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewBTCUSD()}, Asset: asset.Spot}}) require.NoError(t, err, "Subrcribe must not error") catcher := func() (ok bool) { - i := <-b.Websocket.ToRoutine + i := <-e.Websocket.ToRoutine _, ok = i.(*ticker.Price) return } assert.Eventually(t, catcher, sharedtestvalues.WebsocketResponseDefaultTimeout, time.Millisecond*10, "Ticker response should arrive") - subs, err := b.GetSubscriptions() + subs, err := e.GetSubscriptions() require.NoError(t, err, "GetSubscriptions must not error") require.Len(t, subs, 1, "We must only have 1 subscription; subID subscription must have been Removed by subscribeToChan") - err = b.Subscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewBTCUSD()}, Asset: asset.Spot}}) + err = e.Subscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewBTCUSD()}, Asset: asset.Spot}}) require.ErrorContains(t, err, "subscribe: dup (code: 10301)", "Duplicate subscription must error correctly") assert.EventuallyWithT(t, func(t *assert.CollectT) { - i := <-b.Websocket.ToRoutine + i := <-e.Websocket.ToRoutine e, ok := i.(error) require.True(t, ok, "must find an error") assert.ErrorContains(t, e, "subscribe: dup (code: 10301)", "error should be correct") }, sharedtestvalues.WebsocketResponseDefaultTimeout, time.Millisecond*10, "error response should go to ToRoutine") - subs, err = b.GetSubscriptions() + subs, err = e.GetSubscriptions() require.NoError(t, err, "GetSubscriptions must not error") require.Len(t, subs, 1, "We must only have one subscription after an error attempt") - err = b.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.NoError(t, err, "Unsubscribing should not error") chanID, ok := subs[0].Key.(int) assert.True(t, ok, "sub.Key should be an int") - err = b.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.ErrorContains(t, err, strconv.Itoa(chanID), "Unsubscribe should contain correct chanId") assert.ErrorContains(t, err, "unsubscribe: invalid (code: 10400)", "Unsubscribe should contain correct upstream error") - err = b.Subscribe(subscription.List{{ + err = e.Subscribe(subscription.List{{ Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewBTCUSD()}, Asset: asset.Spot, @@ -1278,9 +1278,9 @@ func TestSubToMap(t *testing.T) { } func TestWSNewOrder(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - _, err := b.WsNewOrder(t.Context(), &WsNewOrderRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + _, err := e.WsNewOrder(t.Context(), &WsNewOrderRequest{ GroupID: 1, Type: "EXCHANGE LIMIT", Symbol: "tXRPUSD", @@ -1291,16 +1291,16 @@ func TestWSNewOrder(t *testing.T) { } func TestWSCancelOrder(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsCancelOrder(t.Context(), 1234) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsCancelOrder(t.Context(), 1234) assert.NoError(t, err) } func TestWSModifyOrder(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsModifyOrder(t.Context(), &WsUpdateOrderRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsModifyOrder(t.Context(), &WsUpdateOrderRequest{ OrderID: 1234, Price: -111, Amount: 111, @@ -1309,23 +1309,23 @@ func TestWSModifyOrder(t *testing.T) { } func TestWSCancelAllOrders(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsCancelAllOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsCancelAllOrders(t.Context()) assert.NoError(t, err) } func TestWSCancelMultiOrders(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsCancelMultiOrders(t.Context(), []int64{1, 2, 3, 4}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsCancelMultiOrders(t.Context(), []int64{1, 2, 3, 4}) assert.NoError(t, err) } func TestWSNewOffer(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsNewOffer(t.Context(), &WsNewOfferRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsNewOffer(t.Context(), &WsNewOfferRequest{ Type: order.Limit.String(), Symbol: "fBTC", Amount: -10, @@ -1336,25 +1336,25 @@ func TestWSNewOffer(t *testing.T) { } func TestWSCancelOffer(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - testexch.SetupWs(t, b) - err := b.WsCancelOffer(t.Context(), 1234) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WsCancelOffer(t.Context(), 1234) assert.NoError(t, err) } func TestWSSubscribedResponse(t *testing.T) { - ch, err := b.Websocket.Match.Set("subscribe:waiter1", 1) + ch, err := e.Websocket.Match.Set("subscribe:waiter1", 1) assert.NoError(t, err, "Setting a matcher should not error") - err = b.wsHandleData(t.Context(), []byte(`{"event":"subscribed","channel":"ticker","chanId":224555,"subId":"waiter1","symbol":"tBTCUSD","pair":"BTCUSD"}`)) + err = e.wsHandleData(t.Context(), []byte(`{"event":"subscribed","channel":"ticker","chanId":224555,"subId":"waiter1","symbol":"tBTCUSD","pair":"BTCUSD"}`)) if assert.Error(t, err, "Should error if sub is not registered yet") { assert.ErrorIs(t, err, websocket.ErrSubscriptionFailure, "Should error SubFailure if sub isn't registered yet") assert.ErrorIs(t, err, subscription.ErrNotFound, "Should error SubNotFound if sub isn't registered yet") assert.ErrorContains(t, err, "waiter1", "Should error containing subID if") } - err = b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Key: "waiter1"}) + err = e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "waiter1"}) require.NoError(t, err, "AddSubscriptions must not error") - err = b.wsHandleData(t.Context(), []byte(`{"event":"subscribed","channel":"ticker","chanId":224555,"subId":"waiter1","symbol":"tBTCUSD","pair":"BTCUSD"}`)) + err = e.wsHandleData(t.Context(), []byte(`{"event":"subscribed","channel":"ticker","chanId":224555,"subId":"waiter1","symbol":"tBTCUSD","pair":"BTCUSD"}`)) assert.NoError(t, err, "wsHandleData should not error") if assert.NotEmpty(t, ch, "Matcher should have received a sub notification") { msg := <-ch @@ -1365,32 +1365,32 @@ func TestWSSubscribedResponse(t *testing.T) { } func TestWSOrderBook(t *testing.T) { - err := b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Key: 23405, Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.OrderbookChannel}) + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: 23405, Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.OrderbookChannel}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON := `[23405,[[38334303613,9348.8,0.53],[38334308111,9348.8,5.98979404],[38331335157,9344.1,1.28965787],[38334302803,9343.8,0.08230094],[38334279092,9343,0.8],[38334307036,9342.938663676,0.8],[38332749107,9342.9,0.2],[38332277330,9342.8,0.85],[38329406786,9342,0.1432012],[38332841570,9341.947288638,0.3],[38332163238,9341.7,0.3],[38334303384,9341.6,0.324],[38332464840,9341.4,0.5],[38331935870,9341.2,0.5],[38334312082,9340.9,0.02126899],[38334261292,9340.8,0.26763],[38334138680,9340.625455254,0.12],[38333896802,9339.8,0.85],[38331627527,9338.9,1.57863959],[38334186713,9338.9,0.26769],[38334305819,9338.8,2.999],[38334211180,9338.75285796,3.999],[38334310699,9337.8,0.10679883],[38334307414,9337.5,1],[38334179822,9337.1,0.26773],[38334306600,9336.659955102,1.79],[38334299667,9336.6,1.1],[38334306452,9336.6,0.13979771],[38325672859,9336.3,1.25],[38334311646,9336.2,1],[38334258509,9336.1,0.37],[38334310592,9336,1.79],[38334310378,9335.6,1.43],[38334132444,9335.2,0.26777],[38331367325,9335,0.07],[38334310703,9335,0.10680562],[38334298209,9334.7,0.08757301],[38334304857,9334.456899462,0.291],[38334309940,9334.088390727,0.0725],[38334310377,9333.7,1.2868],[38334297615,9333.607784,0.1108],[38334095188,9333.3,0.26785],[38334228913,9332.7,0.40861186],[38334300526,9332.363996604,0.3884],[38334310701,9332.2,0.10680562],[38334303548,9332.005382871,0.07],[38334311798,9331.8,0.41285228],[38334301012,9331.7,1.7952],[38334089877,9331.4,0.2679],[38321942150,9331.2,0.2],[38334310670,9330,1.069],[38334063096,9329.6,0.26796],[38334310700,9329.4,0.10680562],[38334310404,9329.3,1],[38334281630,9329.1,6.57150597],[38334036864,9327.7,0.26801],[38334310702,9326.6,0.10680562],[38334311799,9326.1,0.50220625],[38334164163,9326,0.219638],[38334309722,9326,1.5],[38333051682,9325.8,0.26807],[38334302027,9325.7,0.75],[38334203435,9325.366592,0.32397696],[38321967613,9325,0.05],[38334298787,9324.9,0.3],[38334301719,9324.8,3.6227592],[38331316716,9324.763454646,0.71442],[38334310698,9323.8,0.10680562],[38334035499,9323.7,0.23431017],[38334223472,9322.670551788,0.42150603],[38334163459,9322.560399006,0.143967],[38321825171,9320.8,2],[38334075805,9320.467496148,0.30772633],[38334075800,9319.916732238,0.61457592],[38333682302,9319.7,0.0011],[38331323088,9319.116771762,0.12913],[38333677480,9319,0.0199],[38334277797,9318.6,0.89],[38325235155,9318.041088,1.20249],[38334310910,9317.82382938,1.79],[38334311811,9317.2,0.61079138],[38334311812,9317.2,0.71937652],[38333298214,9317.1,50],[38334306359,9317,1.79],[38325531545,9316.382823951,0.21263],[38333727253,9316.3,0.02316372],[38333298213,9316.1,45],[38333836479,9316,2.135],[38324520465,9315.9,2.7681],[38334307411,9315.5,1],[38330313617,9315.3,0.84455],[38334077770,9315.294024,0.01248397],[38334286663,9315.294024,1],[38325533762,9315.290315394,2.40498],[38334310018,9315.2,3],[38333682617,9314.6,0.0011],[38334304794,9314.6,0.76364676],[38334304798,9314.3,0.69242113],[38332915733,9313.8,0.0199],[38334084411,9312.8,1],[38334311893,9350.1,-1.015],[38334302734,9350.3,-0.26737],[38334300732,9350.8,-5.2],[38333957619,9351,-0.90677089],[38334300521,9351,-1.6457],[38334301600,9351.012829557,-0.0523],[38334308878,9351.7,-2.5],[38334299570,9351.921544,-0.1015],[38334279367,9352.1,-0.26732],[38334299569,9352.411802928,-0.4036],[38334202773,9353.4,-0.02139404],[38333918472,9353.7,-1.96412776],[38334278782,9354,-0.26731],[38334278606,9355,-1.2785],[38334302105,9355.439221251,-0.79191542],[38313897370,9355.569409242,-0.43363],[38334292995,9355.584296,-0.0979],[38334216989,9355.8,-0.03686414],[38333894025,9355.9,-0.26721],[38334293798,9355.936691952,-0.4311],[38331159479,9356,-0.4204022],[38333918888,9356.1,-1.10885563],[38334298205,9356.4,-0.20124428],[38328427481,9356.5,-0.1],[38333343289,9356.6,-0.41034213],[38334297205,9356.6,-0.08835018],[38334277927,9356.741101161,-0.0737],[38334311645,9356.8,-0.5],[38334309002,9356.9,-5],[38334309736,9357,-0.10680107],[38334306448,9357.4,-0.18645275],[38333693302,9357.7,-0.2672],[38332815159,9357.8,-0.0011],[38331239824,9358.2,-0.02],[38334271608,9358.3,-2.999],[38334311971,9358.4,-0.55],[38333919260,9358.5,-1.9972841],[38334265365,9358.5,-1.7841],[38334277960,9359,-3],[38334274601,9359.020969848,-3],[38326848839,9359.1,-0.84],[38334291080,9359.247048,-0.16199869],[38326848844,9359.4,-1.84],[38333680200,9359.6,-0.26713],[38331326606,9359.8,-0.84454],[38334309738,9359.8,-0.10680107],[38331314707,9359.9,-0.2],[38333919803,9360.9,-1.41177599],[38323651149,9361.33417827,-0.71442],[38333656906,9361.5,-0.26705],[38334035500,9361.5,-0.40861586],[38334091886,9362.4,-6.85940815],[38334269617,9362.5,-4],[38323629409,9362.545858872,-2.40497],[38334309737,9362.7,-0.10680107],[38334312380,9362.7,-3],[38325280830,9362.8,-1.75123],[38326622800,9362.8,-1.05145],[38333175230,9363,-0.0011],[38326848745,9363.2,-0.79],[38334308960,9363.206775564,-0.12],[38333920234,9363.3,-1.25318113],[38326848843,9363.4,-1.29],[38331239823,9363.4,-0.02],[38333209613,9363.4,-0.26719],[38334299964,9364,-0.05583123],[38323470224,9364.161816648,-0.12912],[38334284711,9365,-0.21346019],[38334299594,9365,-2.6757062],[38323211816,9365.073132585,-0.21262],[38334312456,9365.1,-0.11167861],[38333209612,9365.2,-0.26719],[38327770474,9365.3,-0.0073],[38334298788,9365.3,-0.3],[38334075803,9365.409831204,-0.30772637],[38334309740,9365.5,-0.10680107],[38326608767,9365.7,-2.76809],[38333920657,9365.7,-1.25848083],[38329594226,9366.6,-0.02587],[38334311813,9366.7,-4.72290945],[38316386301,9367.39258128,-2.37581],[38334302026,9367.4,-4.5],[38334228915,9367.9,-0.81725458],[38333921381,9368.1,-1.72213641],[38333175678,9368.2,-0.0011],[38334301150,9368.2,-2.654604],[38334297208,9368.3,-0.78036466],[38334309739,9368.3,-0.10680107],[38331227515,9368.7,-0.02],[38331184470,9369,-0.003975],[38334203436,9369.319616,-0.32397695],[38334269964,9369.7,-0.5],[38328386732,9370,-4.11759935],[38332719555,9370,-0.025],[38333921935,9370.5,-1.2224398],[38334258511,9370.5,-0.35],[38326848842,9370.8,-0.34],[38333985038,9370.9,-0.8551502],[38334283018,9370.9,-1],[38326848744,9371,-1.34]],5]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } pressXToJSON = `[23405,[7617,52.98726298,7617.1,53.601795929999994,-550.9,-0.0674,7617,8318.92961981,8257.8,7500],6]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } pressXToJSON = `[23405,[7617,52.98726298,7617.1,53.601795929999994,-550.9,-0.0674,7617,8318.92961981,8257.8,7500]]` - assert.NotPanics(t, func() { err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) }, "handleWSBookUpdate should not panic when seqNo is not configured to be sent") + assert.NotPanics(t, func() { err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) }, "handleWSBookUpdate should not panic when seqNo is not configured to be sent") assert.ErrorIs(t, err, errNoSeqNo, "handleWSBookUpdate should send correct error") } func TestWSAllTrades(t *testing.T) { t.Parallel() - b := new(Bitfinex) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - err := b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.AllTradesChannel, Key: 18788}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.AllTradesChannel, Key: 18788}) require.NoError(t, err, "AddSubscriptions must not error") - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", b.wsHandleData) - close(b.Websocket.DataHandler) + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) expJSON := []string{ `{"TID":"412685577","AssetType":"spot","Side":"BUY","Price":176.3,"Amount":11.1998,"Timestamp":"2020-01-29T03:27:24.802Z"}`, `{"TID":"412685578","AssetType":"spot","Side":"SELL","Price":176.29952759,"Amount":5,"Timestamp":"2020-01-29T03:28:04.802Z"}`, @@ -1400,13 +1400,13 @@ func TestWSAllTrades(t *testing.T) { `{"TID":"5690221203","AssetType":"marginFunding","Side":"BUY","Price":102550,"Amount":0.00991467,"Timestamp":"2024-12-15T04:30:18.019Z"}`, `{"TID":"5690221204","AssetType":"marginFunding","Side":"SELL","Price":102540,"Amount":0.01925285,"Timestamp":"2024-12-15T04:30:18.094Z"}`, } - require.Len(t, b.Websocket.DataHandler, len(expJSON), "Must see correct number of trades") - for resp := range b.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, len(expJSON), "Must see correct number of trades") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 6 - len(b.Websocket.DataHandler) + i := 6 - len(e.Websocket.DataHandler) exp := trade.Data{ - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: btcusdPair, } require.NoErrorf(t, json.Unmarshal([]byte(expJSON[i]), &exp), "Must not error unmarshalling json %d: %s", i, expJSON[i]) @@ -1420,10 +1420,10 @@ func TestWSAllTrades(t *testing.T) { } func TestWSTickerResponse(t *testing.T) { - err := b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.TickerChannel, Key: 11534}) + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.TickerChannel, Key: 11534}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON := `[11534,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1431,10 +1431,10 @@ func TestWSTickerResponse(t *testing.T) { if err != nil { t.Error(err) } - err = b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123412}) + err = e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123412}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON = `[123412,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1442,10 +1442,10 @@ func TestWSTickerResponse(t *testing.T) { if err != nil { t.Error(err) } - err = b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123413}) + err = e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123413}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON = `[123413,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1453,25 +1453,25 @@ func TestWSTickerResponse(t *testing.T) { if err != nil { t.Error(err) } - err = b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123414}) + err = e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{pair}, Channel: subscription.TickerChannel, Key: 123414}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON = `[123414,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } } func TestWSCandleResponse(t *testing.T) { - err := b.Websocket.AddSubscriptions(b.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.CandlesChannel, Key: 343351}) + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{btcusdPair}, Channel: subscription.CandlesChannel, Key: 343351}) require.NoError(t, err, "AddSubscriptions must not error") pressXToJSON := `[343351,[[1574698260000,7379.785503,7383.8,7388.3,7379.785503,1.68829482]]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } pressXToJSON = `[343351,[1574698200000,7399.9,7379.7,7399.9,7371.8,41.63633658]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1479,12 +1479,12 @@ func TestWSCandleResponse(t *testing.T) { func TestWSOrderSnapshot(t *testing.T) { pressXToJSON := `[0,"os",[[34930659963,null,1574955083558,"tETHUSD",1574955083558,1574955083573,0.201104,0.201104,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,120,0,0,0,null,null,null,0,0,null,null,null,"BFX",null,null,null]]]` - err := b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err := e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } pressXToJSON = `[0,"oc",[34930659963,null,1574955083558,"tETHUSD",1574955083558,1574955354487,0.201104,0.201104,"EXCHANGE LIMIT",null,null,null,0,"CANCELED",null,null,120,0,0,0,null,null,null,0,0,null,null,null,"BFX",null,null,null]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1492,13 +1492,13 @@ func TestWSOrderSnapshot(t *testing.T) { func TestWSNotifications(t *testing.T) { pressXToJSON := `[0,"n",[1575282446099,"fon-req",null,null,[41238905,null,null,null,-1000,null,null,null,null,null,null,null,null,null,0.002,2,null,null,null,null,null],null,"SUCCESS","Submitting funding bid of 1000.0 USD at 0.2000 for 2 days."]]` - err := b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err := e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } pressXToJSON = `[0,"n",[1575287438.515,"on-req",null,null,[1185815098,null,1575287436979,"tETHUSD",1575287438515,1575287438515,-2.5,-2.5,"LIMIT",null,null,null,0,"ACTIVE",null,null,230,0,0,0,null,null,null,0,null,null,null,null,"API>BFX",null,null,null],null,"SUCCESS","Submitting limit sell order for -2.5 ETH."]]` - err = b.wsHandleData(t.Context(), []byte(pressXToJSON)) + err = e.wsHandleData(t.Context(), []byte(pressXToJSON)) if err != nil { t.Error(err) } @@ -1506,76 +1506,76 @@ func TestWSNotifications(t *testing.T) { func TestWSFundingOfferSnapshotAndUpdate(t *testing.T) { pressXToJSON := `[0,"fos",[[41237920,"fETH",1573912039000,1573912039000,0.5,0.5,"LIMIT",null,null,0,"ACTIVE",null,null,null,0.0024,2,0,0,null,0,null]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } pressXToJSON = `[0,"fon",[41238747,"fUST",1575026670000,1575026670000,5000,5000,"LIMIT",null,null,0,"ACTIVE",null,null,null,0.006000000000000001,30,0,0,null,0,null]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSFundingCreditSnapshotAndUpdate(t *testing.T) { pressXToJSON := `[0,"fcs",[[26223578,"fUST",1,1575052261000,1575296187000,350,0,"ACTIVE",null,null,null,0,30,1575052261000,1575293487000,0,0,null,0,null,0,"tBTCUST"],[26223711,"fUSD",-1,1575291961000,1575296187000,180,0,"ACTIVE",null,null,null,0.002,7,1575282446000,1575295587000,0,0,null,0,null,0,"tETHUSD"]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } pressXToJSON = `[0,"fcu",[26223578,"fUST",1,1575052261000,1575296787000,350,0,"ACTIVE",null,null,null,0,30,1575052261000,1575293487000,0,0,null,0,null,0,"tBTCUST"]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSFundingLoanSnapshotAndUpdate(t *testing.T) { pressXToJSON := `[0,"fls",[[2995442,"fUSD",-1,1575291961000,1575295850000,820,0,"ACTIVE",null,null,null,0.002,7,1575282446000,1575295850000,0,0,null,0,null,0]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } pressXToJSON = `[0,"fln",[2995444,"fUSD",-1,1575298742000,1575298742000,1000,0,"ACTIVE",null,null,null,0.002,7,1575298742000,1575298742000,0,0,null,0,null,0]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSWalletSnapshot(t *testing.T) { pressXToJSON := `[0,"ws",[["exchange","SAN",19.76,0,null,null,null]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSBalanceUpdate(t *testing.T) { const pressXToJSON = `[0,"bu",[4131.85,4131.85]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSMarginInfoUpdate(t *testing.T) { const pressXToJSON = `[0,"miu",["base",[-13.014640000000007,0,49331.70267297,49318.68803297,27]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSFundingInfoUpdate(t *testing.T) { const pressXToJSON = `[0,"fiu",["sym","tETHUSD",[149361.09689202666,149639.26293509,830.0182168075556,895.0658432466332]]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } func TestWSFundingTrade(t *testing.T) { pressXToJSON := `[0,"fte",[636854,"fUSD",1575282446000,41238905,-1000,0.002,7,null]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } pressXToJSON = `[0,"ftu",[636854,"fUSD",1575282446000,41238905,-1000,0.002,7,null]]` - if err := b.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { + if err := e.wsHandleData(t.Context(), []byte(pressXToJSON)); err != nil { t.Error(err) } } @@ -1584,7 +1584,7 @@ func TestGetHistoricCandles(t *testing.T) { startTime := time.Now().Add(-time.Hour * 24) endTime := time.Now().Add(-time.Hour * 20) - if _, err := b.GetHistoricCandles(t.Context(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil { + if _, err := e.GetHistoricCandles(t.Context(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil { t.Fatal(err) } } @@ -1593,13 +1593,13 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime := time.Now().Add(-time.Hour * 24) endTime := time.Now().Add(-time.Hour * 20) - if _, err := b.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil { + if _, err := e.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil { t.Fatal(err) } } func TestFixCasing(t *testing.T) { - ret, err := b.fixCasing(btcusdPair, asset.Spot) + ret, err := e.fixCasing(btcusdPair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1610,7 +1610,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.Spot) + ret, err = e.fixCasing(pair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1621,7 +1621,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.Spot) + ret, err = e.fixCasing(pair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1631,14 +1631,14 @@ func TestFixCasing(t *testing.T) { if ret != "tBTCUSD" { t.Errorf("unexpected result: %v", ret) } - ret, err = b.fixCasing(btcusdPair, asset.Margin) + ret, err = e.fixCasing(btcusdPair, asset.Margin) if err != nil { t.Fatal(err) } if ret != "tBTCUSD" { t.Errorf("unexpected result: %v", ret) } - ret, err = b.fixCasing(btcusdPair, asset.Spot) + ret, err = e.fixCasing(btcusdPair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1649,7 +1649,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.Spot) + ret, err = e.fixCasing(pair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1660,7 +1660,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.Spot) + ret, err = e.fixCasing(pair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1672,7 +1672,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.Spot) + ret, err = e.fixCasing(pair, asset.Spot) if err != nil { t.Fatal(err) } @@ -1683,7 +1683,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.MarginFunding) + ret, err = e.fixCasing(pair, asset.MarginFunding) if err != nil { t.Fatal(err) } @@ -1694,7 +1694,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.MarginFunding) + ret, err = e.fixCasing(pair, asset.MarginFunding) if err != nil { t.Fatal(err) } @@ -1706,7 +1706,7 @@ func TestFixCasing(t *testing.T) { if err != nil { t.Fatal(err) } - ret, err = b.fixCasing(pair, asset.MarginFunding) + ret, err = e.fixCasing(pair, asset.MarginFunding) if err != nil { t.Fatal(err) } @@ -1714,13 +1714,13 @@ func TestFixCasing(t *testing.T) { t.Errorf("unexpected result: %v", ret) } - _, err = b.fixCasing(currency.NewPair(currency.EMPTYCODE, currency.BTC), asset.MarginFunding) + _, err = e.fixCasing(currency.NewPair(currency.EMPTYCODE, currency.BTC), asset.MarginFunding) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = b.fixCasing(currency.NewPair(currency.BTC, currency.EMPTYCODE), asset.MarginFunding) + _, err = e.fixCasing(currency.NewPair(currency.BTC, currency.EMPTYCODE), asset.MarginFunding) require.NoError(t, err) - _, err = b.fixCasing(currency.EMPTYPAIR, asset.MarginFunding) + _, err = e.fixCasing(currency.EMPTYPAIR, asset.MarginFunding) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) } @@ -1749,7 +1749,7 @@ func TestFormatExchangeKlineInterval(t *testing.T) { } { t.Run(tc.interval.String(), func(t *testing.T) { t.Parallel() - ret, err := b.FormatExchangeKlineInterval(tc.interval) + ret, err := e.FormatExchangeKlineInterval(tc.interval) require.NoError(t, err, "FormatExchangeKlineInterval must not error") assert.Equal(t, tc.output, ret) }) @@ -1758,7 +1758,7 @@ func TestFormatExchangeKlineInterval(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - if _, err := b.GetRecentTrades(t.Context(), btcusdPair, asset.Spot); err != nil { + if _, err := e.GetRecentTrades(t.Context(), btcusdPair, asset.Spot); err != nil { t.Error(err) } @@ -1766,7 +1766,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(t.Context(), currencyPair, asset.Margin) + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Margin) if err != nil { t.Error(err) } @@ -1774,13 +1774,13 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - if _, err := b.GetHistoricTrades(t.Context(), + if _, err := e.GetHistoricTrades(t.Context(), btcusdPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()); err != nil { t.Error(err) } // longer term test - if _, err := b.GetHistoricTrades(t.Context(), + if _, err := e.GetHistoricTrades(t.Context(), btcusdPair, asset.Spot, time.Now().Add(-time.Hour*100), time.Now().Add(-time.Hour*99)); err != nil { @@ -1875,7 +1875,7 @@ func TestPopulateAcceptableMethods(t *testing.T) { t.Error("expected false") } } - if err := b.PopulateAcceptableMethods(t.Context()); err != nil { + if err := e.PopulateAcceptableMethods(t.Context()); err != nil { t.Fatal(err) } if !acceptableMethods.loaded() { @@ -1888,14 +1888,14 @@ func TestPopulateAcceptableMethods(t *testing.T) { t.Error("non-existent code should return no methods") } // since we're already loaded, this will return nil - if err := b.PopulateAcceptableMethods(t.Context()); err != nil { + if err := e.PopulateAcceptableMethods(t.Context()); err != nil { t.Fatal(err) } } func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - r, err := b.GetAvailableTransferChains(t.Context(), currency.USDT) + r, err := e.GetAvailableTransferChains(t.Context(), currency.USDT) if err != nil { t.Fatal(err) } @@ -1934,10 +1934,10 @@ func TestAccetableMethodStore(t *testing.T) { func TestGetSiteListConfigData(t *testing.T) { t.Parallel() - _, err := b.GetSiteListConfigData(t.Context(), "") + _, err := e.GetSiteListConfigData(t.Context(), "") require.ErrorIs(t, err, errSetCannotBeEmpty) - pairs, err := b.GetSiteListConfigData(t.Context(), bitfinexSecuritiesPairs) + pairs, err := e.GetSiteListConfigData(t.Context(), bitfinexSecuritiesPairs) require.NoError(t, err) if len(pairs) == 0 { @@ -1948,7 +1948,7 @@ func TestGetSiteListConfigData(t *testing.T) { func TestGetSiteInfoConfigData(t *testing.T) { t.Parallel() for _, assetType := range []asset.Item{asset.Spot, asset.Futures} { - pairs, err := b.GetSiteInfoConfigData(t.Context(), assetType) + pairs, err := e.GetSiteInfoConfigData(t.Context(), assetType) assert.NoError(t, err) if len(pairs) == 0 { @@ -1959,8 +1959,8 @@ func TestGetSiteInfoConfigData(t *testing.T) { func TestOrderUpdate(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.OrderUpdate(t.Context(), "1234", "", "", 1, 1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.OrderUpdate(t.Context(), "1234", "", "", 1, 1, 1) if err != nil { t.Error(err) } @@ -1968,13 +1968,13 @@ func TestOrderUpdate(t *testing.T) { func TestGetInactiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetInactiveOrders(t.Context(), "tBTCUSD") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetInactiveOrders(t.Context(), "tBTCUSD") if err != nil { t.Error(err) } - _, err = b.GetInactiveOrders(t.Context(), "tBTCUSD", 1, 2, 3, 4) + _, err = e.GetInactiveOrders(t.Context(), "tBTCUSD", 1, 2, 3, 4) if err != nil { t.Error(err) } @@ -1982,8 +1982,8 @@ func TestGetInactiveOrders(t *testing.T) { func TestCancelMultipleOrdersV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelMultipleOrdersV2(t.Context(), 1337, 0, 0, time.Time{}, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelMultipleOrdersV2(t.Context(), 1337, 0, 0, time.Time{}, false) if err != nil { t.Error(err) } @@ -1999,7 +1999,7 @@ func TestGetErrResp(t *testing.T) { s := bufio.NewScanner(fixture) seen := 0 for s.Scan() { - testErr := b.getErrResp(s.Bytes()) + testErr := e.getErrResp(s.Bytes()) seen++ switch seen { case 1: // no event @@ -2024,12 +2024,12 @@ func TestGetErrResp(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/bitfinex/bitfinex_websocket.go b/exchanges/bitfinex/bitfinex_websocket.go index 4e2031ea35b..c68de06ce0e 100644 --- a/exchanges/bitfinex/bitfinex_websocket.go +++ b/exchanges/bitfinex/bitfinex_websocket.go @@ -122,50 +122,50 @@ var subscriptionNames = map[string]string{ } // WsConnect starts a new websocket connection -func (b *Bitfinex) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !b.Websocket.IsEnabled() || !b.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return fmt.Errorf("%v unable to connect to Websocket. Error: %s", - b.Name, + e.Name, err) } - b.Websocket.Wg.Add(1) - go b.wsReadData(b.Websocket.Conn) - if b.Websocket.CanUseAuthenticatedEndpoints() { - err = b.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}) + e.Websocket.Wg.Add(1) + go e.wsReadData(e.Websocket.Conn) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}) if err != nil { log.Errorf(log.ExchangeSys, "%v unable to connect to authenticated Websocket. Error: %s", - b.Name, + e.Name, err) - b.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } - b.Websocket.Wg.Add(1) - go b.wsReadData(b.Websocket.AuthConn) - err = b.WsSendAuth(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(e.Websocket.AuthConn) + err = e.WsSendAuth(ctx) if err != nil { log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", - b.Name, + e.Name, err) - b.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } - b.Websocket.Wg.Add(1) - go b.WsDataHandler(ctx) - return b.ConfigureWS(ctx) + e.Websocket.Wg.Add(1) + go e.WsDataHandler(ctx) + return e.ConfigureWS(ctx) } // wsReadData receives and passes on websocket messages for processing -func (b *Bitfinex) wsReadData(ws websocket.Connection) { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ws websocket.Connection) { + defer e.Websocket.Wg.Done() for { resp := ws.ReadMessage() if resp.Raw == nil { @@ -176,19 +176,19 @@ func (b *Bitfinex) wsReadData(ws websocket.Connection) { } // WsDataHandler handles data from wsReadData -func (b *Bitfinex) WsDataHandler(ctx context.Context) { - defer b.Websocket.Wg.Done() +func (e *Exchange) WsDataHandler(ctx context.Context) { + defer e.Websocket.Wg.Done() for { select { - case <-b.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: select { case resp := <-comms: - err := b.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { select { - case b.Websocket.DataHandler <- err: + case e.Websocket.DataHandler <- err: default: - log.Errorf(log.WebsocketMgr, "%s websocket handle data error: %v", b.Name, err) + log.Errorf(log.WebsocketMgr, "%s websocket handle data error: %v", e.Name, err) } } default: @@ -198,22 +198,22 @@ func (b *Bitfinex) WsDataHandler(ctx context.Context) { if resp.Type != gws.TextMessage { continue } - err := b.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(_ context.Context, respRaw []byte) error { var result any if err := json.Unmarshal(respRaw, &result); err != nil { return err } switch d := result.(type) { case map[string]any: - return b.handleWSEvent(respRaw) + return e.handleWSEvent(respRaw) case []any: chanIDFloat, ok := d[0].(float64) if !ok { @@ -224,11 +224,11 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { eventType, hasEventType := d[1].(string) if chanID != 0 { - if s := b.Websocket.GetSubscription(chanID); s != nil { - return b.handleWSChannelUpdate(s, respRaw, eventType, d) + if s := e.Websocket.GetSubscription(chanID); s != nil { + return e.handleWSChannelUpdate(s, respRaw, eventType, d) } - if b.Verbose { - log.Warnf(log.ExchangeSys, "%s %s; dropped WS message: %s", b.Name, subscription.ErrNotFound, respRaw) + if e.Verbose { + log.Warnf(log.ExchangeSys, "%s %s; dropped WS message: %s", e.Name, subscription.ErrNotFound, respRaw) } // We didn't have a mapping for this chanID; This probably means we have unsubscribed OR // received our first message before processing the sub chanID @@ -244,27 +244,27 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { case wsHeartbeat, pong: return nil case wsNotification: - return b.handleWSNotification(d, respRaw) + return e.handleWSNotification(d, respRaw) case wsOrderSnapshot: if snapBundle, ok := d[2].([]any); ok && len(snapBundle) > 0 { if _, ok := snapBundle[0].([]any); ok { for i := range snapBundle { if positionData, ok := snapBundle[i].([]any); ok { - b.wsHandleOrder(positionData) + e.wsHandleOrder(positionData) } } } } case wsOrderCancel, wsOrderNew, wsOrderUpdate: if oData, ok := d[2].([]any); ok && len(oData) > 0 { - b.wsHandleOrder(oData) + e.wsHandleOrder(oData) } case wsPositionSnapshot: - return b.handleWSPositionSnapshot(d) + return e.handleWSPositionSnapshot(d) case wsPositionNew, wsPositionUpdate, wsPositionClose: - return b.handleWSPositionUpdate(d) + return e.handleWSPositionUpdate(d) case wsTradeExecuted, wsTradeUpdated: - return b.handleWSMyTradeUpdate(d, eventType) + return e.handleWSMyTradeUpdate(d, eventType) case wsFundingOfferSnapshot: if snapBundle, ok := d[2].([]any); ok && len(snapBundle) > 0 { if _, ok := snapBundle[0].([]any); ok { @@ -280,7 +280,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { } snapshot[i] = offer } - b.Websocket.DataHandler <- snapshot + e.Websocket.DataHandler <- snapshot } } case wsFundingOfferNew, wsFundingOfferUpdate, wsFundingOfferCancel: @@ -289,7 +289,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - b.Websocket.DataHandler <- offer + e.Websocket.DataHandler <- offer } case wsFundingCreditSnapshot: if snapBundle, ok := d[2].([]any); ok && len(snapBundle) > 0 { @@ -306,7 +306,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { } snapshot[i] = fundingCredit } - b.Websocket.DataHandler <- snapshot + e.Websocket.DataHandler <- snapshot } } case wsFundingCreditNew, wsFundingCreditUpdate, wsFundingCreditCancel: @@ -315,7 +315,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - b.Websocket.DataHandler <- fundingCredit + e.Websocket.DataHandler <- fundingCredit } case wsFundingLoanSnapshot: if snapBundle, ok := d[2].([]any); ok && len(snapBundle) > 0 { @@ -332,7 +332,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { } snapshot[i] = fundingLoanSnapshot } - b.Websocket.DataHandler <- snapshot + e.Websocket.DataHandler <- snapshot } } case wsFundingLoanNew, wsFundingLoanUpdate, wsFundingLoanCancel: @@ -341,7 +341,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - b.Websocket.DataHandler <- fundingData + e.Websocket.DataHandler <- fundingData } case wsWalletSnapshot: if snapBundle, ok := d[2].([]any); ok && len(snapBundle) > 0 { @@ -372,7 +372,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { } snapshot[i] = wallet } - b.Websocket.DataHandler <- snapshot + e.Websocket.DataHandler <- snapshot } } case wsWalletUpdate: @@ -395,7 +395,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { return errors.New("unable to type assert wallet snapshot balance available") } } - b.Websocket.DataHandler <- wallet + e.Websocket.DataHandler <- wallet } case wsBalanceUpdate: if data, ok := d[2].([]any); ok && len(data) > 0 { @@ -406,7 +406,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if balance.NetAssetsUnderManagement, ok = data[1].(float64); !ok { return errors.New("unable to type assert balance net assets under management") } - b.Websocket.DataHandler <- balance + e.Websocket.DataHandler <- balance } case wsMarginInfoUpdate: if data, ok := d[2].([]any); ok && len(data) > 0 { @@ -431,7 +431,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if marginInfoBase.MarginRequired, ok = baseData[4].(float64); !ok { return errors.New("unable to type assert margin info required") } - b.Websocket.DataHandler <- marginInfoBase + e.Websocket.DataHandler <- marginInfoBase } } case wsFundingInfoUpdate: @@ -457,7 +457,7 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { if fundingInfo.DurationLend, ok = symbolData[3].(float64); !ok { return errors.New("unable to type assert funding info update duration lend") } - b.Websocket.DataHandler <- fundingInfo + e.Websocket.DataHandler <- fundingInfo } } case wsFundingTradeExecuted, wsFundingTradeUpdated: @@ -493,11 +493,11 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { } wsFundingTrade.Period = int64(period) wsFundingTrade.Maker = data[7] != nil - b.Websocket.DataHandler <- wsFundingTrade + e.Websocket.DataHandler <- wsFundingTrade } default: - b.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: b.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return nil } @@ -505,31 +505,31 @@ func (b *Bitfinex) wsHandleData(_ context.Context, respRaw []byte) error { return nil } -func (b *Bitfinex) handleWSEvent(respRaw []byte) error { +func (e *Exchange) handleWSEvent(respRaw []byte) error { event, err := jsonparser.GetUnsafeString(respRaw, "event") if err != nil { return fmt.Errorf("%w 'event': %w from message: %s", common.ErrParsingWSField, err, respRaw) } switch event { case wsEventSubscribed: - return b.handleWSSubscribed(respRaw) + return e.handleWSSubscribed(respRaw) case wsEventUnsubscribed: chanID, err := jsonparser.GetUnsafeString(respRaw, "chanId") if err != nil { return fmt.Errorf("%w 'chanId': %w from message: %s", common.ErrParsingWSField, err, respRaw) } - err = b.Websocket.Match.RequireMatchWithData("unsubscribe:"+chanID, respRaw) + err = e.Websocket.Match.RequireMatchWithData("unsubscribe:"+chanID, respRaw) if err != nil { return fmt.Errorf("%w: unsubscribe:%v", err, chanID) } case wsEventError: if subID, err := jsonparser.GetUnsafeString(respRaw, "subId"); err == nil { - err = b.Websocket.Match.RequireMatchWithData("subscribe:"+subID, respRaw) + err = e.Websocket.Match.RequireMatchWithData("subscribe:"+subID, respRaw) if err != nil { return fmt.Errorf("%w: subscribe:%v", err, subID) } } else if chanID, err := jsonparser.GetUnsafeString(respRaw, "chanId"); err == nil { - err = b.Websocket.Match.RequireMatchWithData("unsubscribe:"+chanID, respRaw) + err = e.Websocket.Match.RequireMatchWithData("unsubscribe:"+chanID, respRaw) if err != nil { return fmt.Errorf("%w: unsubscribe:%v", err, chanID) } @@ -547,11 +547,11 @@ func (b *Bitfinex) handleWSEvent(respRaw []byte) error { return fmt.Errorf("unable to Unmarshal auth resp; Error: %w Msg: %v", err, respRaw) } // TODO - Send a better value down the channel - b.Websocket.DataHandler <- glob + e.Websocket.DataHandler <- glob } else { errCode, err := jsonparser.GetInt(respRaw, "code") if err != nil { - log.Errorf(log.ExchangeSys, "%s %s 'code': %s from message: %s", b.Name, common.ErrParsingWSField, err, respRaw) + log.Errorf(log.ExchangeSys, "%s %s 'code': %s from message: %s", e.Name, common.ErrParsingWSField, err, respRaw) } return fmt.Errorf("WS auth subscription error; Status: %s Error Code: %d", status, errCode) } @@ -575,13 +575,13 @@ func (b *Bitfinex) handleWSEvent(respRaw []byte) error { // handleWSSubscribed parses a subscription response and registers the chanID key immediately, before updating subscribeToChan via IncomingWithData chan // wsHandleData happens sequentially, so by rekeying on chanID immediately we ensure the first message is not dropped -func (b *Bitfinex) handleWSSubscribed(respRaw []byte) error { +func (e *Exchange) handleWSSubscribed(respRaw []byte) error { subID, err := jsonparser.GetUnsafeString(respRaw, "subId") if err != nil { return fmt.Errorf("%w 'subId': %w from message: %s", common.ErrParsingWSField, err, respRaw) } - c := b.Websocket.GetSubscription(subID) + c := e.Websocket.GetSubscription(subID) if c == nil { return fmt.Errorf("%w: %w subID: %s", websocket.ErrSubscriptionFailure, subscription.ErrNotFound, subID) } @@ -596,26 +596,26 @@ func (b *Bitfinex) handleWSSubscribed(respRaw []byte) error { c.Key = int(chanID) // subscribeToChan removes the old subID keyed Subscription - err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, c) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, c) if err != nil { return fmt.Errorf("%w: %w subID: %s", websocket.ErrSubscriptionFailure, err, subID) } - if b.Verbose { - log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s Pair: %s ChannelID: %d\n", b.Name, c.Channel, c.Pairs, chanID) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s Pair: %s ChannelID: %d\n", e.Name, c.Channel, c.Pairs, chanID) } - return b.Websocket.Match.RequireMatchWithData("subscribe:"+subID, respRaw) + return e.Websocket.Match.RequireMatchWithData("subscribe:"+subID, respRaw) } -func (b *Bitfinex) handleWSChannelUpdate(s *subscription.Subscription, respRaw []byte, eventType string, d []any) error { +func (e *Exchange) handleWSChannelUpdate(s *subscription.Subscription, respRaw []byte, eventType string, d []any) error { if s == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } switch eventType { case wsChecksum: - return b.handleWSChecksum(s, d) + return e.handleWSChecksum(s, d) case wsHeartbeat: return nil } @@ -626,19 +626,19 @@ func (b *Bitfinex) handleWSChannelUpdate(s *subscription.Subscription, respRaw [ switch s.Channel { case subscription.OrderbookChannel: - return b.handleWSBookUpdate(s, d) + return e.handleWSBookUpdate(s, d) case subscription.CandlesChannel: - return b.handleWSAllCandleUpdates(s, respRaw) + return e.handleWSAllCandleUpdates(s, respRaw) case subscription.TickerChannel: - return b.handleWSTickerUpdate(s, d) + return e.handleWSTickerUpdate(s, d) case subscription.AllTradesChannel: - return b.handleWSAllTrades(s, respRaw) + return e.handleWSAllTrades(s, respRaw) } - return fmt.Errorf("%s unhandled channel update: %s", b.Name, s.Channel) + return fmt.Errorf("%s unhandled channel update: %s", e.Name, s.Channel) } -func (b *Bitfinex) handleWSChecksum(c *subscription.Subscription, d []any) error { +func (e *Exchange) handleWSChecksum(c *subscription.Subscription, d []any) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } @@ -672,7 +672,7 @@ func (b *Bitfinex) handleWSChecksum(c *subscription.Subscription, d []any) error return nil } -func (b *Bitfinex) handleWSBookUpdate(c *subscription.Subscription, d []any) error { +func (e *Exchange) handleWSBookUpdate(c *subscription.Subscription, d []any) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } @@ -734,7 +734,7 @@ func (b *Bitfinex) handleWSBookUpdate(c *subscription.Subscription, d []any) err }) } } - if err := b.WsInsertSnapshot(c.Pairs[0], c.Asset, newOrderbook, fundingRate); err != nil { + if err := e.WsInsertSnapshot(c.Pairs[0], c.Asset, newOrderbook, fundingRate); err != nil { return fmt.Errorf("inserting snapshot error: %s", err) } @@ -768,7 +768,7 @@ func (b *Bitfinex) handleWSBookUpdate(c *subscription.Subscription, d []any) err }) } - if err := b.WsUpdateOrderbook(c, c.Pairs[0], c.Asset, newOrderbook, int64(sequenceNo), fundingRate); err != nil { + if err := e.WsUpdateOrderbook(c, c.Pairs[0], c.Asset, newOrderbook, int64(sequenceNo), fundingRate); err != nil { return fmt.Errorf("updating orderbook error: %s", err) } @@ -777,7 +777,7 @@ func (b *Bitfinex) handleWSBookUpdate(c *subscription.Subscription, d []any) err return nil } -func (b *Bitfinex) handleWSAllCandleUpdates(c *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) handleWSAllCandleUpdates(c *subscription.Subscription, respRaw []byte) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } @@ -807,7 +807,7 @@ func (b *Bitfinex) handleWSAllCandleUpdates(c *subscription.Subscription, respRa klines := make([]websocket.KlineData, len(wsCandles)) for i := range wsCandles { klines[i] = websocket.KlineData{ - Exchange: b.Name, + Exchange: e.Name, AssetType: c.Asset, Pair: c.Pairs[0], Timestamp: wsCandles[i].Timestamp.Time(), @@ -818,11 +818,11 @@ func (b *Bitfinex) handleWSAllCandleUpdates(c *subscription.Subscription, respRa Volume: wsCandles[i].Volume.Float64(), } } - b.Websocket.DataHandler <- klines + e.Websocket.DataHandler <- klines return nil } -func (b *Bitfinex) handleWSTickerUpdate(c *subscription.Subscription, d []any) error { +func (e *Exchange) handleWSTickerUpdate(c *subscription.Subscription, d []any) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } @@ -837,7 +837,7 @@ func (b *Bitfinex) handleWSTickerUpdate(c *subscription.Subscription, d []any) e t := &ticker.Price{ AssetType: c.Asset, Pair: c.Pairs[0], - ExchangeName: b.Name, + ExchangeName: e.Name, } if len(tickerData) == 10 { @@ -897,13 +897,13 @@ func (b *Bitfinex) handleWSTickerUpdate(c *subscription.Subscription, d []any) e return errors.New("unable to type assert ticker flash return rate") } } - b.Websocket.DataHandler <- t + e.Websocket.DataHandler <- t return nil } -func (b *Bitfinex) handleWSAllTrades(s *subscription.Subscription, respRaw []byte) error { - feedEnabled := b.IsTradeFeedEnabled() - if !feedEnabled && !b.IsSaveTradeDataEnabled() { +func (e *Exchange) handleWSAllTrades(s *subscription.Subscription, respRaw []byte) error { + feedEnabled := e.IsTradeFeedEnabled() + if !feedEnabled && !e.IsSaveTradeDataEnabled() { return nil } if s == nil { @@ -919,13 +919,13 @@ func (b *Bitfinex) handleWSAllTrades(s *subscription.Subscription, respRaw []byt var wsTrades []*Trade switch valueType { case jsonparser.String: - t, err := b.handleWSPublicTradeUpdate(respRaw) + t, err := e.handleWSPublicTradeUpdate(respRaw) if err != nil { return fmt.Errorf("%w `tradesUpdate[2]`: %w", common.ErrParsingWSField, err) } wsTrades = []*Trade{t} case jsonparser.Array: - if wsTrades, err = b.handleWSPublicTradesSnapshot(v); err != nil { + if wsTrades, err = e.handleWSPublicTradesSnapshot(v); err != nil { return fmt.Errorf("%w `tradesSnapshot`: %w", common.ErrParsingWSField, err) } default: @@ -934,7 +934,7 @@ func (b *Bitfinex) handleWSAllTrades(s *subscription.Subscription, respRaw []byt trades := make([]trade.Data, len(wsTrades)) for _, w := range wsTrades { t := trade.Data{ - Exchange: b.Name, + Exchange: e.Name, AssetType: s.Asset, CurrencyPair: s.Pairs[0], TID: strconv.FormatInt(w.TID, 10), @@ -948,21 +948,21 @@ func (b *Bitfinex) handleWSAllTrades(s *subscription.Subscription, respRaw []byt t.Price = w.Rate } if feedEnabled { - b.Websocket.DataHandler <- t + e.Websocket.DataHandler <- t } } - if b.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err = trade.AddTradesToBuffer(trades...) } return err } -func (b *Bitfinex) handleWSPublicTradesSnapshot(v []byte) ([]*Trade, error) { +func (e *Exchange) handleWSPublicTradesSnapshot(v []byte) ([]*Trade, error) { var trades []*Trade return trades, json.Unmarshal(v, &trades) } -func (b *Bitfinex) handleWSPublicTradeUpdate(respRaw []byte) (*Trade, error) { +func (e *Exchange) handleWSPublicTradeUpdate(respRaw []byte) (*Trade, error) { v, _, _, err := jsonparser.Get(respRaw, "[2]") if err != nil { return nil, err @@ -971,7 +971,7 @@ func (b *Bitfinex) handleWSPublicTradeUpdate(respRaw []byte) (*Trade, error) { return t, json.Unmarshal(v, t) } -func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { +func (e *Exchange) handleWSNotification(d []any, respRaw []byte) error { notification, ok := d[2].([]any) if !ok { return errors.New("unable to type assert notification data") @@ -987,14 +987,14 @@ func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { strings.Contains(channelName, wsFundingOfferCancelRequest): if data[0] != nil { if id, ok := data[0].(float64); ok && id > 0 { - if b.Websocket.Match.IncomingWithData(int64(id), respRaw) { + if e.Websocket.Match.IncomingWithData(int64(id), respRaw) { return nil } offer, err := wsHandleFundingOffer(data, true /* include rate real */) if err != nil { return err } - b.Websocket.DataHandler <- offer + e.Websocket.DataHandler <- offer } } case strings.Contains(channelName, wsOrderNewRequest): @@ -1002,10 +1002,10 @@ func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { if cid, ok := data[2].(float64); !ok { return common.GetTypeAssertError("float64", data[2], channelName+" cid") } else if cid > 0 { - if b.Websocket.Match.IncomingWithData(int64(cid), respRaw) { + if e.Websocket.Match.IncomingWithData(int64(cid), respRaw) { return nil } - b.wsHandleOrder(data) + e.wsHandleOrder(data) } } case strings.Contains(channelName, wsOrderUpdateRequest), @@ -1014,15 +1014,15 @@ func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { if id, ok := data[0].(float64); !ok { return common.GetTypeAssertError("float64", data[0], channelName+" id") } else if id > 0 { - if b.Websocket.Match.IncomingWithData(int64(id), respRaw) { + if e.Websocket.Match.IncomingWithData(int64(id), respRaw) { return nil } - b.wsHandleOrder(data) + e.wsHandleOrder(data) } } default: return fmt.Errorf("%s - Unexpected data returned %s", - b.Name, + e.Name, respRaw) } } @@ -1031,10 +1031,10 @@ func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { if strings.EqualFold(wsErr, wsError) { if errMsg, ok := notification[6].(string); ok { return fmt.Errorf("%s - Error %s", - b.Name, + e.Name, errMsg) } - return fmt.Errorf("%s - unhandled error message: %v", b.Name, + return fmt.Errorf("%s - unhandled error message: %v", e.Name, notification[6]) } } @@ -1042,7 +1042,7 @@ func (b *Bitfinex) handleWSNotification(d []any, respRaw []byte) error { return nil } -func (b *Bitfinex) handleWSPositionSnapshot(d []any) error { +func (e *Exchange) handleWSPositionSnapshot(d []any) error { snapBundle, ok := d[2].([]any) if !ok { return common.GetTypeAssertError("[]any", d[2], "positionSnapshotBundle") @@ -1091,11 +1091,11 @@ func (b *Bitfinex) handleWSPositionSnapshot(d []any) error { } snapshot[i] = position } - b.Websocket.DataHandler <- snapshot + e.Websocket.DataHandler <- snapshot return nil } -func (b *Bitfinex) handleWSPositionUpdate(d []any) error { +func (e *Exchange) handleWSPositionUpdate(d []any) error { positionData, ok := d[2].([]any) if !ok { return common.GetTypeAssertError("[]any", d[2], "positionUpdate") @@ -1136,11 +1136,11 @@ func (b *Bitfinex) handleWSPositionUpdate(d []any) error { if position.Leverage, ok = positionData[9].(float64); !ok { return errors.New("unable to type assert position leverage") } - b.Websocket.DataHandler <- position + e.Websocket.DataHandler <- position return nil } -func (b *Bitfinex) handleWSMyTradeUpdate(d []any, eventType string) error { +func (e *Exchange) handleWSMyTradeUpdate(d []any, eventType string) error { tradeData, ok := d[2].([]any) if !ok { return common.GetTypeAssertError("[]any", d[2], "tradeUpdate") @@ -1192,7 +1192,7 @@ func (b *Bitfinex) handleWSMyTradeUpdate(d []any, eventType string) error { return errors.New("unable to type assert trade fee currency") } } - b.Websocket.DataHandler <- tData + e.Websocket.DataHandler <- tData return nil } @@ -1409,10 +1409,10 @@ func wsHandleFundingCreditLoanData(data []any, includePositionPair bool) (*WsCre return &credit, nil } -func (b *Bitfinex) wsHandleOrder(data []any) { +func (e *Exchange) wsHandleOrder(data []any) { var od order.Detail var err error - od.Exchange = b.Name + od.Exchange = e.Name if data[0] != nil { if id, ok := data[0].(float64); ok { od.OrderID = strconv.FormatFloat(id, 'f', -1, 64) @@ -1450,9 +1450,9 @@ func (b *Bitfinex) wsHandleOrder(data []any) { } if data[2] != nil { if p, ok := data[3].(string); ok { - od.Pair, od.AssetType, err = b.GetRequestFormattedPairAndAssetType(p[1:]) + od.Pair, od.AssetType, err = e.GetRequestFormattedPairAndAssetType(p[1:]) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err return } } @@ -1461,8 +1461,8 @@ func (b *Bitfinex) wsHandleOrder(data []any) { if ordType, ok := data[8].(string); ok { oType, err := order.StringToOrderType(ordType) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: od.OrderID, Err: err, } @@ -1475,8 +1475,8 @@ func (b *Bitfinex) wsHandleOrder(data []any) { statusParts := strings.Split(combinedStatus, " @ ") oStatus, err := order.StringToOrderStatus(statusParts[0]) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: od.OrderID, Err: err, } @@ -1484,11 +1484,11 @@ func (b *Bitfinex) wsHandleOrder(data []any) { od.Status = oStatus } } - b.Websocket.DataHandler <- &od + e.Websocket.DataHandler <- &od } // WsInsertSnapshot add the initial orderbook snapshot when subscribed to a channel -func (b *Bitfinex) WsInsertSnapshot(p currency.Pair, assetType asset.Item, books []WebsocketBook, fundingRate bool) error { +func (e *Exchange) WsInsertSnapshot(p currency.Pair, assetType asset.Item, books []WebsocketBook, fundingRate bool) error { if len(books) == 0 { return errors.New("no orderbooks submitted") } @@ -1521,17 +1521,17 @@ func (b *Bitfinex) WsInsertSnapshot(p currency.Pair, assetType asset.Item, books book.Asset = assetType book.Pair = p - book.Exchange = b.Name + book.Exchange = e.Name book.PriceDuplication = true book.IsFundingRate = fundingRate - book.ValidateOrderbook = b.ValidateOrderbook + book.ValidateOrderbook = e.ValidateOrderbook book.LastUpdated = time.Now() // Not included in snapshot - return b.Websocket.Orderbook.LoadSnapshot(&book) + return e.Websocket.Orderbook.LoadSnapshot(&book) } // WsUpdateOrderbook updates the orderbook list, removing and adding to the // orderbook sides -func (b *Bitfinex) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pair, assetType asset.Item, book []WebsocketBook, sequenceNo int64, fundingRate bool) error { +func (e *Exchange) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pair, assetType asset.Item, book []WebsocketBook, sequenceNo int64, fundingRate bool) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } @@ -1602,7 +1602,7 @@ func (b *Bitfinex) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pa checkme := checksumStore[chanID] if checkme == nil { cMtx.Unlock() - return b.Websocket.Orderbook.Update(&orderbookUpdate) + return e.Websocket.Orderbook.Update(&orderbookUpdate) } checksumStore[chanID] = nil cMtx.Unlock() @@ -1610,7 +1610,7 @@ func (b *Bitfinex) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pa if checkme.Sequence+1 == sequenceNo { // Sequence numbers get dropped, if checksum is not in line with // sequence, do not check. - ob, err := b.Websocket.Orderbook.GetOrderbook(p, assetType) + ob, err := e.Websocket.Orderbook.GetOrderbook(p, assetType) if err != nil { return fmt.Errorf("cannot calculate websocket checksum: book not found for %s %s %w", p, @@ -1619,36 +1619,36 @@ func (b *Bitfinex) WsUpdateOrderbook(c *subscription.Subscription, p currency.Pa } if err = validateCRC32(ob, checkme.Token); err != nil { - log.Errorf(log.WebsocketMgr, "%s websocket orderbook update error, will resubscribe orderbook: %v", b.Name, err) - if e2 := b.resubOrderbook(c); e2 != nil { - log.Errorf(log.WebsocketMgr, "%s error resubscribing orderbook: %v", b.Name, e2) + log.Errorf(log.WebsocketMgr, "%s websocket orderbook update error, will resubscribe orderbook: %v", e.Name, err) + if e2 := e.resubOrderbook(c); e2 != nil { + log.Errorf(log.WebsocketMgr, "%s error resubscribing orderbook: %v", e.Name, e2) } return err } } - return b.Websocket.Orderbook.Update(&orderbookUpdate) + return e.Websocket.Orderbook.Update(&orderbookUpdate) } // resubOrderbook resubscribes the orderbook after a consistency error, probably a failed checksum, // which forces a fresh snapshot. If we don't do this the orderbook will keep erroring and drifting. // Flushing the orderbook happens immediately, but the ReSub itself is a go routine to avoid blocking the WS data channel -func (b *Bitfinex) resubOrderbook(c *subscription.Subscription) error { +func (e *Exchange) resubOrderbook(c *subscription.Subscription) error { if c == nil { return fmt.Errorf("%w: Subscription param", common.ErrNilPointer) } if len(c.Pairs) != 1 { return subscription.ErrNotSinglePair } - if err := b.Websocket.Orderbook.InvalidateOrderbook(c.Pairs[0], c.Asset); err != nil { + if err := e.Websocket.Orderbook.InvalidateOrderbook(c.Pairs[0], c.Asset); err != nil { // Non-fatal error - log.Errorf(log.ExchangeSys, "%s error flushing orderbook: %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s error flushing orderbook: %v", e.Name, err) } // Resub will block so we have to do this in a goro go func() { - if err := b.Websocket.ResubscribeToChannel(b.Websocket.Conn, c); err != nil { - log.Errorf(log.ExchangeSys, "%s error resubscribing orderbook: %v", b.Name, err) + if err := e.Websocket.ResubscribeToChannel(e.Websocket.Conn, c); err != nil { + log.Errorf(log.ExchangeSys, "%s error resubscribing orderbook: %v", e.Name, err) } }() @@ -1656,52 +1656,52 @@ func (b *Bitfinex) resubOrderbook(c *subscription.Subscription) error { } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (b *Bitfinex) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *Bitfinex) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(sprig.FuncMap()).Funcs(template.FuncMap{ "subToMap": subToMap, "removeSpotFromMargin": func(ap map[asset.Item]currency.Pairs) string { - spotPairs, _ := b.GetEnabledPairs(asset.Spot) + spotPairs, _ := e.GetEnabledPairs(asset.Spot) return removeSpotFromMargin(ap, spotPairs) }, }).Parse(subTplText) } // ConfigureWS to send checksums and sequence numbers -func (b *Bitfinex) ConfigureWS(ctx context.Context) error { - return b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, map[string]any{ +func (e *Exchange) ConfigureWS(ctx context.Context) error { + return e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, map[string]any{ "event": "conf", "flags": bitfinexChecksumFlag + bitfinexWsSequenceFlag, }) } // Subscribe sends a websocket message to receive data from channels -func (b *Bitfinex) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() var err error - if subs, err = subs.ExpandTemplates(b); err != nil { + if subs, err = subs.ExpandTemplates(e); err != nil { return err } - return b.ParallelChanOp(ctx, subs, b.subscribeToChan, 1) + return e.ParallelChanOp(ctx, subs, e.subscribeToChan, 1) } // Unsubscribe sends a websocket message to stop receiving data from channels -func (b *Bitfinex) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() var err error - if subs, err = subs.ExpandTemplates(b); err != nil { + if subs, err = subs.ExpandTemplates(e); err != nil { return err } - return b.ParallelChanOp(ctx, subs, b.unsubscribeFromChan, 1) + return e.ParallelChanOp(ctx, subs, e.unsubscribeFromChan, 1) } // subscribeToChan handles a single subscription and parses the result // on success it adds the subscription to the websocket -func (b *Bitfinex) subscribeToChan(ctx context.Context, subs subscription.List) error { +func (e *Exchange) subscribeToChan(ctx context.Context, subs subscription.List) error { if len(subs) != 1 { return subscription.ErrNotSinglePair } @@ -1716,29 +1716,29 @@ func (b *Bitfinex) subscribeToChan(ctx context.Context, subs subscription.List) // subId is a single round-trip identifier that provides linking sub requests to chanIDs // Although docs only mention subId for wsBookChannel, it works for all chans - subID := strconv.FormatInt(b.Websocket.Conn.GenerateMessageID(false), 10) + subID := strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10) req["subId"] = subID // Add a temporary Key so we can find this Sub when we get the resp without delay or context switch // Otherwise we might drop the first messages after the subscribed resp s.Key = subID // Note subID string type avoids conflicts with later chanID key - if err := b.Websocket.AddSubscriptions(b.Websocket.Conn, s); err != nil { + if err := e.Websocket.AddSubscriptions(e.Websocket.Conn, s); err != nil { return fmt.Errorf("%w Channel: %s Pair: %s", err, s.Channel, s.Pairs) } // Always remove the temporary subscription keyed by subID defer func() { - _ = b.Websocket.RemoveSubscriptions(b.Websocket.Conn, s) + _ = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) }() - respRaw, err := b.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "subscribe:"+subID, req) + respRaw, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "subscribe:"+subID, req) if err != nil { return fmt.Errorf("%w: Channel: %s Pair: %s", err, s.Channel, s.Pairs) } - if err = b.getErrResp(respRaw); err != nil { + if err = e.getErrResp(respRaw); err != nil { wErr := fmt.Errorf("%w: Channel: %s Pair: %s", err, s.Channel, s.Pairs) - b.Websocket.DataHandler <- wErr + e.Websocket.DataHandler <- wErr return wErr } @@ -1746,7 +1746,7 @@ func (b *Bitfinex) subscribeToChan(ctx context.Context, subs subscription.List) } // unsubscribeFromChan sends a websocket message to stop receiving data from a channel -func (b *Bitfinex) unsubscribeFromChan(ctx context.Context, subs subscription.List) error { +func (e *Exchange) unsubscribeFromChan(ctx context.Context, subs subscription.List) error { if len(subs) != 1 { return errors.New("subscription batching limited to 1") } @@ -1761,25 +1761,25 @@ func (b *Bitfinex) unsubscribeFromChan(ctx context.Context, subs subscription.Li "chanId": chanID, } - respRaw, err := b.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "unsubscribe:"+strconv.Itoa(chanID), req) + respRaw, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "unsubscribe:"+strconv.Itoa(chanID), req) if err != nil { return err } - if err := b.getErrResp(respRaw); err != nil { + if err := e.getErrResp(respRaw); err != nil { wErr := fmt.Errorf("%w: ChanId: %v", err, chanID) - b.Websocket.DataHandler <- wErr + e.Websocket.DataHandler <- wErr return wErr } - return b.Websocket.RemoveSubscriptions(b.Websocket.Conn, s) + return e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } // getErrResp takes a json response string and looks for an error event type // If found it parses the error code and message as a wrapped error and returns it // It might log parsing errors about the nature of the error // If the error message is not defined it will return a wrapped common.ErrUnknownError -func (b *Bitfinex) getErrResp(resp []byte) error { +func (e *Exchange) getErrResp(resp []byte) error { event, err := jsonparser.GetUnsafeString(resp, "event") if err != nil { return fmt.Errorf("%w 'event': %w from message: %s", common.ErrParsingWSField, err, resp) @@ -1789,12 +1789,12 @@ func (b *Bitfinex) getErrResp(resp []byte) error { } errCode, err := jsonparser.GetInt(resp, "code") if err != nil { - log.Errorf(log.ExchangeSys, "%s %s 'code': %s from message: %s", b.Name, common.ErrParsingWSField, err, resp) + log.Errorf(log.ExchangeSys, "%s %s 'code': %s from message: %s", e.Name, common.ErrParsingWSField, err, resp) } var apiErr error if msg, e2 := jsonparser.GetString(resp, "msg"); e2 != nil { - log.Errorf(log.ExchangeSys, "%s %s 'msg': %s from message: %s", b.Name, common.ErrParsingWSField, e2, resp) + log.Errorf(log.ExchangeSys, "%s %s 'msg': %s from message: %s", e.Name, common.ErrParsingWSField, e2, resp) apiErr = common.ErrUnknownError } else { apiErr = errors.New(msg) @@ -1803,8 +1803,8 @@ func (b *Bitfinex) getErrResp(resp []byte) error { } // WsSendAuth sends a authenticated event payload -func (b *Bitfinex) WsSendAuth(ctx context.Context) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) WsSendAuth(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1817,7 +1817,7 @@ func (b *Bitfinex) WsSendAuth(ctx context.Context) error { return err } - return b.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, WsAuthRequest{ + return e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, WsAuthRequest{ Event: "auth", APIKey: creds.Key, AuthPayload: payload, @@ -1828,15 +1828,15 @@ func (b *Bitfinex) WsSendAuth(ctx context.Context) error { } // WsNewOrder authenticated new order request -func (b *Bitfinex) WsNewOrder(ctx context.Context, data *WsNewOrderRequest) (string, error) { - data.CustomID = b.Websocket.AuthConn.GenerateMessageID(false) +func (e *Exchange) WsNewOrder(ctx context.Context, data *WsNewOrderRequest) (string, error) { + data.CustomID = e.Websocket.AuthConn.GenerateMessageID(false) req := makeRequestInterface(wsOrderNew, data) - resp, err := b.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, data.CustomID, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, data.CustomID, req) if err != nil { return "", err } if resp == nil { - return "", errors.New(b.Name + " - Order message not returned") + return "", errors.New(e.Name + " - Order message not returned") } var respData []any err = json.Unmarshal(resp, &respData) @@ -1880,20 +1880,20 @@ func (b *Bitfinex) WsNewOrder(ctx context.Context, data *WsNewOrderRequest) (str } } if strings.EqualFold(errCode, wsError) { - return orderID, errors.New(b.Name + " - " + errCode + ": " + errorMessage) + return orderID, errors.New(e.Name + " - " + errCode + ": " + errorMessage) } return orderID, nil } // WsModifyOrder authenticated modify order request -func (b *Bitfinex) WsModifyOrder(ctx context.Context, data *WsUpdateOrderRequest) error { +func (e *Exchange) WsModifyOrder(ctx context.Context, data *WsUpdateOrderRequest) error { req := makeRequestInterface(wsOrderUpdate, data) - resp, err := b.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, data.OrderID, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, data.OrderID, req) if err != nil { return err } if resp == nil { - return errors.New(b.Name + " - Order message not returned") + return errors.New(e.Name + " - Order message not returned") } var responseData []any @@ -1922,32 +1922,32 @@ func (b *Bitfinex) WsModifyOrder(ctx context.Context, data *WsUpdateOrderRequest } } if strings.EqualFold(errCode, wsError) { - return errors.New(b.Name + " - " + errCode + ": " + errorMessage) + return errors.New(e.Name + " - " + errCode + ": " + errorMessage) } return nil } // WsCancelMultiOrders authenticated cancel multi order request -func (b *Bitfinex) WsCancelMultiOrders(ctx context.Context, orderIDs []int64) error { +func (e *Exchange) WsCancelMultiOrders(ctx context.Context, orderIDs []int64) error { cancel := WsCancelGroupOrdersRequest{ OrderID: orderIDs, } req := makeRequestInterface(wsCancelMultipleOrders, cancel) - return b.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) + return e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) } // WsCancelOrder authenticated cancel order request -func (b *Bitfinex) WsCancelOrder(ctx context.Context, orderID int64) error { +func (e *Exchange) WsCancelOrder(ctx context.Context, orderID int64) error { cancel := WsCancelOrderRequest{ OrderID: orderID, } req := makeRequestInterface(wsOrderCancel, cancel) - resp, err := b.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, orderID, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, orderID, req) if err != nil { return err } if resp == nil { - return fmt.Errorf("%v - Order %v failed to cancel", b.Name, orderID) + return fmt.Errorf("%v - Order %v failed to cancel", e.Name, orderID) } var responseData []any err = json.Unmarshal(resp, &responseData) @@ -1975,36 +1975,36 @@ func (b *Bitfinex) WsCancelOrder(ctx context.Context, orderID int64) error { } } if strings.EqualFold(errCode, wsError) { - return errors.New(b.Name + " - " + errCode + ": " + errorMessage) + return errors.New(e.Name + " - " + errCode + ": " + errorMessage) } return nil } // WsCancelAllOrders authenticated cancel all orders request -func (b *Bitfinex) WsCancelAllOrders(ctx context.Context) error { +func (e *Exchange) WsCancelAllOrders(ctx context.Context) error { cancelAll := WsCancelAllOrdersRequest{All: 1} req := makeRequestInterface(wsCancelMultipleOrders, cancelAll) - return b.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) + return e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) } // WsNewOffer authenticated new offer request -func (b *Bitfinex) WsNewOffer(ctx context.Context, data *WsNewOfferRequest) error { +func (e *Exchange) WsNewOffer(ctx context.Context, data *WsNewOfferRequest) error { req := makeRequestInterface(wsFundingOfferNew, data) - return b.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) + return e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, req) } // WsCancelOffer authenticated cancel offer request -func (b *Bitfinex) WsCancelOffer(ctx context.Context, orderID int64) error { +func (e *Exchange) WsCancelOffer(ctx context.Context, orderID int64) error { cancel := WsCancelOrderRequest{ OrderID: orderID, } req := makeRequestInterface(wsFundingOfferCancel, cancel) - resp, err := b.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, orderID, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, orderID, req) if err != nil { return err } if resp == nil { - return fmt.Errorf("%v - Order %v failed to cancel", b.Name, orderID) + return fmt.Errorf("%v - Order %v failed to cancel", e.Name, orderID) } var responseData []any err = json.Unmarshal(resp, &responseData) @@ -2032,7 +2032,7 @@ func (b *Bitfinex) WsCancelOffer(ctx context.Context, orderID int64) error { } } if strings.EqualFold(errCode, wsError) { - return errors.New(b.Name + " - " + errCode + ": " + errorMessage) + return errors.New(e.Name + " - " + errCode + ": " + errorMessage) } return nil diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 7ae8d4aceff..4c9b040096f 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -33,12 +33,12 @@ import ( ) // SetDefaults sets the basic defaults for bitfinex -func (b *Bitfinex) SetDefaults() { - b.Name = "Bitfinex" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Bitfinex" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for _, a := range []asset.Item{asset.Spot, asset.Margin, asset.MarginFunding} { ps := currency.PairStore{ @@ -49,19 +49,19 @@ func (b *Bitfinex) SetDefaults() { if a == asset.Margin { ps.ConfigFormat.Delimiter = ":" } - if err := b.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", b.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } // Margin WS Currently not fully implemented and causes subscription collisions with spot - if err := b.DisableAssetWebsocketSupport(asset.Margin); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", b.Name, asset.Margin, err) + if err := e.DisableAssetWebsocketSupport(asset.Margin); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, asset.Margin, err) } // TODO: Implement Futures and Securities asset types. - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -152,61 +152,61 @@ func (b *Bitfinex) SetDefaults() { } var err error - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: bitfinexAPIURLBase, exchange.WebsocketSpot: publicBitfinexWebsocketEndpoint, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (b *Bitfinex) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsEndpoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: publicBitfinexWebsocketEndpoint, RunningURL: wsEndpoint, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - err = b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, URL: publicBitfinexWebsocketEndpoint, @@ -215,7 +215,7 @@ func (b *Bitfinex) Setup(exch *config.Exchange) error { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, URL: authenticatedBitfinexWebsocketEndpoint, @@ -224,8 +224,8 @@ func (b *Bitfinex) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitfinex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - items, err := b.GetPairs(ctx, a) +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + items, err := e.GetPairs(ctx, a) if err != nil { return nil, err } @@ -252,47 +252,47 @@ func (b *Bitfinex) FetchTradablePairs(ctx context.Context, a asset.Item) (curren // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitfinex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := b.CurrencyPairs.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.CurrencyPairs.GetAssetTypes(false) for i := range assets { - pairs, err := b.FetchTradablePairs(ctx, assets[i]) + pairs, err := e.FetchTradablePairs(ctx, assets[i]) if err != nil { return err } - err = b.UpdatePairs(pairs, assets[i], false, forceUpdate) + err = e.UpdatePairs(pairs, assets[i], false, forceUpdate) if err != nil { return err } } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateOrderExecutionLimits sets exchange execution order limits for an asset type -func (b *Bitfinex) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { if a != asset.Spot { return common.ErrNotYetImplemented } - limits, err := b.GetSiteInfoConfigData(ctx, a) + limits, err := e.GetSiteInfoConfigData(ctx, a) if err != nil { return err } - if err := b.LoadLimits(limits); err != nil { - return fmt.Errorf("%s Error loading exchange limits: %v", b.Name, err) + if err := e.LoadLimits(limits); err != nil { + return fmt.Errorf("%s Error loading exchange limits: %v", e.Name, err) } return nil } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitfinex) UpdateTickers(ctx context.Context, a asset.Item) error { - t, err := b.GetTickerBatch(ctx) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + t, err := e.GetTickerBatch(ctx) if err != nil { return err } var errs error for key, val := range t { - pair, enabled, err := b.MatchSymbolCheckEnabled(key[1:], a, true) + pair, enabled, err := e.MatchSymbolCheckEnabled(key[1:], a, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { errs = common.AppendError(errs, err) continue @@ -310,7 +310,7 @@ func (b *Bitfinex) UpdateTickers(ctx context.Context, a asset.Item) error { Volume: val.Volume, Pair: pair, AssetType: a, - ExchangeName: b.Name, + ExchangeName: e.Name, }) if err != nil { errs = common.AppendError(errs, err) @@ -320,43 +320,43 @@ func (b *Bitfinex) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitfinex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := b.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(b.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } o := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, PriceDuplication: true, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return o, err } if assetType != asset.Spot && assetType != asset.Margin && assetType != asset.MarginFunding { return o, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - b.appendOptionalDelimiter(&fPair) + e.appendOptionalDelimiter(&fPair) prefix := "t" if assetType == asset.MarginFunding { prefix = "f" } - orderbookNew, err := b.GetOrderbook(ctx, prefix+fPair.String(), "R0", 100) + orderbookNew, err := e.GetOrderbook(ctx, prefix+fPair.String(), "R0", 100) if err != nil { return o, err } @@ -402,16 +402,16 @@ func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy if err != nil { return nil, err } - return orderbook.Get(b.Name, fPair, assetType) + return orderbook.Get(e.Name, fPair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies on the // Bitfinex exchange -func (b *Bitfinex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = b.Name + response.Exchange = e.Name - accountBalance, err := b.GetAccountBalance(ctx) + accountBalance, err := e.GetAccountBalance(ctx) if err != nil { return response, err } @@ -439,7 +439,7 @@ func (b *Bitfinex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) } response.Accounts = Accounts - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -453,13 +453,13 @@ func (b *Bitfinex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitfinex) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitfinex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - history, err := b.GetMovementHistory(ctx, c.String(), "", time.Date(2012, 0, 0, 0, 0, 0, 0, time.Local), time.Now(), 0) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + history, err := e.GetMovementHistory(ctx, c.String(), "", time.Date(2012, 0, 0, 0, 0, 0, 0, time.Local), time.Now(), 0) if err != nil { return nil, err } @@ -482,24 +482,24 @@ func (b *Bitfinex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitfinex) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return b.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitfinex) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if a == asset.MarginFunding { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } - p, err := b.FormatExchangeCurrency(p, a) + p, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - currString, err := b.fixCasing(p, a) + currString, err := e.fixCasing(p, a) if err != nil { return nil, err } @@ -509,7 +509,7 @@ func (b *Bitfinex) GetHistoricTrades(ctx context.Context, p currency.Pair, a ass const limit = 10000 allTrades: for { - tradeData, err := b.GetTrades(ctx, currString, limit, time.Time{}, ts, false) + tradeData, err := e.GetTrades(ctx, currString, limit, time.Time{}, ts, false) if err != nil { return nil, err } @@ -520,7 +520,7 @@ allTrades: } resp = append(resp, trade.Data{ TID: strconv.FormatInt(tradeData[i].TID, 10), - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: tradeData[i].Price, @@ -540,7 +540,7 @@ allTrades: } } - if err := b.AddTradesToBuffer(resp...); err != nil { + if err := e.AddTradesToBuffer(resp...); err != nil { return nil, err } @@ -549,21 +549,21 @@ allTrades: } // SubmitOrder submits a new order -func (b *Bitfinex) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { - if err := o.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { + if err := o.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := b.FormatExchangeCurrency(o.Pair, o.AssetType) + fPair, err := e.FormatExchangeCurrency(o.Pair, o.AssetType) if err != nil { return nil, err } var orderID string status := order.New - if b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { var symbolStr string - if symbolStr, err = b.fixCasing(fPair, o.AssetType); err != nil { + if symbolStr, err = e.fixCasing(fPair, o.AssetType); err != nil { return nil, err } orderType := strings.ToUpper(o.Type.String()) @@ -580,18 +580,18 @@ func (b *Bitfinex) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Sub // All v2 apis use negatives for Short side req.Amount *= -1 } - orderID, err = b.WsNewOrder(ctx, req) + orderID, err = e.WsNewOrder(ctx, req) if err != nil { return nil, err } } else { var response Order - b.appendOptionalDelimiter(&fPair) + e.appendOptionalDelimiter(&fPair) orderType := o.Type.Lower() if o.AssetType == asset.Spot { orderType = "exchange " + orderType } - response, err = b.NewOrder(ctx, + response, err = e.NewOrder(ctx, fPair.String(), orderType, o.Amount, @@ -617,12 +617,12 @@ func (b *Bitfinex) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Sub // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitfinex) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } - if b.Websocket.IsEnabled() && b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.IsEnabled() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { orderIDInt, err := strconv.ParseInt(action.OrderID, 10, 64) if err != nil { return &order.ModifyResponse{OrderID: action.OrderID}, err @@ -636,14 +636,14 @@ func (b *Bitfinex) ModifyOrder(ctx context.Context, action *order.Modify) (*orde if action.Side.IsShort() && action.Amount > 0 { wsRequest.Amount *= -1 } - err = b.WsModifyOrder(ctx, &wsRequest) + err = e.WsModifyOrder(ctx, &wsRequest) if err != nil { return nil, err } return action.DeriveModifyResponse() } - _, err := b.OrderUpdate(ctx, action.OrderID, "", action.ClientOrderID, action.Amount, action.Price, -1) + _, err := e.OrderUpdate(ctx, action.OrderID, "", action.ClientOrderID, action.Amount, action.Price, -1) if err != nil { return nil, err } @@ -651,7 +651,7 @@ func (b *Bitfinex) ModifyOrder(ctx context.Context, action *order.Modify) (*orde } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitfinex) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -660,16 +660,16 @@ func (b *Bitfinex) CancelOrder(ctx context.Context, o *order.Cancel) error { if err != nil { return err } - if b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - err = b.WsCancelOrder(ctx, orderIDInt) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + err = e.WsCancelOrder(ctx, orderIDInt) } else { - _, err = b.CancelExistingOrder(ctx, orderIDInt) + _, err = e.CancelExistingOrder(ctx, orderIDInt) } return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitfinex) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { // While bitfinex supports cancelling multiple orders, it is // done in a way that is not helpful for GCT, and it would be better instead // to use CancelAllOrders or CancelOrder @@ -677,17 +677,17 @@ func (b *Bitfinex) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*orde } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitfinex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { var err error - if b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - err = b.WsCancelAllOrders(ctx) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + err = e.WsCancelAllOrders(ctx) } else { - _, err = b.CancelAllExistingOrders(ctx) + _, err = e.CancelAllExistingOrders(ctx) } return order.CancelAllResponse{}, err } -func (b *Bitfinex) parseOrderToOrderDetail(o *Order) (*order.Detail, error) { +func (e *Exchange) parseOrderToOrderDetail(o *Order) (*order.Detail, error) { side, err := order.StringToOrderSide(o.Side) if err != nil { return nil, err @@ -696,7 +696,7 @@ func (b *Bitfinex) parseOrderToOrderDetail(o *Order) (*order.Detail, error) { orderDetail := &order.Detail{ Amount: o.OriginalAmount, Date: o.Timestamp.Time(), - Exchange: b.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(o.ID, 10), Side: side, Price: o.Price, @@ -724,7 +724,7 @@ func (b *Bitfinex) parseOrderToOrderDetail(o *Order) (*order.Detail, error) { } else { orderDetail.Type, err = order.StringToOrderType(orderType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } } @@ -732,11 +732,11 @@ func (b *Bitfinex) parseOrderToOrderDetail(o *Order) (*order.Detail, error) { } // GetOrderInfo returns order information based on order ID -func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } @@ -745,14 +745,14 @@ func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair curren return nil, err } - b.appendOptionalDelimiter(&pair) + e.appendOptionalDelimiter(&pair) var cf string - cf, err = b.fixCasing(pair, assetType) + cf, err = e.fixCasing(pair, assetType) if err != nil { return nil, err } - resp, err := b.GetInactiveOrders(ctx, cf, id) + resp, err := e.GetInactiveOrders(ctx, cf, id) if err != nil { return nil, err } @@ -761,13 +761,13 @@ func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair curren continue } var o *order.Detail - o, err = b.parseOrderToOrderDetail(&resp[i]) + o, err = e.parseOrderToOrderDetail(&resp[i]) if err != nil { return nil, err } return o, nil } - resp, err = b.GetOpenOrders(ctx, id) + resp, err = e.GetOpenOrders(ctx, id) if err != nil { return nil, err } @@ -776,7 +776,7 @@ func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair curren continue } var o *order.Detail - o, err = b.parseOrderToOrderDetail(&resp[i]) + o, err = e.parseOrderToOrderDetail(&resp[i]) if err != nil { return nil, err } @@ -786,7 +786,7 @@ func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair curren } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accountID, chain string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, accountID, chain string) (*deposit.Address, error) { if accountID == "" { accountID = "funding" } @@ -796,7 +796,7 @@ func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accou c = currency.NewCode("UST") } - if err := b.PopulateAcceptableMethods(ctx); err != nil { + if err := e.PopulateAcceptableMethods(ctx); err != nil { return nil, err } @@ -811,7 +811,7 @@ func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accou return nil, fmt.Errorf("a chain must be specified, %s available", methods) } - resp, err := b.NewDeposit(ctx, method, accountID, 0) + resp, err := e.NewDeposit(ctx, method, accountID, 0) if err != nil { return nil, err } @@ -822,12 +822,12 @@ func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accou } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - if err := b.PopulateAcceptableMethods(ctx); err != nil { + if err := e.PopulateAcceptableMethods(ctx); err != nil { return nil, err } @@ -855,7 +855,7 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ // As this is for trading, I've made the wrapper default 'exchange' // TODO: Discover an automated way to make the decision for wallet type to withdraw from walletType := "exchange" - resp, err := b.WithdrawCryptocurrency(ctx, + resp, err := e.WithdrawCryptocurrency(ctx, walletType, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, @@ -873,7 +873,7 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted // Returns comma delimited withdrawal IDs -func (b *Bitfinex) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -882,7 +882,7 @@ func (b *Bitfinex) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withd // As this is for trading, I've made the wrapper default 'exchange' // TODO: Discover an automated way to make the decision for wallet type to withdraw from walletType := "exchange" - resp, err := b.WithdrawFIAT(ctx, withdrawalType, walletType, withdrawRequest) + resp, err := e.WithdrawFIAT(ctx, withdrawalType, walletType, withdrawRequest) if err != nil { return nil, err } @@ -895,11 +895,11 @@ func (b *Bitfinex) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withd // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted // Returns comma delimited withdrawal IDs -func (b *Bitfinex) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := b.WithdrawFiatFunds(ctx, withdrawRequest) + v, err := e.WithdrawFiatFunds(ctx, withdrawRequest) if err != nil { return nil, err } @@ -910,25 +910,25 @@ func (b *Bitfinex) WithdrawFiatFundsToInternationalBank(ctx context.Context, wit } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitfinex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := b.GetOpenOrders(ctx) + resp, err := e.GetOpenOrders(ctx) if err != nil { return nil, err } @@ -936,18 +936,18 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReq orders := make([]order.Detail, len(resp)) for i := range resp { var orderDetail *order.Detail - orderDetail, err = b.parseOrderToOrderDetail(&resp[i]) + orderDetail, err = e.parseOrderToOrderDetail(&resp[i]) if err != nil { return nil, err } orders[i] = *orderDetail } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -955,22 +955,22 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq var orders []order.Detail for i := range req.Pairs { - b.appendOptionalDelimiter(&req.Pairs[i]) + e.appendOptionalDelimiter(&req.Pairs[i]) var cf string - cf, err = b.fixCasing(req.Pairs[i], req.AssetType) + cf, err = e.fixCasing(req.Pairs[i], req.AssetType) if err != nil { return nil, err } var resp []Order - resp, err = b.GetInactiveOrders(ctx, cf) + resp, err = e.GetInactiveOrders(ctx, cf) if err != nil { return nil, err } for j := range resp { var orderDetail *order.Detail - orderDetail, err = b.parseOrderToOrderDetail(&resp[j]) + orderDetail, err = e.parseOrderToOrderDetail(&resp[j]) if err != nil { return nil, err } @@ -978,16 +978,16 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // AuthenticateWebsocket sends an authentication message to the websocket -func (b *Bitfinex) AuthenticateWebsocket(ctx context.Context) error { - return b.WsSendAuth(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.WsSendAuth(ctx) } // appendOptionalDelimiter ensures that a delimiter is present for long character currencies -func (b *Bitfinex) appendOptionalDelimiter(p *currency.Pair) { +func (e *Exchange) appendOptionalDelimiter(p *currency.Pair) { if (len(p.Base.String()) > 3 && !p.Quote.IsEmpty()) || len(p.Quote.String()) > 3 { p.Delimiter = ":" @@ -996,13 +996,13 @@ func (b *Bitfinex) appendOptionalDelimiter(p *currency.Pair) { // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Bitfinex) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (b *Bitfinex) FormatExchangeKlineInterval(in kline.Interval) (string, error) { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) (string, error) { switch in { case kline.OneMin: return "1m", nil @@ -1034,21 +1034,21 @@ func (b *Bitfinex) FormatExchangeKlineInterval(in kline.Interval) (string, error } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitfinex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - cf, err := b.fixCasing(req.Pair, req.Asset) + cf, err := e.fixCasing(req.Pair, req.Asset) if err != nil { return nil, err } - fInterval, err := b.FormatExchangeKlineInterval(req.ExchangeInterval) + fInterval, err := e.FormatExchangeKlineInterval(req.ExchangeInterval) if err != nil { return nil, err } - candles, err := b.GetCandles(ctx, cf, fInterval, req.Start, req.End, req.RequestLimit, true) + candles, err := e.GetCandles(ctx, cf, fInterval, req.Start, req.End, req.RequestLimit, true) if err != nil { return nil, err } @@ -1068,24 +1068,24 @@ func (b *Bitfinex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitfinex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } - cf, err := b.fixCasing(req.Pair, req.Asset) + cf, err := e.fixCasing(req.Pair, req.Asset) if err != nil { return nil, err } - fInterval, err := b.FormatExchangeKlineInterval(req.ExchangeInterval) + fInterval, err := e.FormatExchangeKlineInterval(req.ExchangeInterval) if err != nil { return nil, err } timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var candles []Candle - candles, err = b.GetCandles(ctx, cf, fInterval, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time, req.RequestLimit, true) + candles, err = e.GetCandles(ctx, cf, fInterval, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time, req.RequestLimit, true) if err != nil { return nil, err } @@ -1104,7 +1104,7 @@ func (b *Bitfinex) GetHistoricCandlesExtended(ctx context.Context, pair currency return req.ProcessResponse(timeSeries) } -func (b *Bitfinex) fixCasing(in currency.Pair, a asset.Item) (string, error) { +func (e *Exchange) fixCasing(in currency.Pair, a asset.Item) (string, error) { if in.Base.IsEmpty() { return "", currency.ErrCurrencyPairEmpty } @@ -1123,7 +1123,7 @@ func (b *Bitfinex) fixCasing(in currency.Pair, a asset.Item) (string, error) { checkString[1] = 'F' } - cFmt, err := b.FormatExchangeCurrency(in, a) + cFmt, err := e.FormatExchangeCurrency(in, a) if err != nil { return "", err } @@ -1145,10 +1145,9 @@ func (b *Bitfinex) fixCasing(in currency.Pair, a asset.Item) (string, error) { return string(runes), nil } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (b *Bitfinex) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - if err := b.PopulateAcceptableMethods(ctx); err != nil { +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + if err := e.PopulateAcceptableMethods(ctx); err != nil { return nil, err } @@ -1165,34 +1164,34 @@ func (b *Bitfinex) GetAvailableTransferChains(ctx context.Context, cryptocurrenc } // GetServerTime returns the current exchange server time. -func (b *Bitfinex) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (b *Bitfinex) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (b *Bitfinex) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { // TODO: Add futures support for Bitfinex return nil, common.ErrNotYetImplemented } // GetOpenInterest returns the open interest rate for a given asset pair -func (b *Bitfinex) GetOpenInterest(context.Context, ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(context.Context, ...key.PairAsset) ([]futures.OpenInterest, error) { // TODO: Add futures support for Bitfinex return nil, common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Bitfinex) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } - symbol, err := b.FormatSymbol(cp, a) + symbol, err := e.FormatSymbol(cp, a) if err != nil { return "", err } diff --git a/exchanges/bitflyer/bitflyer.go b/exchanges/bitflyer/bitflyer.go index 915105beec7..85b1e1c3f4f 100644 --- a/exchanges/bitflyer/bitflyer.go +++ b/exchanges/bitflyer/bitflyer.go @@ -42,82 +42,82 @@ const ( lowVolume ) -// Bitflyer is the overarching type across this package -type Bitflyer struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bitflyer +type Exchange struct { exchange.Base } // GetLatestBlockCA returns the latest block information from bitflyer chain // analysis system -func (b *Bitflyer) GetLatestBlockCA(ctx context.Context) (ChainAnalysisBlock, error) { +func (e *Exchange) GetLatestBlockCA(ctx context.Context) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, latestBlock, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.ChainAnalysis, latestBlock, &resp) } // GetBlockCA returns block information by blockhash from bitflyer chain // analysis system -func (b *Bitflyer) GetBlockCA(ctx context.Context, blockhash string) (ChainAnalysisBlock, error) { +func (e *Exchange) GetBlockCA(ctx context.Context, blockhash string) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHash+blockhash, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHash+blockhash, &resp) } // GetBlockbyHeightCA returns the block information by height from bitflyer chain // analysis system -func (b *Bitflyer) GetBlockbyHeightCA(ctx context.Context, height int64) (ChainAnalysisBlock, error) { +func (e *Exchange) GetBlockbyHeightCA(ctx context.Context, height int64) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHeight+strconv.FormatInt(height, 10), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHeight+strconv.FormatInt(height, 10), &resp) } // GetTransactionByHashCA returns transaction information by txHash from // bitflyer chain analysis system -func (b *Bitflyer) GetTransactionByHashCA(ctx context.Context, txHash string) (ChainAnalysisTransaction, error) { +func (e *Exchange) GetTransactionByHashCA(ctx context.Context, txHash string) (ChainAnalysisTransaction, error) { var resp ChainAnalysisTransaction - return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, transaction+txHash, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.ChainAnalysis, transaction+txHash, &resp) } // GetAddressInfoCA returns balance information for address by addressln string // from bitflyer chain analysis system -func (b *Bitflyer) GetAddressInfoCA(ctx context.Context, addressln string) (ChainAnalysisAddress, error) { +func (e *Exchange) GetAddressInfoCA(ctx context.Context, addressln string) (ChainAnalysisAddress, error) { var resp ChainAnalysisAddress - return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, address+addressln, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.ChainAnalysis, address+addressln, &resp) } // GetMarkets returns market information -func (b *Bitflyer) GetMarkets(ctx context.Context) ([]MarketInfo, error) { +func (e *Exchange) GetMarkets(ctx context.Context) ([]MarketInfo, error) { var resp []MarketInfo - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetMarkets, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetMarkets, &resp) } // GetOrderBook returns market orderbook depth -func (b *Bitflyer) GetOrderBook(ctx context.Context, symbol string) (Orderbook, error) { +func (e *Exchange) GetOrderBook(ctx context.Context, symbol string) (Orderbook, error) { var resp Orderbook v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetBoard+"?"+v.Encode(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetBoard+"?"+v.Encode(), &resp) } // GetTicker returns ticker information -func (b *Bitflyer) GetTicker(ctx context.Context, symbol string) (Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (Ticker, error) { var resp Ticker v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetTicker+"?"+v.Encode(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetTicker+"?"+v.Encode(), &resp) } // GetExecutionHistory returns past trades that were executed on the market -func (b *Bitflyer) GetExecutionHistory(ctx context.Context, symbol string) ([]ExecutedTrade, error) { +func (e *Exchange) GetExecutionHistory(ctx context.Context, symbol string) ([]ExecutedTrade, error) { var resp []ExecutedTrade v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetExecutionHistory+"?"+v.Encode(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetExecutionHistory+"?"+v.Encode(), &resp) } // GetExchangeStatus returns exchange status information -func (b *Bitflyer) GetExchangeStatus(ctx context.Context) (string, error) { +func (e *Exchange) GetExchangeStatus(ctx context.Context) (string, error) { resp := make(map[string]string) - err := b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetHealth, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetHealth, &resp) if err != nil { return "", err } @@ -138,132 +138,132 @@ func (b *Bitflyer) GetExchangeStatus(ctx context.Context) (string, error) { // GetChats returns trollbox chat log // Note: returns vary from instant to infinity -func (b *Bitflyer) GetChats(ctx context.Context, fromDate string) ([]ChatLog, error) { +func (e *Exchange) GetChats(ctx context.Context, fromDate string) ([]ChatLog, error) { var resp []ChatLog v := url.Values{} v.Set("from_date", fromDate) - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetChats+"?"+v.Encode(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, pubGetChats+"?"+v.Encode(), &resp) } // GetPermissions returns current permissions for associated with your API // keys -func (b *Bitflyer) GetPermissions() { +func (e *Exchange) GetPermissions() { // Needs to be updated } // GetAccountBalance returnsthe full list of account funds -func (b *Bitflyer) GetAccountBalance() { +func (e *Exchange) GetAccountBalance() { // Needs to be updated } // GetMarginStatus returns current margin status -func (b *Bitflyer) GetMarginStatus() { +func (e *Exchange) GetMarginStatus() { // Needs to be updated } // GetCollateralAccounts returns a full list of collateralised accounts -func (b *Bitflyer) GetCollateralAccounts() { +func (e *Exchange) GetCollateralAccounts() { // Needs to be updated } // GetCryptoDepositAddress returns an address for cryptocurrency deposits -func (b *Bitflyer) GetCryptoDepositAddress() { +func (e *Exchange) GetCryptoDepositAddress() { // Needs to be updated } // GetDepositHistory returns a full history of deposits -func (b *Bitflyer) GetDepositHistory() { +func (e *Exchange) GetDepositHistory() { // Needs to be updated } // GetTransactionHistory returns a full history of transactions -func (b *Bitflyer) GetTransactionHistory() { +func (e *Exchange) GetTransactionHistory() { // Needs to be updated } // GetBankAccSummary returns a full list of bank accounts assoc. with your keys -func (b *Bitflyer) GetBankAccSummary() { +func (e *Exchange) GetBankAccSummary() { // Needs to be updated } // GetCashDeposits returns a full list of cash deposits to the exchange -func (b *Bitflyer) GetCashDeposits() { +func (e *Exchange) GetCashDeposits() { // Needs to be updated } // WithdrawFunds withdraws funds to a certain bank -func (b *Bitflyer) WithdrawFunds() { +func (e *Exchange) WithdrawFunds() { // Needs to be updated } // GetDepositCancellationHistory returns the cancellation history of deposits -func (b *Bitflyer) GetDepositCancellationHistory() { +func (e *Exchange) GetDepositCancellationHistory() { // Needs to be updated } // SendOrder creates new order -func (b *Bitflyer) SendOrder() { +func (e *Exchange) SendOrder() { // Needs to be updated } // CancelExistingOrder cancels an order -func (b *Bitflyer) CancelExistingOrder() { +func (e *Exchange) CancelExistingOrder() { // Needs to be updated } // SendParentOrder sends a special order -func (b *Bitflyer) SendParentOrder() { +func (e *Exchange) SendParentOrder() { // Needs to be updated } // CancelParentOrder cancels a special order -func (b *Bitflyer) CancelParentOrder() { +func (e *Exchange) CancelParentOrder() { // Needs to be updated } // CancelAllExistingOrders cancels all orders on the exchange -func (b *Bitflyer) CancelAllExistingOrders() { +func (e *Exchange) CancelAllExistingOrders() { // Needs to be updated } // GetAllOrders returns a list of all orders -func (b *Bitflyer) GetAllOrders() { +func (e *Exchange) GetAllOrders() { // Needs to be updated } // GetParentOrders returns a list of all parent orders -func (b *Bitflyer) GetParentOrders() { +func (e *Exchange) GetParentOrders() { // Needs to be updated } // GetParentOrderDetails returns a detailing of a parent order -func (b *Bitflyer) GetParentOrderDetails() { +func (e *Exchange) GetParentOrderDetails() { // Needs to be updated } // GetExecutions returns execution details -func (b *Bitflyer) GetExecutions() { +func (e *Exchange) GetExecutions() { // Needs to be updated } // GetOpenInterestData returns a summary of open interest -func (b *Bitflyer) GetOpenInterestData() { +func (e *Exchange) GetOpenInterestData() { // Needs to be updated } // GetMarginChange returns collateral history -func (b *Bitflyer) GetMarginChange() { +func (e *Exchange) GetMarginChange() { // Needs to be updated } // GetTradingCommission returns trading commission -func (b *Bitflyer) GetTradingCommission() { +func (e *Exchange) GetTradingCommission() { // Needs to be updated } // SendHTTPRequest sends an unauthenticated request -func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := b.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -271,11 +271,11 @@ func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } @@ -284,7 +284,7 @@ func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st // Note: HTTP not done due to incorrect account privileges, please open a PR // if you have access and update the authenticated requests // TODO: Fill out this function once API access is obtained -func (b *Bitflyer) SendAuthHTTPRequest() { +func (e *Exchange) SendAuthHTTPRequest() { //nolint:gocritic // code example // headers := make(map[string]string) // headers["ACCESS-KEY"] = b.API.Credentials.Key @@ -293,7 +293,7 @@ func (b *Bitflyer) SendAuthHTTPRequest() { // GetFee returns an estimate of fee based on type of transaction // TODO: Figure out the weird fee structure. Do we use Bitcoin Easy Exchange,Lightning Spot,Bitcoin Market,Lightning FX/Futures ??? -func (b *Bitflyer) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index 9addb99623e..00c32045655 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -26,17 +26,17 @@ const ( canManipulateRealOrders = false ) -var b *Bitflyer +var e *Exchange func TestMain(m *testing.M) { - b = new(Bitflyer) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bitflyer Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -44,7 +44,7 @@ func TestMain(m *testing.M) { func TestGetLatestBlockCA(t *testing.T) { t.Parallel() - _, err := b.GetLatestBlockCA(t.Context()) + _, err := e.GetLatestBlockCA(t.Context()) if err != nil { t.Error("Bitflyer - GetLatestBlockCA() error:", err) } @@ -52,7 +52,7 @@ func TestGetLatestBlockCA(t *testing.T) { func TestGetBlockCA(t *testing.T) { t.Parallel() - _, err := b.GetBlockCA(t.Context(), "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") + _, err := e.GetBlockCA(t.Context(), "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") if err != nil { t.Error("Bitflyer - GetBlockCA() error:", err) } @@ -60,7 +60,7 @@ func TestGetBlockCA(t *testing.T) { func TestGetBlockbyHeightCA(t *testing.T) { t.Parallel() - _, err := b.GetBlockbyHeightCA(t.Context(), 0) + _, err := e.GetBlockbyHeightCA(t.Context(), 0) if err != nil { t.Error("Bitflyer - GetBlockbyHeightCA() error:", err) } @@ -68,7 +68,7 @@ func TestGetBlockbyHeightCA(t *testing.T) { func TestGetTransactionByHashCA(t *testing.T) { t.Parallel() - _, err := b.GetTransactionByHashCA(t.Context(), "0562d1f063cd4127053d838b165630445af5e480ceb24e1fd9ecea52903cb772") + _, err := e.GetTransactionByHashCA(t.Context(), "0562d1f063cd4127053d838b165630445af5e480ceb24e1fd9ecea52903cb772") if err != nil { t.Error("Bitflyer - GetTransactionByHashCA() error:", err) } @@ -76,7 +76,7 @@ func TestGetTransactionByHashCA(t *testing.T) { func TestGetAddressInfoCA(t *testing.T) { t.Parallel() - v, err := b.GetAddressInfoCA(t.Context(), core.BitcoinDonationAddress) + v, err := e.GetAddressInfoCA(t.Context(), core.BitcoinDonationAddress) if err != nil { t.Error("Bitflyer - GetAddressInfoCA() error:", err) } @@ -87,7 +87,7 @@ func TestGetAddressInfoCA(t *testing.T) { func TestGetMarkets(t *testing.T) { t.Parallel() - markets, err := b.GetMarkets(t.Context()) + markets, err := e.GetMarkets(t.Context()) if err != nil { t.Error("Bitflyer - GetMarkets() error:", err) } @@ -103,7 +103,7 @@ func TestGetMarkets(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook(t.Context(), "BTC_JPY") + _, err := e.GetOrderBook(t.Context(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetOrderBook() error:", err) } @@ -111,7 +111,7 @@ func TestGetOrderBook(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(t.Context(), "BTC_JPY") + _, err := e.GetTicker(t.Context(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetTicker() error:", err) } @@ -119,7 +119,7 @@ func TestGetTicker(t *testing.T) { func TestGetExecutionHistory(t *testing.T) { t.Parallel() - _, err := b.GetExecutionHistory(t.Context(), "BTC_JPY") + _, err := e.GetExecutionHistory(t.Context(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetExecutionHistory() error:", err) } @@ -127,7 +127,7 @@ func TestGetExecutionHistory(t *testing.T) { func TestGetExchangeStatus(t *testing.T) { t.Parallel() - _, err := b.GetExchangeStatus(t.Context()) + _, err := e.GetExchangeStatus(t.Context()) if err != nil { t.Error("Bitflyer - GetExchangeStatus() error:", err) } @@ -139,7 +139,7 @@ func TestCheckFXString(t *testing.T) { if err != nil { t.Fatal(err) } - p = b.CheckFXString(p) + p = e.CheckFXString(p) if p.Base.String() != "FX_BTC" { t.Error("Bitflyer - CheckFXString() error") } @@ -159,11 +159,11 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(b) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -178,9 +178,9 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(b) { + if sharedtestvalues.AreAPICredentialsSet(e) { // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -188,28 +188,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } } @@ -217,7 +217,7 @@ func TestGetFee(t *testing.T) { // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -225,7 +225,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.JPY - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -233,7 +233,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.JPY - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } } @@ -241,7 +241,7 @@ func TestGetFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawFiatText + " & " + exchange.WithdrawCryptoViaWebsiteOnlyText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -255,10 +255,10 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(b) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -271,7 +271,7 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received '%v'", common.ErrNotYetImplemented, err) } @@ -282,10 +282,10 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.BTC, Quote: currency.LTC, @@ -297,7 +297,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - _, err := b.SubmitOrder(t.Context(), orderSubmission) + _, err := e.SubmitOrder(t.Context(), orderSubmission) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) } @@ -305,7 +305,7 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -315,7 +315,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) @@ -324,7 +324,7 @@ func TestCancelExchangeOrder(t *testing.T) { func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -334,7 +334,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.CancelAllOrders(t.Context(), orderCancellation) + _, err := e.CancelAllOrders(t.Context(), orderCancellation) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) @@ -343,10 +343,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: b.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -355,7 +355,7 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) @@ -364,8 +364,8 @@ func TestWithdraw(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifyOrder(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") @@ -374,11 +374,11 @@ func TestModifyOrder(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) } @@ -386,11 +386,11 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) @@ -403,7 +403,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(t.Context(), currencyPair, asset.Spot) + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -415,7 +415,7 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(t.Context(), + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Fatal(err) @@ -424,19 +424,19 @@ func TestGetHistoricTrades(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) + testexch.UpdatePairsOnce(t, e) } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - err := b.CurrencyPairs.SetAssetEnabled(asset.Futures, false) + testexch.UpdatePairsOnce(t, e) + err := e.CurrencyPairs.SetAssetEnabled(asset.Futures, false) require.NoError(t, err, "SetAssetEnabled must not error") - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err, "GetCurrencyTradeURL must not error") assert.NotEmpty(t, resp, "GetCurrencyTradeURL should return an url") } diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index 89011d46999..a5b0c75a197 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -29,12 +29,12 @@ import ( ) // SetDefaults sets the basic defaults for Bitflyer -func (b *Bitflyer) SetDefaults() { - b.Name = "Bitflyer" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Bitflyer" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{ Delimiter: currency.UnderscoreDelimiter, @@ -44,7 +44,7 @@ func (b *Bitflyer) SetDefaults() { Delimiter: currency.UnderscoreDelimiter, Uppercase: true, } - err := b.SetGlobalPairsManager(requestFmt, + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot, asset.Futures) @@ -52,7 +52,7 @@ func (b *Bitflyer) SetDefaults() { log.Errorln(log.ExchangeSys, err) } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: false, @@ -72,14 +72,14 @@ func (b *Bitflyer) SetDefaults() { }, } - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: japanURL, exchange.ChainAnalysis: chainAnalysis, }) @@ -89,20 +89,20 @@ func (b *Bitflyer) SetDefaults() { } // Setup takes in the supplied exchange configuration details and sets params -func (b *Bitflyer) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { if err := exch.Validate(); err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - return b.SetupDefaults(exch) + return e.SetupDefaults(exch) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitflyer) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - symbols, err := b.GetMarkets(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + symbols, err := e.GetMarkets(ctx) if err != nil { return nil, err } @@ -130,39 +130,39 @@ func (b *Bitflyer) FetchTradablePairs(ctx context.Context, a asset.Item) (curren // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitflyer) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := b.CurrencyPairs.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.CurrencyPairs.GetAssetTypes(false) for _, a := range assets { - pairs, err := b.FetchTradablePairs(ctx, a) + pairs, err := e.FetchTradablePairs(ctx, a) if err != nil { return err } - err = b.UpdatePairs(pairs, a, false, forceUpdate) + err = e.UpdatePairs(pairs, a, false, forceUpdate) if err != nil { return err } } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitflyer) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (b *Bitflyer) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitflyer) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - fPair, err := b.FormatExchangeCurrency(p, a) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tickerNew, err := b.GetTicker(ctx, b.CheckFXString(fPair).String()) + tickerNew, err := e.GetTicker(ctx, e.CheckFXString(fPair).String()) if err != nil { return nil, err } @@ -173,18 +173,18 @@ func (b *Bitflyer) UpdateTicker(ctx context.Context, p currency.Pair, a asset.It Bid: tickerNew.BestBid, Last: tickerNew.Last, Volume: tickerNew.Volume, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(b.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } // CheckFXString upgrades currency pair if needed -func (b *Bitflyer) CheckFXString(p currency.Pair) currency.Pair { +func (e *Exchange) CheckFXString(p currency.Pair) currency.Pair { if strings.Contains(p.Base.String(), "FX") { p.Base = currency.FX_BTC return p @@ -193,26 +193,26 @@ func (b *Bitflyer) CheckFXString(p currency.Pair) currency.Pair { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := b.GetOrderBook(ctx, b.CheckFXString(fPair).String()) + orderbookNew, err := e.GetOrderBook(ctx, e.CheckFXString(fPair).String()) if err != nil { return book, err } @@ -238,34 +238,34 @@ func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy return book, err } - return orderbook.Get(b.Name, fPair, assetType) + return orderbook.Get(e.Name, fPair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies on the // Bitflyer exchange -func (b *Bitflyer) UpdateAccountInfo(_ context.Context, _ asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(_ context.Context, _ asset.Item) (account.Holdings, error) { return account.Holdings{}, common.ErrNotYetImplemented } // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitflyer) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitflyer) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns recent historic trades -func (b *Bitflyer) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = b.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetExecutionHistory(ctx, p.String()) + tradeData, err := e.GetExecutionHistory(ctx, p.String()) if err != nil { return nil, err } @@ -278,7 +278,7 @@ func (b *Bitflyer) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy } resp[i] = trade.Data{ TID: strconv.FormatInt(tradeData[i].ID, 10), - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -288,7 +288,7 @@ func (b *Bitflyer) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -298,124 +298,124 @@ func (b *Bitflyer) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitflyer) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *Bitflyer) SubmitOrder(_ context.Context, _ *order.Submit) (*order.SubmitResponse, error) { +func (e *Exchange) SubmitOrder(_ context.Context, _ *order.Submit) (*order.SubmitResponse, error) { return nil, common.ErrNotYetImplemented } // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitflyer) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitflyer) CancelOrder(_ context.Context, _ *order.Cancel) error { +func (e *Exchange) CancelOrder(_ context.Context, _ *order.Cancel) error { return common.ErrNotYetImplemented } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitflyer) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitflyer) CancelAllOrders(_ context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(_ context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { // TODO, implement BitFlyer API - b.CancelAllExistingOrders() + e.CancelAllExistingOrders() return order.CancelAllResponse{}, common.ErrNotYetImplemented } // GetOrderInfo returns order information based on order ID -func (b *Bitflyer) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { return nil, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitflyer) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { return nil, common.ErrNotYetImplemented } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitflyer) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitflyer) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitflyer) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitflyer) GetActiveOrders(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { return nil, common.ErrNotYetImplemented } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitflyer) GetOrderHistory(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(_ context.Context, _ *order.MultiOrderRequest) (order.FilteredOrders, error) { return nil, common.ErrNotYetImplemented } // GetFeeByType returns an estimate of fee based on the type of transaction -func (b *Bitflyer) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Bitflyer) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitflyer) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitflyer) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (b *Bitflyer) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (b *Bitflyer) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (b *Bitflyer) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Bitflyer) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index b12ace201ac..d1658627e26 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -53,16 +53,16 @@ const ( var errSymbolIsEmpty = errors.New("symbol cannot be empty") -// Bithumb is the overarching type across the Bithumb package -type Bithumb struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bithumb +type Exchange struct { exchange.Base location *time.Location obm orderbookManager } // GetTradablePairs returns a list of tradable currencies -func (b *Bithumb) GetTradablePairs(ctx context.Context) ([]string, error) { - result, err := b.GetAllTickers(ctx) +func (e *Exchange) GetTradablePairs(ctx context.Context) ([]string, error) { + result, err := e.GetAllTickers(ctx) if err != nil { return nil, err } @@ -77,9 +77,9 @@ func (b *Bithumb) GetTradablePairs(ctx context.Context) ([]string, error) { // GetTicker returns ticker information // // symbol e.g. "btc" -func (b *Bithumb) GetTicker(ctx context.Context, symbol string) (Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (Ticker, error) { var response TickerResponse - err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response) if err != nil { return response.Data, err } @@ -92,9 +92,9 @@ func (b *Bithumb) GetTicker(ctx context.Context, symbol string) (Ticker, error) } // GetAllTickers returns all ticker information -func (b *Bithumb) GetAllTickers(ctx context.Context) (map[string]Ticker, error) { +func (e *Exchange) GetAllTickers(ctx context.Context) (map[string]Ticker, error) { var response TickersResponse - err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+"all", &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+"all", &response) if err != nil { return nil, err } @@ -121,9 +121,9 @@ func (b *Bithumb) GetAllTickers(ctx context.Context) (map[string]Ticker, error) // GetOrderBook returns current orderbook // // symbol e.g. "btc" -func (b *Bithumb) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, error) { response := Orderbook{} - err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response) if err != nil { return nil, err } @@ -136,12 +136,12 @@ func (b *Bithumb) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, } // GetAssetStatus returns the withdrawal and deposit status for the symbol -func (b *Bithumb) GetAssetStatus(ctx context.Context, symbol string) (*Status, error) { +func (e *Exchange) GetAssetStatus(ctx context.Context, symbol string) (*Status, error) { if symbol == "" { return nil, errSymbolIsEmpty } var response Status - err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response) if err != nil { return nil, err } @@ -154,9 +154,9 @@ func (b *Bithumb) GetAssetStatus(ctx context.Context, symbol string) (*Status, e } // GetAssetStatusAll returns the withdrawal and deposit status for all symbols -func (b *Bithumb) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) { +func (e *Exchange) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) { var response StatusAll - err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+"ALL", &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+"ALL", &response) if err != nil { return nil, err } @@ -171,12 +171,12 @@ func (b *Bithumb) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) { // GetTransactionHistory returns recent transactions // // symbol e.g. "btc" -func (b *Bithumb) GetTransactionHistory(ctx context.Context, symbol string) (TransactionHistory, error) { +func (e *Exchange) GetTransactionHistory(ctx context.Context, symbol string) (TransactionHistory, error) { response := TransactionHistory{} path := publicTransactionHistory + strings.ToUpper(symbol) - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) if err != nil { return response, err } @@ -190,7 +190,7 @@ func (b *Bithumb) GetTransactionHistory(ctx context.Context, symbol string) (Tra // GetAccountInformation returns account information based on the desired // order/payment currencies -func (b *Bithumb) GetAccountInformation(ctx context.Context, orderCurrency, paymentCurrency string) (Account, error) { +func (e *Exchange) GetAccountInformation(ctx context.Context, orderCurrency, paymentCurrency string) (Account, error) { var response Account if orderCurrency == "" { return response, errSymbolIsEmpty @@ -203,11 +203,11 @@ func (b *Bithumb) GetAccountInformation(ctx context.Context, orderCurrency, paym } return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccInfo, val, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccInfo, val, &response) } // GetAccountBalance returns customer wallet information -func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance, error) { +func (e *Exchange) GetAccountBalance(ctx context.Context, c string) (FullBalance, error) { var response Balance fullBalance := FullBalance{ make(map[string]float64), @@ -222,7 +222,7 @@ func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance, vals.Set("currency", c) } - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccBalance, vals, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccBalance, vals, &response) if err != nil { return fullBalance, err } @@ -260,12 +260,12 @@ func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance, // GetWalletAddress returns customer wallet address // // currency e.g. btc, ltc or "", will default to btc without currency specified -func (b *Bithumb) GetWalletAddress(ctx context.Context, curr currency.Code) (WalletAddressRes, error) { +func (e *Exchange) GetWalletAddress(ctx context.Context, curr currency.Code) (WalletAddressRes, error) { response := WalletAddressRes{} params := url.Values{} params.Set("currency", curr.Upper().String()) - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateWalletAdd, params, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateWalletAdd, params, &response) if err != nil { return response, err } @@ -303,11 +303,11 @@ func (b *Bithumb) GetWalletAddress(ctx context.Context, curr currency.Code) (Wal } // GetLastTransaction returns customer last transaction -func (b *Bithumb) GetLastTransaction(ctx context.Context) (LastTransactionTicker, error) { +func (e *Exchange) GetLastTransaction(ctx context.Context) (LastTransactionTicker, error) { response := LastTransactionTicker{} return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateTicker, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateTicker, nil, &response) } // GetOrders returns order list @@ -317,7 +317,7 @@ func (b *Bithumb) GetLastTransaction(ctx context.Context) (LastTransactionTicker // count: Value : 1 ~1000 (default : 100) // after: YYYY-MM-DD hh:mm:ss's UNIX Timestamp // (2014-11-28 16:40:01 = 1417160401000) -func (b *Bithumb) GetOrders(ctx context.Context, orderID, transactionType string, count int64, after time.Time, orderCurrency, paymentCurrency currency.Code) (Orders, error) { +func (e *Exchange) GetOrders(ctx context.Context, orderID, transactionType string, count int64, after time.Time, orderCurrency, paymentCurrency currency.Code) (Orders, error) { response := Orders{} params := url.Values{} @@ -347,11 +347,11 @@ func (b *Bithumb) GetOrders(ctx context.Context, orderID, transactionType string } return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrders, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrders, params, &response) } // GetUserTransactions returns customer transactions -func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, searchType int64, orderCurrency, paymentCurrency currency.Code) (UserTransactions, error) { +func (e *Exchange) GetUserTransactions(ctx context.Context, offset, count, searchType int64, orderCurrency, paymentCurrency currency.Code) (UserTransactions, error) { params := url.Values{} if offset > 0 { params.Set("offset", strconv.FormatInt(offset, 10)) @@ -370,7 +370,7 @@ func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, search } var response UserTransactions - return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUserTrans, params, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUserTrans, params, &response) } // PlaceTrade executes a trade order @@ -380,7 +380,7 @@ func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, search // transactionType: Transaction type(bid : purchase, ask : sales) // units: Order quantity // price: Transaction amount per currency -func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { +func (e *Exchange) PlaceTrade(ctx context.Context, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { response := OrderPlace{} params := url.Values{} @@ -391,7 +391,7 @@ func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType params.Set("price", strconv.FormatInt(price, 10)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response) } // GetOrderDetails returns specific order details @@ -400,7 +400,7 @@ func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType // transactionType: Transaction type(bid : purchase, ask : sales) // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) { +func (e *Exchange) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) { response := OrderDetails{} params := url.Values{} @@ -409,7 +409,7 @@ func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType, params.Set("currency", strings.ToUpper(currency)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response) } // CancelTrade cancels a customer purchase/sales transaction @@ -417,7 +417,7 @@ func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType, // orderID: Order number registered for purchase/sales // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) { +func (e *Exchange) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -426,7 +426,7 @@ func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, cur params.Set("currency", strings.ToUpper(currency)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response) } // WithdrawCrypto withdraws a customer currency to an address @@ -437,7 +437,7 @@ func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, cur // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM // (default value: BTC) // units: Quantity to withdraw currency -func (b *Bithumb) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -449,16 +449,16 @@ func (b *Bithumb) WithdrawCrypto(ctx context.Context, address, destination, curr params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateBTCWithdraw, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateBTCWithdraw, params, &response) } // RequestKRWDepositDetails returns Bithumb banking details for deposit // information -func (b *Bithumb) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, error) { +func (e *Exchange) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, error) { response := KRWDeposit{} return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWDeposit, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWDeposit, nil, &response) } // RequestKRWWithdraw allows a customer KRW withdrawal request @@ -466,7 +466,7 @@ func (b *Bithumb) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, err // bank: Bankcode with bank name e.g. (bankcode)_(bankname) // account: Withdrawing bank account number // price: Withdrawing amount -func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string, price int64) (ActionStatus, error) { +func (e *Exchange) RequestKRWWithdraw(ctx context.Context, bank, account string, price int64) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -475,7 +475,7 @@ func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string, params.Set("price", strconv.FormatInt(price, 10)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWWithdraw, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWWithdraw, params, &response) } // MarketBuyOrder initiates a buy order through available order books @@ -483,7 +483,7 @@ func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string, // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) // units: Order quantity -func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units float64) (MarketBuy, error) { +func (e *Exchange) MarketBuyOrder(ctx context.Context, pair currency.Pair, units float64) (MarketBuy, error) { response := MarketBuy{} params := url.Values{} @@ -492,7 +492,7 @@ func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketBuy, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketBuy, params, &response) } // MarketSellOrder initiates a sell order through available order books @@ -500,7 +500,7 @@ func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) // units: Order quantity -func (b *Bithumb) MarketSellOrder(ctx context.Context, pair currency.Pair, units float64) (MarketSell, error) { +func (e *Exchange) MarketSellOrder(ctx context.Context, pair currency.Pair, units float64) (MarketSell, error) { response := MarketSell{} params := url.Values{} @@ -509,12 +509,12 @@ func (b *Bithumb) MarketSellOrder(ctx context.Context, pair currency.Pair, units params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketSell, params, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketSell, params, &response) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bithumb) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := b.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -522,22 +522,22 @@ func (b *Bithumb) SendHTTPRequest(ctx context.Context, ep exchange.URL, path str Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to bithumb -func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := b.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -546,7 +546,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange. } var intermediary json.RawMessage - err = b.SendPayload(ctx, request.Auth, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.Auth, func() (*request.Item, error) { // This is time window sensitive n := strconv.FormatInt(time.Now().UnixMilli(), 10) @@ -573,9 +573,9 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange. Body: bytes.NewBufferString(payload), Result: &intermediary, NonceEnabled: true, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -599,7 +599,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange. } // GetFee returns an estimate of fee based on type of transaction -func (b *Bithumb) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { @@ -676,15 +676,15 @@ var errCode = map[string]string{ } // GetCandleStick returns candle stick data for requested pair -func (b *Bithumb) GetCandleStick(ctx context.Context, symbol, interval string) (resp *OHLCVResponse, err error) { +func (e *Exchange) GetCandleStick(ctx context.Context, symbol, interval string) (resp *OHLCVResponse, err error) { path := publicCandleStick + symbol + "/" + interval - err = b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) return } // FetchExchangeLimits fetches spot order execution limits -func (b *Bithumb) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { - ticks, err := b.GetAllTickers(ctx) +func (e *Exchange) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { + ticks, err := e.GetAllTickers(ctx) if err != nil { return nil, err } diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index abfb2b613c8..0d45cd014ec 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -29,18 +29,18 @@ const ( var testPair = currency.NewPairWithDelimiter("BTC", "KRW", "_") -var b = &Bithumb{} +var e *Exchange func TestMain(m *testing.M) { - b = new(Bithumb) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bithumb Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.API.AuthenticatedWebsocketSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -48,13 +48,13 @@ func TestMain(m *testing.M) { func TestGetTradablePairs(t *testing.T) { t.Parallel() - _, err := b.GetTradablePairs(t.Context()) + _, err := e.GetTradablePairs(t.Context()) require.NoError(t, err, "GetTradablePairs must not error") } func TestGetTicker(t *testing.T) { t.Parallel() - tick, err := b.GetTicker(t.Context(), testPair.Base.String()) + tick, err := e.GetTicker(t.Context(), testPair.Base.String()) require.NoError(t, err, "GetTicker must not error") assert.Positive(t, tick.OpeningPrice, "OpeningPrice should be positive") assert.Positive(t, tick.ClosingPrice, "ClosingPrice should be positive") @@ -73,14 +73,14 @@ func TestGetTicker(t *testing.T) { // not all currencies have dates and fluctuation rates func TestGetAllTickers(t *testing.T) { t.Parallel() - tick, err := b.GetAllTickers(t.Context()) + tick, err := e.GetAllTickers(t.Context()) require.NoError(t, err, "GetAllTickers must not error") assert.NotEmpty(t, tick, "tick should not be empty") } func TestGetOrderBook(t *testing.T) { t.Parallel() - ob, err := b.GetOrderBook(t.Context(), testPair.Base.String()) + ob, err := e.GetOrderBook(t.Context(), testPair.Base.String()) require.NoError(t, err, "GetOrderBook must not error") assert.NotEmpty(t, ob.Status, "Status should not be empty") assert.NotEmpty(t, ob.Data.Timestamp, "Timestamp should not be empty") @@ -90,8 +90,8 @@ func TestGetOrderBook(t *testing.T) { func TestGetTransactionHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetTransactionHistory(t.Context(), testPair.Base.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTransactionHistory(t.Context(), testPair.Base.String()) require.NoError(t, err, "GetTransactionHistory must not error") } @@ -99,28 +99,28 @@ func TestGetAccountInformation(t *testing.T) { t.Parallel() // Offline test - _, err := b.GetAccountInformation(t.Context(), "", "") + _, err := e.GetAccountInformation(t.Context(), "", "") assert.Error(t, err, "expected error when no order currency is specified") - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = b.GetAccountInformation(t.Context(), testPair.Base.String(), testPair.Quote.String()) + _, err = e.GetAccountInformation(t.Context(), testPair.Base.String(), testPair.Quote.String()) assert.NoError(t, err, "GetAccountInformation should not error") } func TestGetAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetAccountBalance(t.Context(), testPair.Base.String()) + _, err := e.GetAccountBalance(t.Context(), testPair.Base.String()) require.NoError(t, err, "GetAccountBalance must not error") } func TestGetWalletAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - a, err := b.GetWalletAddress(t.Context(), testPair.Base) + a, err := e.GetWalletAddress(t.Context(), testPair.Base) require.NoError(t, err, "GetWalletAddress must not error") assert.NotEmpty(t, a.Data.Currency, "Currency should not be empty") assert.NotEmpty(t, a.Data.Tag, "Tag should not be empty") @@ -129,96 +129,96 @@ func TestGetWalletAddress(t *testing.T) { func TestGetLastTransaction(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetLastTransaction(t.Context()) + _, err := e.GetLastTransaction(t.Context()) require.NoError(t, err, "GetLastTransaction must not error") } func TestGetOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetOrders(t.Context(), "1337", order.Bid.Lower(), 100, time.Time{}, testPair.Base, testPair.Quote) + _, err := e.GetOrders(t.Context(), "1337", order.Bid.Lower(), 100, time.Time{}, testPair.Base, testPair.Quote) require.NoError(t, err, "GetOrders must not error") } func TestGetUserTransactions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetUserTransactions(t.Context(), 0, 0, 0, currency.EMPTYCODE, currency.EMPTYCODE) + _, err := e.GetUserTransactions(t.Context(), 0, 0, 0, currency.EMPTYCODE, currency.EMPTYCODE) require.NoError(t, err, "GetUserTransactions must not error") } func TestPlaceTrade(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.PlaceTrade(t.Context(), testPair.Base.String(), order.Bid.Lower(), 0, 0) + _, err := e.PlaceTrade(t.Context(), testPair.Base.String(), order.Bid.Lower(), 0, 0) require.NoError(t, err, "PlaceTrade must not error") } func TestGetOrderDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetOrderDetails(t.Context(), "1337", order.Bid.Lower(), testPair.Base.String()) + _, err := e.GetOrderDetails(t.Context(), "1337", order.Bid.Lower(), testPair.Base.String()) require.NoError(t, err, "GetOrderDetails must not error") } func TestCancelTrade(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.CancelTrade(t.Context(), "", "", "") + _, err := e.CancelTrade(t.Context(), "", "", "") require.NoError(t, err, "CancelTrade must not error") } func TestWithdrawCrypto(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.WithdrawCrypto(t.Context(), "LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0) + _, err := e.WithdrawCrypto(t.Context(), "LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0) require.NoError(t, err, "WithdrawCrypto must not error") } func TestRequestKRWDepositDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.RequestKRWDepositDetails(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.RequestKRWDepositDetails(t.Context()) require.NoError(t, err, "RequestKRWDepositDetails must not error") } func TestRequestKRWWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.RequestKRWWithdraw(t.Context(), "102_bank", "1337", 1000) + _, err := e.RequestKRWWithdraw(t.Context(), "102_bank", "1337", 1000) require.NoError(t, err, "RequestKRWWithdraw must not error") } func TestMarketBuyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.MarketBuyOrder(t.Context(), testPair, 0) + _, err := e.MarketBuyOrder(t.Context(), testPair, 0) require.NoError(t, err, "MarketBuyOrder must not error") } func TestMarketSellOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.MarketSellOrder(t.Context(), testPair, 0) + _, err := e.MarketSellOrder(t.Context(), testPair, 0) require.NoError(t, err, "MarketSellOrder must not error") } func TestUpdateTicker(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - tick, err := b.UpdateTicker(t.Context(), testPair, asset.Spot) + testexch.UpdatePairsOnce(t, e) + tick, err := e.UpdateTicker(t.Context(), testPair, asset.Spot) require.NoError(t, err, "UpdateTicker must not error") assert.Positive(t, tick.High, "High should be positive") assert.Positive(t, tick.Low, "Low should be positive") @@ -233,8 +233,8 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - err := b.UpdateTickers(t.Context(), asset.Spot) + testexch.UpdatePairsOnce(t, e) + err := e.UpdateTickers(t.Context(), asset.Spot) require.NoError(t, err, "UpdateTickers must not error") } @@ -251,10 +251,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err, "GetFeeByType must not error") - if !sharedtestvalues.AreAPICredentialsSet(b) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "FeeType should be correct") } else { assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType, "FeeType should be correct") @@ -265,65 +265,65 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() // CryptocurrencyTradeFee Basic - _, err := b.GetFee(feeBuilder) + _, err := e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyTradeFee High quantity feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err, "GetFee must not error") } func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() assert.Equal(t, expectedResult, withdrawPermissions, "withdrawPermissions should be correct") } func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, @@ -331,13 +331,13 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) require.NoError(t, err, "GetActiveOrders must not error") } func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, @@ -346,7 +346,7 @@ func TestGetOrderHistory(t *testing.T) { Pairs: currency.Pairs{testPair}, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) require.NoError(t, err, "GetOrderHistory must not error") } @@ -355,10 +355,10 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: testPair, Side: order.Buy, Type: order.Limit, @@ -367,13 +367,13 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - _, err := b.SubmitOrder(t.Context(), orderSubmission) + _, err := e.SubmitOrder(t.Context(), orderSubmission) require.NoError(t, err, "SubmitOrder must not error") } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", @@ -382,13 +382,13 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) require.NoError(t, err, "CancelOrder must not error") } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", @@ -397,7 +397,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) require.NoError(t, err, "CancelAllOrders must not error") assert.Emptyf(t, resp.Status, "%v orders failed to cancel", len(resp.Status)) @@ -405,17 +405,17 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) require.NoError(t, err, "UpdateAccountInfo must not error") } func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.ModifyOrder(t.Context(), &order.Modify{ + _, err := e.ModifyOrder(t.Context(), &order.Modify{ OrderID: "1337", Price: 100, Amount: 1000, @@ -428,21 +428,21 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) t.Skip("TestWithdraw not allowed for live tests") } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Type: withdraw.Fiat, - Exchange: b.Name, + Exchange: e.Name, Fiat: withdraw.FiatRequest{ Bank: banking.Account{ - SupportedExchanges: b.Name, + SupportedExchanges: e.Name, Enabled: true, AccountName: "Satoshi Nakamoto", AccountNumber: "12345", @@ -464,30 +464,30 @@ func TestWithdrawFiat(t *testing.T) { Description: "WITHDRAW IT ALL", } - _, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) require.NoError(t, err, "WithdrawFiatFunds must not error") } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestGetDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetDepositAddress(t.Context(), testPair.Base, "", "") + _, err := e.GetDepositAddress(t.Context(), testPair.Base, "", "") require.NoError(t, err, "GetDepositAddress must not error") } func TestGetCandleStick(t *testing.T) { t.Parallel() - c, err := b.GetCandleStick(t.Context(), testPair.String(), "1m") + c, err := e.GetCandleStick(t.Context(), testPair.String(), "1m") require.NoError(t, err, "GetCandleStick must not error") assert.NotEmpty(t, c.Status, "Status should not be empty") assert.NotEmpty(t, c.Data, "Data should not be empty") @@ -496,7 +496,7 @@ func TestGetCandleStick(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() startTime := time.Now().AddDate(0, -1, 0) - c, err := b.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now()) + c, err := e.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now()) require.NoError(t, err, "GetHistoricCandles must not error") assert.NotEmpty(t, c.Exchange, "Exchange should not be empty") assert.NotEmpty(t, c.Candles, "Candles should not be empty") @@ -505,14 +505,14 @@ func TestGetHistoricCandles(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() startTime := time.Now().Add(-time.Hour * 24) - _, err := b.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now()) + _, err := e.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestGetRecentTrades(t *testing.T) { t.Parallel() - tr, err := b.GetRecentTrades(t.Context(), testPair, asset.Spot) + tr, err := e.GetRecentTrades(t.Context(), testPair, asset.Spot) require.NoError(t, err, "GetRecentTrades must not error") assert.NotEmpty(t, tr, "Trades should not be empty") for _, req := range tr { @@ -526,16 +526,16 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits(t.Context(), asset.Empty) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Empty) require.NoError(t, err, "UpdateOrderExecutionLimits must not error") - limit, err := b.GetOrderExecutionLimits(asset.Spot, testPair) + limit, err := e.GetOrderExecutionLimits(asset.Spot, testPair) require.NoError(t, err, "GetOrderExecutionLimits must not error") err = limit.Conforms(46241000, 0.00001, order.Limit) @@ -595,10 +595,10 @@ func TestGetAmountMinimum(t *testing.T) { func TestGetAssetStatus(t *testing.T) { t.Parallel() - _, err := b.GetAssetStatus(t.Context(), "") + _, err := e.GetAssetStatus(t.Context(), "") assert.ErrorIs(t, err, errSymbolIsEmpty) - s, err := b.GetAssetStatus(t.Context(), "sol") + s, err := e.GetAssetStatus(t.Context(), "sol") require.NoError(t, err, "GetAssetStatus must not error") assert.NotEmpty(t, s.Status, "Status should not be empty") assert.NotEmpty(t, s.Data.DepositStatus, "DepositStatus should not be empty") @@ -607,7 +607,7 @@ func TestGetAssetStatus(t *testing.T) { func TestGetAssetStatusAll(t *testing.T) { t.Parallel() - s, err := b.GetAssetStatusAll(t.Context()) + s, err := e.GetAssetStatusAll(t.Context()) require.NoError(t, err, "GetAssetStatusAll must not error") require.NoError(t, err, "GetAssetStatus must not error") assert.NotEmpty(t, s.Status, "Status should not be empty") @@ -615,42 +615,42 @@ func TestGetAssetStatusAll(t *testing.T) { func TestUpdateCurrencyStates(t *testing.T) { t.Parallel() - err := b.UpdateCurrencyStates(t.Context(), asset.Spot) + err := e.UpdateCurrencyStates(t.Context(), asset.Spot) require.NoError(t, err, "UpdateCurrencyStates must not error") } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot) require.NoError(t, err, "GetWithdrawalsHistory must not error") } func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetOrderInfo(t.Context(), "1234", testPair, asset.Spot) + _, err := e.GetOrderInfo(t.Context(), "1234", testPair, asset.Spot) require.NoError(t, err, "GetOrderInfo must not error") } func TestGetWithdrawalHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot) require.NoError(t, err, "GetWithdrawalsHistory must not error") } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/bithumb/bithumb_websocket.go b/exchanges/bithumb/bithumb_websocket.go index ec5834f27de..8ac317075a4 100644 --- a/exchanges/bithumb/bithumb_websocket.go +++ b/exchanges/bithumb/bithumb_websocket.go @@ -35,50 +35,50 @@ var defaultSubscriptions = subscription.List{ } // WsConnect initiates a websocket connection -func (b *Bithumb) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !b.Websocket.IsEnabled() || !b.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - dialer.HandshakeTimeout = b.Config.HTTPTimeout + dialer.HandshakeTimeout = e.Config.HTTPTimeout dialer.Proxy = http.ProxyFromEnvironment - err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { - return fmt.Errorf("%v - Unable to connect to Websocket. Error: %w", b.Name, err) + return fmt.Errorf("%v - Unable to connect to Websocket. Error: %w", e.Name, err) } - b.Websocket.Wg.Add(1) - go b.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() - b.setupOrderbookManager(ctx) + e.setupOrderbookManager(ctx) return nil } // wsReadData receives and passes on websocket messages for processing -func (b *Bithumb) wsReadData() { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { select { - case <-b.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: return default: - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := b.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (b *Bithumb) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { var resp WsResponse err := json.Unmarshal(respRaw, &resp) if err != nil { @@ -102,12 +102,12 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { return err } var lu time.Time - lu, err = time.ParseInLocation(tickerTimeLayout, tick.Date+tick.Time, b.location) + lu, err = time.ParseInLocation(tickerTimeLayout, tick.Date+tick.Time, e.location) if err != nil { return err } - b.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: b.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, AssetType: asset.Spot, Last: tick.PreviousClosePrice, Pair: tick.Symbol, @@ -120,7 +120,7 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { LastUpdated: lu, } case "transaction": - if !b.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } @@ -133,13 +133,13 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { toBuffer := make([]trade.Data, len(trades.List)) var lu time.Time for x := range trades.List { - lu, err = time.ParseInLocation(tradeTimeLayout, trades.List[x].ContractTime, b.location) + lu, err = time.ParseInLocation(tradeTimeLayout, trades.List[x].ContractTime, e.location) if err != nil { return err } toBuffer[x] = trade.Data{ - Exchange: b.Name, + Exchange: e.Name, AssetType: asset.Spot, CurrencyPair: trades.List[x].Symbol, Timestamp: lu, @@ -148,7 +148,7 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { } } - err = b.AddTradesToBuffer(toBuffer...) + err = e.AddTradesToBuffer(toBuffer...) if err != nil { return err } @@ -158,9 +158,9 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { if err != nil { return err } - init, err := b.UpdateLocalBuffer(&orderbooks) + init, err := e.UpdateLocalBuffer(&orderbooks) if err != nil && !init { - return fmt.Errorf("%v - UpdateLocalCache error: %s", b.Name, err) + return fmt.Errorf("%v - UpdateLocalCache error: %s", e.Name, err) } return nil default: @@ -171,23 +171,23 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error { } // generateSubscriptions generates the default subscription set -func (b *Bithumb) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *Bithumb) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(sprig.FuncMap()).Funcs(template.FuncMap{"subToReq": subToReq}).Parse(subTplText) } // Subscribe subscribes to a set of channels -func (b *Bithumb) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() var errs error for _, s := range subs { - err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(s.QualifiedChannel)) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(s.QualifiedChannel)) if err == nil { - err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, s) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) } if err != nil { errs = common.AppendError(errs, err) diff --git a/exchanges/bithumb/bithumb_websocket_test.go b/exchanges/bithumb/bithumb_websocket_test.go index 265bdda52d0..3cc801ce11c 100644 --- a/exchanges/bithumb/bithumb_websocket_test.go +++ b/exchanges/bithumb/bithumb_websocket_test.go @@ -28,7 +28,7 @@ func TestWsHandleData(t *testing.T) { pairs := currency.Pairs{currency.NewBTCUSDT()} - dummy := Bithumb{ + dummy := Exchange{ location: time.Local, Base: exchange.Base{ Name: "dummy", @@ -52,7 +52,7 @@ func TestWsHandleData(t *testing.T) { } dummy.setupOrderbookManager(t.Context()) - dummy.API.Endpoints = b.NewEndpoints() + dummy.API.Endpoints = e.NewEndpoints() welcomeMsg := []byte(`{"status":"0000","resmsg":"Connected Successfully"}`) err := dummy.wsHandleData(welcomeMsg) @@ -94,12 +94,12 @@ func TestSubToReq(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(Bithumb) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") p := currency.Pairs{currency.NewPairWithDelimiter("BTC", "KRW", "_"), currency.NewPairWithDelimiter("ETH", "KRW", "_")} - require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, false)) - require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, true)) - subs, err := b.generateSubscriptions() + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, false)) + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, true)) + subs, err := e.generateSubscriptions() require.NoError(t, err) exp := subscription.List{ {Asset: asset.Spot, Channel: subscription.AllTradesChannel, Pairs: p, QualifiedChannel: `{"type":"transaction","symbols":["BTC_KRW","ETH_KRW"]}`}, diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 1265152bd6c..5cdc3133371 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -35,26 +35,26 @@ import ( var errNotEnoughPairs = errors.New("at least one currency is required to fetch order history") // SetDefaults sets the basic defaults for Bithumb -func (b *Bithumb) SetDefaults() { - b.Name = "Bithumb" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Bithumb" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.UnderscoreDelimiter} configFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter} - err := b.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.location, err = time.LoadLocation("Asia/Seoul") + e.location, err = time.LoadLocation("Asia/Seoul") if err != nil { log.Errorf(log.ExchangeSys, "Bithumb unable to load time location: %s", err) } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, RESTCapabilities: protocol.Features{ @@ -116,14 +116,14 @@ func (b *Bithumb) SetDefaults() { }, Subscriptions: defaultSubscriptions.Clone(), } - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: apiURL, exchange.WebsocketSpot: wsEndpoint, }) @@ -131,44 +131,44 @@ func (b *Bithumb) SetDefaults() { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout } // Setup takes in the supplied exchange configuration details and sets params -func (b *Bithumb) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - ePoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + ePoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: wsEndpoint, RunningURL: ePoint, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, RateLimit: request.NewWeightedRateLimitByDuration(time.Second), @@ -176,8 +176,8 @@ func (b *Bithumb) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bithumb) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - currencies, err := b.GetTradablePairs(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + currencies, err := e.GetTradablePairs(ctx) if err != nil { return nil, err } @@ -196,25 +196,25 @@ func (b *Bithumb) FetchTradablePairs(ctx context.Context, _ asset.Item) (currenc // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bithumb) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = b.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error { - tickers, err := b.GetAllTickers(ctx) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + tickers, err := e.GetAllTickers(ctx) if err != nil { return err } - pairs, err := b.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { return err } @@ -226,7 +226,7 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error { return fmt.Errorf("enabled pair %s [%s] not found in returned ticker map %v", pairs[i], pairs, tickers) } - p, err := b.FormatExchangeCurrency(pairs[i], a) + p, err := e.FormatExchangeCurrency(pairs[i], a) if err != nil { return err } @@ -237,7 +237,7 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error { Open: t.OpeningPrice, Close: t.ClosingPrice, Pair: p, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -248,30 +248,30 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bithumb) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := b.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(b.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } curr := p.Base.String() - orderbookNew, err := b.GetOrderBook(ctx, curr) + orderbookNew, err := e.GetOrderBook(ctx, curr) if err != nil { return book, err } @@ -296,14 +296,14 @@ func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp if err != nil { return book, err } - return orderbook.Get(b.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bithumb exchange -func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - bal, err := b.GetAccountBalance(ctx, "ALL") + bal, err := e.GetAccountBalance(ctx, "ALL") if err != nil { return info, err } @@ -334,8 +334,8 @@ func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( AssetType: assetType, }) - info.Exchange = b.Name - creds, err := b.GetCredentials(ctx) + info.Exchange = e.Name + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -349,13 +349,13 @@ func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Bithumb) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bithumb) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - transactions, err := b.GetUserTransactions(ctx, 0, 0, 3, c, currency.EMPTYCODE) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + transactions, err := e.GetUserTransactions(ctx, 0, 0, 3, c, currency.EMPTYCODE) if err != nil { return nil, err } @@ -372,13 +372,13 @@ func (b *Bithumb) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = b.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetTransactionHistory(ctx, p.String()) + tradeData, err := e.GetTransactionHistory(ctx, p.String()) if err != nil { return nil, err } @@ -390,7 +390,7 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp return nil, err } resp[i] = trade.Data{ - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -400,7 +400,7 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -410,18 +410,18 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bithumb) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // TODO: Fill this out to support limit orders -func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -429,14 +429,14 @@ func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm var orderID string if s.Side.IsLong() { var result MarketBuy - result, err = b.MarketBuyOrder(ctx, fPair, s.Amount) + result, err = e.MarketBuyOrder(ctx, fPair, s.Amount) if err != nil { return nil, err } orderID = result.OrderID } else if s.Side.IsShort() { var result MarketSell - result, err = b.MarketSellOrder(ctx, fPair, s.Amount) + result, err = e.MarketSellOrder(ctx, fPair, s.Amount) if err != nil { return nil, err } @@ -447,27 +447,27 @@ func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bithumb) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bithumb) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - _, err := b.CancelTrade(ctx, o.Side.String(), o.OrderID, o.Pair.Base.String()) + _, err := e.CancelTrade(ctx, o.Side.String(), o.OrderID, o.Pair.Base.String()) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bithumb) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -477,13 +477,13 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order. } var allOrders []OrderData - currs, err := b.GetEnabledPairs(asset.Spot) + currs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return cancelAllOrdersResponse, err } for i := range currs { - orders, err := b.GetOrders(ctx, "", orderCancellation.Side.String(), 100, time.Time{}, currs[i].Base, currency.EMPTYCODE) + orders, err := e.GetOrders(ctx, "", orderCancellation.Side.String(), 100, time.Time{}, currs[i].Base, currency.EMPTYCODE) if err != nil { return cancelAllOrdersResponse, err } @@ -491,7 +491,7 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order. } for i := range allOrders { - _, err := b.CancelTrade(ctx, + _, err := e.CancelTrade(ctx, orderCancellation.Side.String(), allOrders[i].OrderID, orderCancellation.Pair.Base.String()) @@ -504,11 +504,11 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order. } // GetOrderInfo returns order information based on order ID -func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - orders, err := b.GetOrders(ctx, orderID, "", 0, time.Time{}, pair.Base, currency.EMPTYCODE) + orders, err := e.GetOrders(ctx, orderID, "", 0, time.Time{}, pair.Base, currency.EMPTYCODE) if err != nil { return nil, err } @@ -518,7 +518,7 @@ func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currenc } orderDetail := order.Detail{ Amount: orders.Data[i].Units, - Exchange: b.Name, + Exchange: e.Name, ExecutedAmount: orders.Data[i].Units - orders.Data[i].UnitsRemaining, OrderID: orders.Data[i].OrderID, Date: orders.Data[i].OrderDate.Time(), @@ -540,8 +540,8 @@ func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currenc } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bithumb) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - addr, err := b.GetWalletAddress(ctx, cryptocurrency) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + addr, err := e.GetWalletAddress(ctx, cryptocurrency) if err != nil { return nil, err } @@ -554,11 +554,11 @@ func (b *Bithumb) GetDepositAddress(ctx context.Context, cryptocurrency currency // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bithumb) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := b.WithdrawCrypto(ctx, + v, err := e.WithdrawCrypto(ctx, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Currency.String(), @@ -574,7 +574,7 @@ func (b *Bithumb) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -586,7 +586,7 @@ func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdr } bankDetails := strconv.FormatFloat(withdrawRequest.Fiat.Bank.BankCode, 'f', -1, 64) + "_" + withdrawRequest.Fiat.Bank.BankName - resp, err := b.RequestKRWWithdraw(ctx, + resp, err := e.RequestKRWWithdraw(ctx, bankDetails, withdrawRequest.Fiat.Bank.AccountNumber, int64(withdrawRequest.Amount)) @@ -603,24 +603,24 @@ func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdr } // WithdrawFiatFundsToInternationalBank is not supported as Bithumb only withdraws KRW to South Korean banks -func (b *Bithumb) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bithumb) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -630,7 +630,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ return nil, errNotEnoughPairs } - format, err := b.GetPairFormat(req.AssetType, false) + format, err := e.GetPairFormat(req.AssetType, false) if err != nil { return nil, err } @@ -638,7 +638,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ var orders []order.Detail for x := range req.Pairs { var resp Orders - resp, err = b.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE) + resp, err = e.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE) if err != nil { return nil, err } @@ -650,7 +650,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ orderDetail := order.Detail{ Amount: resp.Data[i].Units, - Exchange: b.Name, + Exchange: e.Name, ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining, OrderID: resp.Data[i].OrderID, Date: resp.Data[i].OrderDate.Time(), @@ -672,12 +672,12 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ orders = append(orders, orderDetail) } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -687,7 +687,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ return nil, errNotEnoughPairs } - format, err := b.GetPairFormat(req.AssetType, false) + format, err := e.GetPairFormat(req.AssetType, false) if err != nil { return nil, err } @@ -695,7 +695,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ var orders []order.Detail for x := range req.Pairs { var resp Orders - resp, err = b.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE) + resp, err = e.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE) if err != nil { return nil, err } @@ -709,7 +709,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ Amount: resp.Data[i].Units, ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining, RemainingAmount: resp.Data[i].UnitsRemaining, - Exchange: b.Name, + Exchange: e.Name, OrderID: resp.Data[i].OrderID, Date: resp.Data[i].OrderDate.Time(), Price: resp.Data[i].Price, @@ -729,29 +729,29 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ orders = append(orders, orderDetail) } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Bithumb) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (b *Bithumb) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { return in.Short() } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bithumb) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineRequest(pair, a, interval, start, end, true) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, true) if err != nil { return nil, err } - candles, err := b.GetCandleStick(ctx, req.RequestFormatted.String(), b.FormatExchangeKlineInterval(req.ExchangeInterval)) + candles, err := e.GetCandleStick(ctx, req.RequestFormatted.String(), e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } @@ -777,22 +777,22 @@ func (b *Bithumb) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bithumb) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (b *Bithumb) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error { - limits, err := b.FetchExchangeLimits(ctx) +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error { + limits, err := e.FetchExchangeLimits(ctx) if err != nil { return fmt.Errorf("cannot update exchange execution limits: %w", err) } - return b.LoadLimits(limits) + return e.LoadLimits(limits) } // UpdateCurrencyStates updates currency states for exchange -func (b *Bithumb) UpdateCurrencyStates(ctx context.Context, a asset.Item) error { - status, err := b.GetAssetStatusAll(ctx) +func (e *Exchange) UpdateCurrencyStates(ctx context.Context, a asset.Item) error { + status, err := e.GetAssetStatusAll(ctx) if err != nil { return err } @@ -804,27 +804,27 @@ func (b *Bithumb) UpdateCurrencyStates(ctx context.Context, a asset.Item) error Deposit: convert.BoolPtr(options.DepositStatus == 1), } } - return b.States.UpdateAll(a, payload) + return e.States.UpdateAll(a, payload) } // GetServerTime returns the current exchange server time. -func (b *Bithumb) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (b *Bithumb) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (b *Bithumb) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Bithumb) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/bithumb/bithumb_ws_orderbook.go b/exchanges/bithumb/bithumb_ws_orderbook.go index c806abdfd87..08cc5b5bf58 100644 --- a/exchanges/bithumb/bithumb_ws_orderbook.go +++ b/exchanges/bithumb/bithumb_ws_orderbook.go @@ -24,7 +24,7 @@ const ( maxWSOrderbookWorkers = 10 ) -func (b *Bithumb) processBooks(updates *WsOrderbooks) error { +func (e *Exchange) processBooks(updates *WsOrderbooks) error { bids := make([]orderbook.Level, 0, len(updates.List)) asks := make([]orderbook.Level, 0, len(updates.List)) for x := range updates.List { @@ -35,7 +35,7 @@ func (b *Bithumb) processBooks(updates *WsOrderbooks) error { } asks = append(asks, i) } - return b.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Pair: updates.List[0].Symbol, Asset: asset.Spot, Bids: bids, @@ -45,30 +45,30 @@ func (b *Bithumb) processBooks(updates *WsOrderbooks) error { } // UpdateLocalBuffer updates and returns the most recent iteration of the orderbook -func (b *Bithumb) UpdateLocalBuffer(wsdp *WsOrderbooks) (bool, error) { +func (e *Exchange) UpdateLocalBuffer(wsdp *WsOrderbooks) (bool, error) { if len(wsdp.List) < 1 { return false, errors.New("insufficient data to process") } - err := b.obm.stageWsUpdate(wsdp, wsdp.List[0].Symbol, asset.Spot) + err := e.obm.stageWsUpdate(wsdp, wsdp.List[0].Symbol, asset.Spot) if err != nil { - init, err2 := b.obm.checkIsInitialSync(wsdp.List[0].Symbol) + init, err2 := e.obm.checkIsInitialSync(wsdp.List[0].Symbol) if err2 != nil { return false, err2 } return init, err } - err = b.applyBufferUpdate(wsdp.List[0].Symbol) + err = e.applyBufferUpdate(wsdp.List[0].Symbol) if err != nil { - b.invalidateAndCleanupOrderbook(wsdp.List[0].Symbol) + e.invalidateAndCleanupOrderbook(wsdp.List[0].Symbol) } return false, err } // applyBufferUpdate applies the buffer to the orderbook or initiates a new // orderbook sync by the REST protocol which is off handed to go routine. -func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error { - fetching, needsFetching, err := b.obm.handleFetchingBook(pair) +func (e *Exchange) applyBufferUpdate(pair currency.Pair) error { + fetching, needsFetching, err := e.obm.handleFetchingBook(pair) if err != nil { return err } @@ -77,22 +77,22 @@ func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error { } if needsFetching { - if b.Verbose { - log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", b.Name) + if e.Verbose { + log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", e.Name) } - return b.obm.fetchBookViaREST(pair) + return e.obm.fetchBookViaREST(pair) } - recent, err := b.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) + recent, err := e.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) if err != nil { - log.Errorf(log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", b.Name, err) + log.Errorf(log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", e.Name, err) } if recent != nil { - err = b.obm.checkAndProcessOrderbookUpdate(b.processBooks, pair, recent) + err = e.obm.checkAndProcessOrderbookUpdate(e.processBooks, pair, recent) if err != nil { - log.Errorf(log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", b.Name, err) - err = b.obm.setNeedsFetchingBook(pair) + log.Errorf(log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", e.Name, err) + err = e.obm.setNeedsFetchingBook(pair) if err != nil { return err } @@ -104,24 +104,24 @@ func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error { // SynchroniseWebsocketOrderbook synchronises full orderbook for currency pair // asset -func (b *Bithumb) SynchroniseWebsocketOrderbook(ctx context.Context) { - b.Websocket.Wg.Add(1) +func (e *Exchange) SynchroniseWebsocketOrderbook(ctx context.Context) { + e.Websocket.Wg.Add(1) go func() { - defer b.Websocket.Wg.Done() + defer e.Websocket.Wg.Done() for { select { - case <-b.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: for { select { - case <-b.obm.jobs: + case <-e.obm.jobs: default: return } } - case j := <-b.obm.jobs: - err := b.processJob(ctx, j.Pair) + case j := <-e.obm.jobs: + err := e.processJob(ctx, j.Pair) if err != nil { - log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", b.Name, err) + log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", e.Name, err) } } } @@ -129,45 +129,45 @@ func (b *Bithumb) SynchroniseWebsocketOrderbook(ctx context.Context) { } // processJob fetches and processes orderbook updates -func (b *Bithumb) processJob(ctx context.Context, p currency.Pair) error { - err := b.SeedLocalCache(ctx, p) +func (e *Exchange) processJob(ctx context.Context, p currency.Pair) error { + err := e.SeedLocalCache(ctx, p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) } - err = b.obm.stopFetchingBook(p) + err = e.obm.stopFetchingBook(p) if err != nil { return err } // Immediately apply the buffer updates so we don't wait for a // new update to initiate this. - err = b.applyBufferUpdate(p) + err = e.applyBufferUpdate(p) if err != nil { - b.invalidateAndCleanupOrderbook(p) + e.invalidateAndCleanupOrderbook(p) return err } return nil } // invalidateAndCleanupOrderbook invalidates orderbook and cleans local cache -func (b *Bithumb) invalidateAndCleanupOrderbook(p currency.Pair) { - if err := b.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { - log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", b.Name, err) +func (e *Exchange) invalidateAndCleanupOrderbook(p currency.Pair) { + if err := e.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil { + log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", e.Name, err) } - if err := b.obm.cleanup(p); err != nil { - log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", b.Name, err) + if err := e.obm.cleanup(p); err != nil { + log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", e.Name, err) } } -func (b *Bithumb) setupOrderbookManager(ctx context.Context) { - if b.obm.state == nil { - b.obm.state = make(map[currency.Code]map[currency.Code]map[asset.Item]*update) - b.obm.jobs = make(chan job, maxWSOrderbookJobs) +func (e *Exchange) setupOrderbookManager(ctx context.Context) { + if e.obm.state == nil { + e.obm.state = make(map[currency.Code]map[currency.Code]map[asset.Item]*update) + e.obm.jobs = make(chan job, maxWSOrderbookJobs) } else { // Change state on reconnect for initial sync. - for _, m1 := range b.obm.state { + for _, m1 := range e.obm.state { for _, m2 := range m1 { for _, update := range m2 { update.initialSync = true @@ -180,7 +180,7 @@ func (b *Bithumb) setupOrderbookManager(ctx context.Context) { for range maxWSOrderbookWorkers { // 10 workers for synchronising book - b.SynchroniseWebsocketOrderbook(ctx) + e.SynchroniseWebsocketOrderbook(ctx) } } @@ -398,22 +398,22 @@ bufferEmpty: } // SeedLocalCache seeds depth data -func (b *Bithumb) SeedLocalCache(ctx context.Context, p currency.Pair) error { - ob, err := b.GetOrderBook(ctx, p.String()) +func (e *Exchange) SeedLocalCache(ctx context.Context, p currency.Pair) error { + ob, err := e.GetOrderBook(ctx, p.String()) if err != nil { return err } - return b.SeedLocalCacheWithBook(p, ob) + return e.SeedLocalCacheWithBook(p, ob) } // SeedLocalCacheWithBook seeds the local orderbook cache -func (b *Bithumb) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error { +func (e *Exchange) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error { ob := &orderbook.Book{ Pair: p, Asset: asset.Spot, - Exchange: b.Name, + Exchange: e.Name, LastUpdated: o.Data.Timestamp.Time(), - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(o.Data.Bids)), Asks: make(orderbook.Levels, len(o.Data.Asks)), } @@ -425,7 +425,7 @@ func (b *Bithumb) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error { ob.Asks[i].Price = o.Data.Asks[i].Price ob.Asks[i].Amount = o.Data.Asks[i].Quantity } - return b.Websocket.Orderbook.LoadSnapshot(ob) + return e.Websocket.Orderbook.LoadSnapshot(ob) } // setNeedsFetchingBook completes the book fetching initiation. diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index ddaea4309b2..7d7bdba0c11 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -18,8 +18,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/request" ) -// Bitmex is the overarching type across this package -type Bitmex struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bitmex +type Exchange struct { exchange.Base } @@ -116,104 +116,104 @@ const ( ) // GetAnnouncement returns the general announcements from Bitmex -func (b *Bitmex) GetAnnouncement(ctx context.Context) ([]Announcement, error) { +func (e *Exchange) GetAnnouncement(ctx context.Context) ([]Announcement, error) { var announcement []Announcement - return announcement, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAnnouncement, + return announcement, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAnnouncement, nil, &announcement) } // GetUrgentAnnouncement returns an urgent announcement for your account -func (b *Bitmex) GetUrgentAnnouncement(ctx context.Context) ([]Announcement, error) { +func (e *Exchange) GetUrgentAnnouncement(ctx context.Context) ([]Announcement, error) { var announcement []Announcement - return announcement, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return announcement, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointAnnouncementUrgent, nil, &announcement) } // GetAPIKeys returns the APIkeys from bitmex -func (b *Bitmex) GetAPIKeys(ctx context.Context) ([]APIKey, error) { +func (e *Exchange) GetAPIKeys(ctx context.Context) ([]APIKey, error) { var keys []APIKey - return keys, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return keys, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointAPIkeys, nil, &keys) } // RemoveAPIKey removes an Apikey from the bitmex trading engine -func (b *Bitmex) RemoveAPIKey(ctx context.Context, params APIKeyParams) (bool, error) { +func (e *Exchange) RemoveAPIKey(ctx context.Context, params APIKeyParams) (bool, error) { var keyDeleted bool - return keyDeleted, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + return keyDeleted, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointAPIkeys, ¶ms, &keyDeleted) } // DisableAPIKey disables an Apikey from the bitmex trading engine -func (b *Bitmex) DisableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { +func (e *Exchange) DisableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { var keyInfo APIKey - return keyInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return keyInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointDisableAPIkey, ¶ms, &keyInfo) } // EnableAPIKey enables an Apikey from the bitmex trading engine -func (b *Bitmex) EnableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { +func (e *Exchange) EnableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { var keyInfo APIKey - return keyInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return keyInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointEnableAPIkey, ¶ms, &keyInfo) } // GetTrollboxMessages returns messages from the bitmex trollbox -func (b *Bitmex) GetTrollboxMessages(ctx context.Context, params ChatGetParams) ([]Chat, error) { +func (e *Exchange) GetTrollboxMessages(ctx context.Context, params ChatGetParams) ([]Chat, error) { var messages []Chat - return messages, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollbox, ¶ms, &messages) + return messages, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollbox, ¶ms, &messages) } // SendTrollboxMessage sends a message to the bitmex trollbox -func (b *Bitmex) SendTrollboxMessage(ctx context.Context, params ChatSendParams) ([]Chat, error) { +func (e *Exchange) SendTrollboxMessage(ctx context.Context, params ChatSendParams) ([]Chat, error) { var messages []Chat - return messages, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return messages, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointTrollboxSend, ¶ms, &messages) } // GetTrollboxChannels the channels from the bitmex trollbox -func (b *Bitmex) GetTrollboxChannels(ctx context.Context) ([]ChatChannel, error) { +func (e *Exchange) GetTrollboxChannels(ctx context.Context) ([]ChatChannel, error) { var channels []ChatChannel - return channels, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxChannels, + return channels, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxChannels, nil, &channels) } // GetTrollboxConnectedUsers the channels from the bitmex trollbox -func (b *Bitmex) GetTrollboxConnectedUsers(ctx context.Context) (ConnectedUsers, error) { +func (e *Exchange) GetTrollboxConnectedUsers(ctx context.Context) (ConnectedUsers, error) { var users ConnectedUsers - return users, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxConnected, nil, &users) + return users, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxConnected, nil, &users) } // GetAccountExecutions returns all raw transactions, which includes order // opening and cancellation, and order status changes. It can be quite noisy. // More focused information is available at /execution/tradeHistory. -func (b *Bitmex) GetAccountExecutions(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { +func (e *Exchange) GetAccountExecutions(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { var executionList []Execution - return executionList, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return executionList, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointExecution, params, &executionList) @@ -221,17 +221,17 @@ func (b *Bitmex) GetAccountExecutions(ctx context.Context, params *GenericReques // GetAccountExecutionTradeHistory returns all balance-affecting executions. // This includes each trade, insurance charge, and settlement. -func (b *Bitmex) GetAccountExecutionTradeHistory(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { +func (e *Exchange) GetAccountExecutionTradeHistory(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { var tradeHistory []Execution - return tradeHistory, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return tradeHistory, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointExecutionTradeHistory, params, &tradeHistory) } // GetFullFundingHistory returns funding history -func (b *Bitmex) GetFullFundingHistory(ctx context.Context, symbol, count, filter, columns, start string, reverse bool, startTime, endTime time.Time) ([]Funding, error) { +func (e *Exchange) GetFullFundingHistory(ctx context.Context, symbol, count, filter, columns, start string, reverse bool, startTime, endTime time.Time) ([]Funding, error) { var fundingHistory []Funding params := url.Values{} if symbol != "" { @@ -260,59 +260,59 @@ func (b *Bitmex) GetFullFundingHistory(ctx context.Context, symbol, count, filte params.Set("startTime", startTime.Format(time.RFC3339)) params.Set("endTime", endTime.Format(time.RFC3339)) } - return fundingHistory, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointFundingHistory+params.Encode(), + return fundingHistory, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointFundingHistory+params.Encode(), nil, &fundingHistory) } // GetInstrument returns instrument data -func (b *Bitmex) GetInstrument(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { +func (e *Exchange) GetInstrument(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { var instruments []Instrument - return instruments, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointInstruments, + return instruments, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointInstruments, params, &instruments) } // GetInstruments returns instrument data -func (b *Bitmex) GetInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { +func (e *Exchange) GetInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { var instruments []Instrument - return instruments, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointInstruments, + return instruments, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointInstruments, params, &instruments) } // GetActiveInstruments returns active instruments -func (b *Bitmex) GetActiveInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { +func (e *Exchange) GetActiveInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { var activeInstruments []Instrument - return activeInstruments, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveInstruments, + return activeInstruments, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveInstruments, params, &activeInstruments) } // GetActiveAndIndexInstruments returns all active instruments and all indices -func (b *Bitmex) GetActiveAndIndexInstruments(ctx context.Context) ([]Instrument, error) { +func (e *Exchange) GetActiveAndIndexInstruments(ctx context.Context) ([]Instrument, error) { var activeAndIndices []Instrument return activeAndIndices, - b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveAndIndexInstruments, + e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveAndIndexInstruments, nil, &activeAndIndices) } // GetActiveIntervals returns funding history -func (b *Bitmex) GetActiveIntervals(ctx context.Context) (InstrumentInterval, error) { +func (e *Exchange) GetActiveIntervals(ctx context.Context) (InstrumentInterval, error) { var interval InstrumentInterval - return interval, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveIntervals, + return interval, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveIntervals, nil, &interval) } // GetCompositeIndex returns composite index -func (b *Bitmex) GetCompositeIndex(ctx context.Context, symbol, count, filter, columns, start, reverse string, startTime, endTime time.Time) ([]IndexComposite, error) { +func (e *Exchange) GetCompositeIndex(ctx context.Context, symbol, count, filter, columns, start, reverse string, startTime, endTime time.Time) ([]IndexComposite, error) { var compositeIndices []IndexComposite params := url.Values{} params.Set("symbol", symbol) @@ -338,82 +338,82 @@ func (b *Bitmex) GetCompositeIndex(ctx context.Context, symbol, count, filter, c params.Set("startTime", startTime.Format(time.RFC3339)) params.Set("endTime", endTime.Format(time.RFC3339)) } - return compositeIndices, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointCompositeIndex+"?"+params.Encode(), + return compositeIndices, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointCompositeIndex+"?"+params.Encode(), nil, &compositeIndices) } // GetIndices returns all price indices -func (b *Bitmex) GetIndices(ctx context.Context) ([]Instrument, error) { +func (e *Exchange) GetIndices(ctx context.Context) ([]Instrument, error) { var indices []Instrument - return indices, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, nil, &indices) + return indices, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, nil, &indices) } // GetInsuranceFundHistory returns insurance fund history -func (b *Bitmex) GetInsuranceFundHistory(ctx context.Context, params *GenericRequestParams) ([]Insurance, error) { +func (e *Exchange) GetInsuranceFundHistory(ctx context.Context, params *GenericRequestParams) ([]Insurance, error) { var history []Insurance - return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, params, &history) + return history, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, params, &history) } // GetLeaderboard returns leaderboard information -func (b *Bitmex) GetLeaderboard(ctx context.Context, params LeaderboardGetParams) ([]Leaderboard, error) { +func (e *Exchange) GetLeaderboard(ctx context.Context, params LeaderboardGetParams) ([]Leaderboard, error) { var leader []Leaderboard - return leader, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLeader, params, &leader) + return leader, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLeader, params, &leader) } // GetAliasOnLeaderboard returns your alias on the leaderboard -func (b *Bitmex) GetAliasOnLeaderboard(ctx context.Context) (Alias, error) { +func (e *Exchange) GetAliasOnLeaderboard(ctx context.Context) (Alias, error) { var alias Alias - return alias, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAlias, nil, &alias) + return alias, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAlias, nil, &alias) } // GetLiquidationOrders returns liquidation orders -func (b *Bitmex) GetLiquidationOrders(ctx context.Context, params *GenericRequestParams) ([]Liquidation, error) { +func (e *Exchange) GetLiquidationOrders(ctx context.Context, params *GenericRequestParams) ([]Liquidation, error) { var orders []Liquidation - return orders, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLiquidation, + return orders, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLiquidation, params, &orders) } // GetCurrentNotifications returns your current notifications -func (b *Bitmex) GetCurrentNotifications(ctx context.Context) ([]Notification, error) { +func (e *Exchange) GetCurrentNotifications(ctx context.Context) ([]Notification, error) { var notifications []Notification - return notifications, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return notifications, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointNotifications, nil, ¬ifications) } // GetOrders returns all the orders, open and closed -func (b *Bitmex) GetOrders(ctx context.Context, params *OrdersRequest) ([]Order, error) { +func (e *Exchange) GetOrders(ctx context.Context, params *OrdersRequest) ([]Order, error) { var orders []Order - return orders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return orders, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointOrder, params, &orders) } // AmendOrder amends the quantity or price of an open order -func (b *Bitmex) AmendOrder(ctx context.Context, params *OrderAmendParams) (Order, error) { +func (e *Exchange) AmendOrder(ctx context.Context, params *OrderAmendParams) (Order, error) { var order Order - return order, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, + return order, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointOrder, params, &order) } // CreateOrder creates a new order -func (b *Bitmex) CreateOrder(ctx context.Context, params *OrderNewParams) (Order, error) { +func (e *Exchange) CreateOrder(ctx context.Context, params *OrderNewParams) (Order, error) { var orderInfo Order - return orderInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return orderInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointOrder, params, &orderInfo) @@ -421,223 +421,223 @@ func (b *Bitmex) CreateOrder(ctx context.Context, params *OrderNewParams) (Order // CancelOrders cancels one or a batch of orders on the exchange and returns // a cancelled order list -func (b *Bitmex) CancelOrders(ctx context.Context, params *OrderCancelParams) ([]Order, error) { +func (e *Exchange) CancelOrders(ctx context.Context, params *OrderCancelParams) ([]Order, error) { var cancelledOrders []Order - return cancelledOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + return cancelledOrders, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointOrder, params, &cancelledOrders) } // CancelAllExistingOrders cancels all open orders on the exchange -func (b *Bitmex) CancelAllExistingOrders(ctx context.Context, params OrderCancelAllParams) ([]Order, error) { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context, params OrderCancelAllParams) ([]Order, error) { var cancelledOrders []Order - return cancelledOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + return cancelledOrders, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointCancelAllOrders, params, &cancelledOrders) } // AmendBulkOrders amends multiple orders for the same symbol -func (b *Bitmex) AmendBulkOrders(ctx context.Context, params OrderAmendBulkParams) ([]Order, error) { +func (e *Exchange) AmendBulkOrders(ctx context.Context, params OrderAmendBulkParams) ([]Order, error) { var amendedOrders []Order - return amendedOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, + return amendedOrders, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointBulk, params, &amendedOrders) } // CreateBulkOrders creates multiple orders for the same symbol -func (b *Bitmex) CreateBulkOrders(ctx context.Context, params OrderNewBulkParams) ([]Order, error) { +func (e *Exchange) CreateBulkOrders(ctx context.Context, params OrderNewBulkParams) ([]Order, error) { var orders []Order - return orders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return orders, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointBulk, params, &orders) } // CancelAllOrdersAfterTime closes all positions after a certain time period -func (b *Bitmex) CancelAllOrdersAfterTime(ctx context.Context, params OrderCancelAllAfterParams) ([]Order, error) { +func (e *Exchange) CancelAllOrdersAfterTime(ctx context.Context, params OrderCancelAllAfterParams) ([]Order, error) { var cancelledOrder []Order - return cancelledOrder, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return cancelledOrder, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointCancelOrderAfter, params, &cancelledOrder) } // ClosePosition closes a position WARNING deprecated use /order endpoint -func (b *Bitmex) ClosePosition(ctx context.Context, params OrderClosePositionParams) ([]Order, error) { +func (e *Exchange) ClosePosition(ctx context.Context, params OrderClosePositionParams) ([]Order, error) { var closedPositions []Order - return closedPositions, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return closedPositions, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointOrder, params, &closedPositions) } // GetOrderbook returns layer two orderbook data -func (b *Bitmex) GetOrderbook(ctx context.Context, params OrderBookGetL2Params) ([]OrderBookL2, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, params OrderBookGetL2Params) ([]OrderBookL2, error) { var orderBooks []OrderBookL2 - return orderBooks, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointOrderbookL2, + return orderBooks, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointOrderbookL2, params, &orderBooks) } // GetPositions returns positions -func (b *Bitmex) GetPositions(ctx context.Context, params PositionGetParams) ([]Position, error) { +func (e *Exchange) GetPositions(ctx context.Context, params PositionGetParams) ([]Position, error) { var positions []Position - return positions, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return positions, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointPosition, params, &positions) } // IsolatePosition enables isolated margin or cross margin per-position -func (b *Bitmex) IsolatePosition(ctx context.Context, params PositionIsolateMarginParams) (Position, error) { +func (e *Exchange) IsolatePosition(ctx context.Context, params PositionIsolateMarginParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return position, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointIsolatePosition, params, &position) } // LeveragePosition chooses leverage for a position -func (b *Bitmex) LeveragePosition(ctx context.Context, params PositionUpdateLeverageParams) (Position, error) { +func (e *Exchange) LeveragePosition(ctx context.Context, params PositionUpdateLeverageParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return position, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointLeveragePosition, params, &position) } // UpdateRiskLimit updates risk limit on a position -func (b *Bitmex) UpdateRiskLimit(ctx context.Context, params PositionUpdateRiskLimitParams) (Position, error) { +func (e *Exchange) UpdateRiskLimit(ctx context.Context, params PositionUpdateRiskLimitParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return position, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointAdjustRiskLimit, params, &position) } // TransferMargin transfers equity in or out of a position -func (b *Bitmex) TransferMargin(ctx context.Context, params PositionTransferIsolatedMarginParams) (Position, error) { +func (e *Exchange) TransferMargin(ctx context.Context, params PositionTransferIsolatedMarginParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return position, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointTransferMargin, params, &position) } // GetQuotes returns quotations -func (b *Bitmex) GetQuotes(ctx context.Context, params *GenericRequestParams) ([]Quote, error) { +func (e *Exchange) GetQuotes(ctx context.Context, params *GenericRequestParams) ([]Quote, error) { var quotations []Quote - return quotations, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuote, + return quotations, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuote, params, "ations) } // GetQuotesByBuckets returns previous quotes in time buckets -func (b *Bitmex) GetQuotesByBuckets(ctx context.Context, params *QuoteGetBucketedParams) ([]Quote, error) { +func (e *Exchange) GetQuotesByBuckets(ctx context.Context, params *QuoteGetBucketedParams) ([]Quote, error) { var quotations []Quote - return quotations, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuoteBucketed, + return quotations, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuoteBucketed, params, "ations) } // GetSettlementHistory returns settlement history -func (b *Bitmex) GetSettlementHistory(ctx context.Context, params *GenericRequestParams) ([]Settlement, error) { +func (e *Exchange) GetSettlementHistory(ctx context.Context, params *GenericRequestParams) ([]Settlement, error) { var history []Settlement - return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointSettlement, + return history, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointSettlement, params, &history) } // GetStats returns exchange wide per series turnover and volume statistics -func (b *Bitmex) GetStats(ctx context.Context) ([]Stats, error) { +func (e *Exchange) GetStats(ctx context.Context) ([]Stats, error) { var stats []Stats - return stats, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStats, nil, &stats) + return stats, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStats, nil, &stats) } // GetStatsHistorical historic stats -func (b *Bitmex) GetStatsHistorical(ctx context.Context) ([]StatsHistory, error) { +func (e *Exchange) GetStatsHistorical(ctx context.Context) ([]StatsHistory, error) { var history []StatsHistory - return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsHistory, nil, &history) + return history, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsHistory, nil, &history) } // GetStatSummary returns the stats summary in USD terms -func (b *Bitmex) GetStatSummary(ctx context.Context) ([]StatsUSD, error) { +func (e *Exchange) GetStatSummary(ctx context.Context) ([]StatsUSD, error) { var summary []StatsUSD - return summary, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsSummary, nil, &summary) + return summary, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsSummary, nil, &summary) } // GetTrade returns executed trades on the desk -func (b *Bitmex) GetTrade(ctx context.Context, params *GenericRequestParams) ([]Trade, error) { +func (e *Exchange) GetTrade(ctx context.Context, params *GenericRequestParams) ([]Trade, error) { var trade []Trade - return trade, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrade, params, &trade) + return trade, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrade, params, &trade) } // GetPreviousTrades previous trade history in time buckets -func (b *Bitmex) GetPreviousTrades(ctx context.Context, params *TradeGetBucketedParams) ([]Trade, error) { +func (e *Exchange) GetPreviousTrades(ctx context.Context, params *TradeGetBucketedParams) ([]Trade, error) { var trade []Trade - return trade, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTradeBucketed, + return trade, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTradeBucketed, params, &trade) } // GetUserInfo returns your user information -func (b *Bitmex) GetUserInfo(ctx context.Context) (User, error) { +func (e *Exchange) GetUserInfo(ctx context.Context) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return userInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUser, nil, &userInfo) } // UpdateUserInfo updates user information -func (b *Bitmex) UpdateUserInfo(ctx context.Context, params *UserUpdateParams) (User, error) { +func (e *Exchange) UpdateUserInfo(ctx context.Context, params *UserUpdateParams) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, + return userInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointUser, params, &userInfo) } // GetAffiliateStatus returns your affiliate status -func (b *Bitmex) GetAffiliateStatus(ctx context.Context) (AffiliateStatus, error) { +func (e *Exchange) GetAffiliateStatus(ctx context.Context) (AffiliateStatus, error) { var status AffiliateStatus - return status, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return status, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserAffiliate, nil, &status) } // CancelWithdraw cancels a current withdrawal -func (b *Bitmex) CancelWithdraw(ctx context.Context, token string) (TransactionInfo, error) { +func (e *Exchange) CancelWithdraw(ctx context.Context, token string) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserCancelWithdraw, UserTokenParams{Token: token}, &info) @@ -645,140 +645,140 @@ func (b *Bitmex) CancelWithdraw(ctx context.Context, token string) (TransactionI // CheckReferalCode checks a code, will return a percentage eg 0.1 for 10% or // if err a 404 -func (b *Bitmex) CheckReferalCode(ctx context.Context, referralCode string) (float64, error) { +func (e *Exchange) CheckReferalCode(ctx context.Context, referralCode string) (float64, error) { var percentage float64 - return percentage, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointUserCheckReferralCode, + return percentage, e.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointUserCheckReferralCode, UserCheckReferralCodeParams{ReferralCode: referralCode}, &percentage) } // GetUserCommision returns your account's commission status. -func (b *Bitmex) GetUserCommision(ctx context.Context) (UserCommission, error) { +func (e *Exchange) GetUserCommision(ctx context.Context) (UserCommission, error) { var commissionInfo UserCommission - return commissionInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return commissionInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserCommision, nil, &commissionInfo) } // ConfirmEmail confirms email address with a token -func (b *Bitmex) ConfirmEmail(ctx context.Context, token string) (ConfirmEmail, error) { +func (e *Exchange) ConfirmEmail(ctx context.Context, token string) (ConfirmEmail, error) { var confirmation ConfirmEmail - return confirmation, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return confirmation, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserConfirmEmail, UserTokenParams{Token: token}, &confirmation) } // ConfirmTwoFactorAuth confirms 2FA for this account. -func (b *Bitmex) ConfirmTwoFactorAuth(ctx context.Context, token, typ string) (bool, error) { +func (e *Exchange) ConfirmTwoFactorAuth(ctx context.Context, token, typ string) (bool, error) { var working bool - return working, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return working, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserConfirmTFA, UserConfirmTFAParams{Token: token, Type: typ}, &working) } // ConfirmWithdrawal confirms a withdrawal -func (b *Bitmex) ConfirmWithdrawal(ctx context.Context, token string) (TransactionInfo, error) { +func (e *Exchange) ConfirmWithdrawal(ctx context.Context, token string) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserCancelWithdraw, UserTokenParams{Token: token}, &info) } // GetCryptoDepositAddress returns a deposit address for a cryptocurrency -func (b *Bitmex) GetCryptoDepositAddress(ctx context.Context, cryptoCurrency string) (string, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, cryptoCurrency string) (string, error) { var address string if !strings.EqualFold(cryptoCurrency, currency.XBT.String()) { return "", fmt.Errorf("%v %w only bitcoin", cryptoCurrency, currency.ErrCurrencyNotSupported) } - return address, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return address, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserDepositAddress, UserCurrencyParams{Currency: "XBt"}, &address) } // DisableTFA dsiables 2 factor authentication for your account -func (b *Bitmex) DisableTFA(ctx context.Context, token, typ string) (bool, error) { +func (e *Exchange) DisableTFA(ctx context.Context, token, typ string) (bool, error) { var disabled bool - return disabled, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return disabled, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserDisableTFA, UserConfirmTFAParams{Token: token, Type: typ}, &disabled) } // UserLogOut logs you out of BitMEX -func (b *Bitmex) UserLogOut(ctx context.Context) error { - return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, +func (e *Exchange) UserLogOut(ctx context.Context) error { + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserLogout, nil, nil) } // UserLogOutAll logs you out of all systems for BitMEX -func (b *Bitmex) UserLogOutAll(ctx context.Context) (int64, error) { +func (e *Exchange) UserLogOutAll(ctx context.Context) (int64, error) { var status int64 - return status, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return status, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserLogoutAll, nil, &status) } // GetUserMargin returns user margin information -func (b *Bitmex) GetUserMargin(ctx context.Context, currency string) (UserMargin, error) { +func (e *Exchange) GetUserMargin(ctx context.Context, currency string) (UserMargin, error) { var info UserMargin - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMargin, UserCurrencyParams{Currency: currency}, &info) } // GetAllUserMargin returns user margin information -func (b *Bitmex) GetAllUserMargin(ctx context.Context) ([]UserMargin, error) { +func (e *Exchange) GetAllUserMargin(ctx context.Context) ([]UserMargin, error) { var info []UserMargin - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMargin, UserCurrencyParams{Currency: "all"}, &info) } // GetMinimumWithdrawalFee returns minimum withdrawal fee information -func (b *Bitmex) GetMinimumWithdrawalFee(ctx context.Context, currency string) (MinWithdrawalFee, error) { +func (e *Exchange) GetMinimumWithdrawalFee(ctx context.Context, currency string) (MinWithdrawalFee, error) { var fee MinWithdrawalFee - return fee, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return fee, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMinWithdrawalFee, UserCurrencyParams{Currency: currency}, &fee) } // GetUserPreferences returns user preferences -func (b *Bitmex) GetUserPreferences(ctx context.Context, params UserPreferencesParams) (User, error) { +func (e *Exchange) GetUserPreferences(ctx context.Context, params UserPreferencesParams) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return userInfo, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserPreferences, params, &userInfo) } // EnableTFA enables 2 factor authentication -func (b *Bitmex) EnableTFA(ctx context.Context, typ string) (bool, error) { +func (e *Exchange) EnableTFA(ctx context.Context, typ string) (bool, error) { var enabled bool - return enabled, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return enabled, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserRequestTFA, UserConfirmTFAParams{Type: typ}, &enabled) @@ -787,20 +787,20 @@ func (b *Bitmex) EnableTFA(ctx context.Context, typ string) (bool, error) { // UserRequestWithdrawal This will send a confirmation email to the email // address on record, unless requested via an API Key with the withdraw // permission. -func (b *Bitmex) UserRequestWithdrawal(ctx context.Context, params UserRequestWithdrawalParams) (TransactionInfo, error) { +func (e *Exchange) UserRequestWithdrawal(ctx context.Context, params UserRequestWithdrawalParams) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserRequestWithdraw, params, &info) } // GetWalletInfo returns user wallet information -func (b *Bitmex) GetWalletInfo(ctx context.Context, currency string) (WalletInfo, error) { +func (e *Exchange) GetWalletInfo(ctx context.Context, currency string) (WalletInfo, error) { var info WalletInfo - if err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWallet, UserCurrencyParams{Currency: currency}, &info); err != nil { @@ -818,29 +818,29 @@ func (b *Bitmex) GetWalletInfo(ctx context.Context, currency string) (WalletInfo } // GetWalletHistory returns user wallet history transaction data -func (b *Bitmex) GetWalletHistory(ctx context.Context, currency string) ([]TransactionInfo, error) { +func (e *Exchange) GetWalletHistory(ctx context.Context, currency string) ([]TransactionInfo, error) { var info []TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletHistory, UserCurrencyParams{Currency: currency}, &info) } // GetWalletSummary returns user wallet summary -func (b *Bitmex) GetWalletSummary(ctx context.Context, currency string) ([]TransactionInfo, error) { +func (e *Exchange) GetWalletSummary(ctx context.Context, currency string) ([]TransactionInfo, error) { var info []TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletSummary, UserCurrencyParams{Currency: currency}, &info) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bitmex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, params Parameter, result any) error { +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, params Parameter, result any) error { var respCheck any - endpoint, err := b.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -856,28 +856,28 @@ func (b *Bitmex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri Method: http.MethodGet, Path: path, Result: &respCheck, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - err = b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) if err != nil { return err } - return b.CaptureError(respCheck, result) + return e.CaptureError(respCheck, result) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to bitmex -func (b *Bitmex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, verb, path string, params Parameter, result any) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, verb, path string, params Parameter, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := b.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -916,21 +916,21 @@ func (b *Bitmex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U Headers: headers, Body: strings.NewReader(payload), Result: &respCheck, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - err = b.SendPayload(ctx, request.Auth, newRequest, request.AuthenticatedRequest) + err = e.SendPayload(ctx, request.Auth, newRequest, request.AuthenticatedRequest) if err != nil { return err } - return b.CaptureError(respCheck, result) + return e.CaptureError(respCheck, result) } // CaptureError little hack that captures an error -func (b *Bitmex) CaptureError(resp, reType any) error { +func (e *Exchange) CaptureError(resp, reType any) error { var Error RequestError marshalled, err := json.Marshal(resp) @@ -949,7 +949,7 @@ func (b *Bitmex) CaptureError(resp, reType any) error { } // GetFee returns an estimate of fee based on type of transaction -func (b *Bitmex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 var err error switch feeBuilder.FeeType { diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index 5a3e053fa97..9cad9cb577d 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -36,18 +36,18 @@ const ( canManipulateRealOrders = false ) -var b *Bitmex +var e *Exchange func TestMain(m *testing.M) { - b = new(Bitmex) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bitmex Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.API.AuthenticatedWebsocketSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -55,60 +55,60 @@ func TestMain(m *testing.M) { func TestGetFullFundingHistory(t *testing.T) { t.Parallel() - _, err := b.GetFullFundingHistory(t.Context(), + _, err := e.GetFullFundingHistory(t.Context(), "", "", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) require.NoError(t, err) - _, err = b.GetFullFundingHistory(t.Context(), + _, err = e.GetFullFundingHistory(t.Context(), "LTCUSD", "1", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) require.NoError(t, err) } func TestGetUrgentAnnouncement(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.GetUrgentAnnouncement(t.Context()) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetUrgentAnnouncement(t.Context()) require.Error(t, err) } func TestGetAPIKeys(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.GetAPIKeys(t.Context()) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetAPIKeys(t.Context()) require.Error(t, err) } func TestRemoveAPIKey(t *testing.T) { t.Parallel() - _, err := b.RemoveAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) + _, err := e.RemoveAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) require.Error(t, err) } func TestDisableAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.DisableAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.DisableAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) require.Error(t, err) } func TestEnableAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.EnableAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.EnableAPIKey(t.Context(), APIKeyParams{APIKeyID: "1337"}) require.Error(t, err) } func TestGetTrollboxMessages(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxMessages(t.Context(), ChatGetParams{Count: 1}) + _, err := e.GetTrollboxMessages(t.Context(), ChatGetParams{Count: 1}) require.NoError(t, err) } func TestSendTrollboxMessage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.SendTrollboxMessage(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.SendTrollboxMessage(t.Context(), ChatSendParams{ ChannelID: 1337, Message: "Hello,World!", @@ -118,41 +118,41 @@ func TestSendTrollboxMessage(t *testing.T) { func TestGetTrollboxChannels(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxChannels(t.Context()) + _, err := e.GetTrollboxChannels(t.Context()) require.NoError(t, err) } func TestGetTrollboxConnectedUsers(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxConnectedUsers(t.Context()) + _, err := e.GetTrollboxConnectedUsers(t.Context()) require.NoError(t, err) } func TestGetAccountExecutions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.GetAccountExecutions(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetAccountExecutions(t.Context(), &GenericRequestParams{}) require.Error(t, err) } func TestGetAccountExecutionTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.GetAccountExecutionTradeHistory(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetAccountExecutionTradeHistory(t.Context(), &GenericRequestParams{}) require.Error(t, err) } func TestGetFundingHistory(t *testing.T) { t.Parallel() - _, err := b.GetAccountFundingHistory(t.Context()) + _, err := e.GetAccountFundingHistory(t.Context()) require.Error(t, err) } func TestGetInstruments(t *testing.T) { t.Parallel() - _, err := b.GetInstruments(t.Context(), + _, err := e.GetInstruments(t.Context(), &GenericRequestParams{ Symbol: "XRPUSD", }) @@ -161,39 +161,39 @@ func TestGetInstruments(t *testing.T) { func TestGetActiveInstruments(t *testing.T) { t.Parallel() - _, err := b.GetActiveInstruments(t.Context(), + _, err := e.GetActiveInstruments(t.Context(), &GenericRequestParams{}) require.NoError(t, err) } func TestGetActiveAndIndexInstruments(t *testing.T) { t.Parallel() - _, err := b.GetActiveAndIndexInstruments(t.Context()) + _, err := e.GetActiveAndIndexInstruments(t.Context()) require.NoError(t, err) } func TestGetActiveIntervals(t *testing.T) { t.Parallel() - _, err := b.GetActiveIntervals(t.Context()) + _, err := e.GetActiveIntervals(t.Context()) require.NoError(t, err) } func TestGetCompositeIndex(t *testing.T) { t.Parallel() - _, err := b.GetCompositeIndex(t.Context(), + _, err := e.GetCompositeIndex(t.Context(), ".XBT", "", "", "", "", "", time.Time{}, time.Time{}) require.NoError(t, err) } func TestGetIndices(t *testing.T) { t.Parallel() - _, err := b.GetIndices(t.Context()) + _, err := e.GetIndices(t.Context()) require.NoError(t, err) } func TestGetInsuranceFundHistory(t *testing.T) { t.Parallel() - _, err := b.GetInsuranceFundHistory(t.Context(), + _, err := e.GetInsuranceFundHistory(t.Context(), &GenericRequestParams{}) require.NoError(t, err) } @@ -201,8 +201,8 @@ func TestGetInsuranceFundHistory(t *testing.T) { func TestGetLeaderboard(t *testing.T) { t.Parallel() - b := new(Bitmex) //nolint:govet // Intentional shadow - err := testexch.Setup(b) + e := new(Exchange) //nolint:govet // Intentional shadow + err := testexch.Setup(e) require.NoError(t, err, "Setup must not error") server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -225,7 +225,7 @@ func TestGetLeaderboard(t *testing.T) { })) defer server.Close() - err = b.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), server.URL+"/api/v1") + err = e.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), server.URL+"/api/v1") require.NoError(t, err, "SetRunningURL must not error") expectedLeaderboard := []Leaderboard{ @@ -233,42 +233,42 @@ func TestGetLeaderboard(t *testing.T) { {Name: "CryptoKing", Profit: 9876.54}, } - result, err := b.GetLeaderboard(t.Context(), LeaderboardGetParams{}) + result, err := e.GetLeaderboard(t.Context(), LeaderboardGetParams{}) require.NoError(t, err, "GetLeaderboard must not error") assert.Equal(t, expectedLeaderboard, result, "GetLeaderboard result should be correct") } func TestGetAliasOnLeaderboard(t *testing.T) { t.Parallel() - _, err := b.GetAliasOnLeaderboard(t.Context()) + _, err := e.GetAliasOnLeaderboard(t.Context()) require.Error(t, err) } func TestGetLiquidationOrders(t *testing.T) { t.Parallel() - _, err := b.GetLiquidationOrders(t.Context(), + _, err := e.GetLiquidationOrders(t.Context(), &GenericRequestParams{}) require.NoError(t, err) } func TestGetCurrentNotifications(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.GetCurrentNotifications(t.Context()) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.GetCurrentNotifications(t.Context()) require.Error(t, err) } func TestAmendOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.AmendOrder(t.Context(), &OrderAmendParams{}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.AmendOrder(t.Context(), &OrderAmendParams{}) require.Error(t, err) } func TestCreateOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.CreateOrder(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.CreateOrder(t.Context(), &OrderNewParams{ Symbol: "XBTM15", Price: 219.0, @@ -280,113 +280,113 @@ func TestCreateOrder(t *testing.T) { func TestCancelOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.CancelOrders(t.Context(), &OrderCancelParams{}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.CancelOrders(t.Context(), &OrderCancelParams{}) require.Error(t, err) } func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.CancelAllExistingOrders(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.CancelAllExistingOrders(t.Context(), OrderCancelAllParams{}) require.Error(t, err) } func TestAmendBulkOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.AmendBulkOrders(t.Context(), OrderAmendBulkParams{}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.AmendBulkOrders(t.Context(), OrderAmendBulkParams{}) require.Error(t, err) } func TestCreateBulkOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.CreateBulkOrders(t.Context(), OrderNewBulkParams{}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.CreateBulkOrders(t.Context(), OrderNewBulkParams{}) require.Error(t, err) } func TestCancelAllOrdersAfterTime(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.CancelAllOrdersAfterTime(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.CancelAllOrdersAfterTime(t.Context(), OrderCancelAllAfterParams{}) require.Error(t, err) } func TestClosePosition(t *testing.T) { t.Parallel() - _, err := b.ClosePosition(t.Context(), OrderClosePositionParams{}) + _, err := e.ClosePosition(t.Context(), OrderClosePositionParams{}) require.Error(t, err) } func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(t.Context(), + _, err := e.GetOrderbook(t.Context(), OrderBookGetL2Params{Symbol: "XBT"}) require.NoError(t, err) } func TestGetPositions(t *testing.T) { t.Parallel() - _, err := b.GetPositions(t.Context(), PositionGetParams{}) + _, err := e.GetPositions(t.Context(), PositionGetParams{}) require.Error(t, err) } func TestIsolatePosition(t *testing.T) { t.Parallel() - _, err := b.IsolatePosition(t.Context(), + _, err := e.IsolatePosition(t.Context(), PositionIsolateMarginParams{Symbol: "XBT"}) require.Error(t, err) } func TestLeveragePosition(t *testing.T) { t.Parallel() - _, err := b.LeveragePosition(t.Context(), + _, err := e.LeveragePosition(t.Context(), PositionUpdateLeverageParams{}) require.Error(t, err) } func TestUpdateRiskLimit(t *testing.T) { t.Parallel() - _, err := b.UpdateRiskLimit(t.Context(), + _, err := e.UpdateRiskLimit(t.Context(), PositionUpdateRiskLimitParams{}) require.Error(t, err) } func TestTransferMargin(t *testing.T) { t.Parallel() - _, err := b.TransferMargin(t.Context(), + _, err := e.TransferMargin(t.Context(), PositionTransferIsolatedMarginParams{}) require.Error(t, err) } func TestGetQuotesByBuckets(t *testing.T) { t.Parallel() - _, err := b.GetQuotesByBuckets(t.Context(), + _, err := e.GetQuotesByBuckets(t.Context(), &QuoteGetBucketedParams{}) require.Error(t, err) } func TestGetSettlementHistory(t *testing.T) { t.Parallel() - _, err := b.GetSettlementHistory(t.Context(), + _, err := e.GetSettlementHistory(t.Context(), &GenericRequestParams{}) require.NoError(t, err) } func TestGetStats(t *testing.T) { t.Parallel() - _, err := b.GetStats(t.Context()) + _, err := e.GetStats(t.Context()) require.NoError(t, err) } func TestGetStatsHistorical(t *testing.T) { t.Parallel() - b := new(Bitmex) //nolint:govet // Intentional shadow - err := testexch.Setup(b) + e := new(Exchange) //nolint:govet // Intentional shadow + err := testexch.Setup(e) require.NoError(t, err, "Setup must not error") server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -413,7 +413,7 @@ func TestGetStatsHistorical(t *testing.T) { })) defer server.Close() - err = b.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), server.URL+"/api/v1") + err = e.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), server.URL+"/api/v1") require.NoError(t, err, "SetRunningURL must not error") expectedStats := []StatsHistory{ @@ -421,20 +421,20 @@ func TestGetStatsHistorical(t *testing.T) { {Currency: "XBt", Date: time.Date(2023, 10, 25, 10, 35, 42, 123000000, time.UTC), RootSymbol: "XBT", Turnover: 4500000000, Volume: 90000}, } - result, err := b.GetStatsHistorical(t.Context()) + result, err := e.GetStatsHistorical(t.Context()) require.NoError(t, err, "GetStatsHistorical must not error") assert.Equal(t, expectedStats, result, "GetStatsHistorical result should be correct") } func TestGetStatSummary(t *testing.T) { t.Parallel() - _, err := b.GetStatSummary(t.Context()) + _, err := e.GetStatSummary(t.Context()) require.NoError(t, err) } func TestGetTrade(t *testing.T) { t.Parallel() - _, err := b.GetTrade(t.Context(), + _, err := e.GetTrade(t.Context(), &GenericRequestParams{ Symbol: "XBT", Reverse: false, @@ -445,7 +445,7 @@ func TestGetTrade(t *testing.T) { func TestGetPreviousTrades(t *testing.T) { t.Parallel() - _, err := b.GetPreviousTrades(t.Context(), + _, err := e.GetPreviousTrades(t.Context(), &TradeGetBucketedParams{ Symbol: "XBTBTC", Start: time.Now().Add(-time.Hour).Unix(), @@ -467,9 +467,9 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err) - if !sharedtestvalues.AreAPICredentialsSet(b) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType) } else { assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType) @@ -480,52 +480,52 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() // CryptocurrencyTradeFee Basic - _, err := b.GetFee(feeBuilder) + _, err := e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee High quantity feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - _, err = b.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) } @@ -533,7 +533,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.WithdrawCryptoWithEmailText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() assert.Equal(t, expectedResult, withdrawPermissions) } @@ -545,8 +545,8 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(b) { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -562,8 +562,8 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(b) { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -575,10 +575,10 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.XBT, Quote: currency.USD, @@ -590,8 +590,8 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Futures, } - response, err := b.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(b) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) assert.Equal(t, order.New, response.Status) } else { @@ -601,7 +601,7 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -611,8 +611,8 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Futures, } - err := b.CancelOrder(t.Context(), orderCancellation) - if sharedtestvalues.AreAPICredentialsSet(b) { + err := e.CancelOrder(t.Context(), orderCancellation) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -621,7 +621,7 @@ func TestCancelExchangeOrder(t *testing.T) { func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -631,8 +631,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Futures, } - resp, err := b.CancelAllOrders(t.Context(), orderCancellation) - if sharedtestvalues.AreAPICredentialsSet(b) { + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) require.Empty(t, resp.Status, "CancelAllOrders must not fail to cancel orders") } else { @@ -642,35 +642,35 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(b) { - _, err := b.UpdateAccountInfo(t.Context(), asset.Spot) + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) require.NoError(t, err) - _, err = b.UpdateAccountInfo(t.Context(), asset.Futures) + _, err = e.UpdateAccountInfo(t.Context(), asset.Futures) require.NoError(t, err) } else { - _, err := b.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) require.Error(t, err) - _, err = b.UpdateAccountInfo(t.Context(), asset.Futures) + _, err = e.UpdateAccountInfo(t.Context(), asset.Futures) require.Error(t, err) } } func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) - _, err := b.ModifyOrder(t.Context(), + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder(t.Context(), &order.Modify{OrderID: "1337", AssetType: asset.Futures}) require.Error(t, err) } func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: b.Name, + Exchange: e.Name, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, }, @@ -680,8 +680,8 @@ func TestWithdraw(t *testing.T) { OneTimePassword: 696969, } - _, err := b.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if sharedtestvalues.AreAPICredentialsSet(b) { + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.Error(t, err) @@ -690,30 +690,30 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) require.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) require.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestGetDepositAddress(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(b) { - _, err := b.GetDepositAddress(t.Context(), currency.BTC, "", "") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") require.NoError(t, err) } else { - _, err := b.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") require.Error(t, err) } } @@ -721,19 +721,19 @@ func TestGetDepositAddress(t *testing.T) { // TestWsAuth dials websocket, sends login request. func TestWsAuth(t *testing.T) { t.Parallel() - if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(b) { + if !e.Websocket.IsEnabled() && !e.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } var dialer gws.Dialer - err := b.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) require.NoError(t, err) - go b.wsReadData() - err = b.websocketSendAuth(t.Context()) + go e.wsReadData() + err = e.websocketSendAuth(t.Context()) require.NoError(t, err) timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout) select { - case resp := <-b.Websocket.DataHandler: + case resp := <-e.Websocket.DataHandler: sub, ok := resp.(WebsocketSubscribeResp) if !ok { t.Fatal("unable to type assert WebsocketSubscribeResp") @@ -749,7 +749,7 @@ func TestWsAuth(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(t.Context(), true) + err := e.UpdateTradablePairs(t.Context(), true) require.NoError(t, err) } @@ -764,7 +764,7 @@ func TestWsPositionUpdate(t *testing.T) { "unrealisedGrossPnl":-677,"unrealisedPnl":-677,"unrealisedPnlPcnt":-0.0078,"unrealisedRoePcnt":-0.7756, "simpleQty":0.001,"liquidationPrice":1140.1, "timestamp":"2017-04-04T22:07:45.442Z" }]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) } @@ -786,7 +786,7 @@ func TestWsInsertExectuionUpdate(t *testing.T) { "homeNotional":-0.00088155,"foreignNotional":1,"transactTime":"2017-04-04T22:07:46.035Z", "timestamp":"2017-04-04T22:07:46.035Z" }]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) } @@ -799,7 +799,7 @@ func TestWSPositionUpdateHandling(t *testing.T) { "markPrice":1136.88,"posState":"Liquidated","simpleQty":0.001,"liquidationPrice":1140.1,"bankruptPrice":1134.37, "timestamp":"2017-04-04T22:07:46.019Z" }]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) pressXToJSON = []byte(`{"table":"position", "action":"update", @@ -815,7 +815,7 @@ func TestWSPositionUpdateHandling(t *testing.T) { "avgEntryPrice":null,"breakEvenPrice":null,"marginCallPrice":null,"liquidationPrice":null,"bankruptPrice":null, "timestamp":"2017-04-04T22:07:46.140Z" }]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) require.NoError(t, err) } @@ -836,7 +836,7 @@ func TestWSOrderbookHandling(t *testing.T) { {"symbol":"ETHUSD","id":17999996000,"side":"Buy","size":20,"price":40}, {"symbol":"ETHUSD","id":17999997000,"side":"Buy","size":100,"price":30} ]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) pressXToJSON = []byte(`{ @@ -845,14 +845,14 @@ func TestWSOrderbookHandling(t *testing.T) { "data":[ {"symbol":"ETHUSD","id":17999995000,"side":"Buy","size":5,"timestamp":"2017-04-04T22:16:38.461Z"} ]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) require.NoError(t, err) pressXToJSON = []byte(`{ "table":"orderBookL2_25", "action":"update", "data":[]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) require.ErrorContains(t, err, "empty orderbook") pressXToJSON = []byte(`{ @@ -861,7 +861,7 @@ func TestWSOrderbookHandling(t *testing.T) { "data":[ {"symbol":"ETHUSD","id":17999995000,"side":"Buy","timestamp":"2017-04-04T22:16:38.461Z"} ]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) require.NoError(t, err) pressXToJSON = []byte(`{ @@ -870,7 +870,7 @@ func TestWSOrderbookHandling(t *testing.T) { "data":[ {"symbol":"ETHUSD","id":17999995000,"side":"Buy","timestamp":"2017-04-04T22:16:38.461Z"} ]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) assert.ErrorIs(t, err, orderbook.ErrOrderbookInvalid) } @@ -883,7 +883,7 @@ func TestWSDeleveragePositionUpdateHandling(t *testing.T) { "markPrice":1160.72,"posState":"Deleverage","simpleQty":1.746,"liquidationPrice":1140.1, "timestamp":"2017-04-04T22:16:38.460Z" }]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) pressXToJSON = []byte(`{"table":"position", @@ -901,7 +901,7 @@ func TestWSDeleveragePositionUpdateHandling(t *testing.T) { "avgEntryPrice":null,"breakEvenPrice":null,"marginCallPrice":null,"liquidationPrice":null,"bankruptPrice":null, "timestamp":"2017-04-04T22:16:38.547Z" }]}`) - err = b.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) require.NoError(t, err) } @@ -923,53 +923,53 @@ func TestWSDeleverageExecutionInsertHandling(t *testing.T) { "homeNotional":-1.72306,"foreignNotional":2000,"transactTime":"2017-04-04T22:16:38.472Z", "timestamp":"2017-04-04T22:16:38.472Z" }]}`) - err := b.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) require.NoError(t, err) } func TestWsTrades(t *testing.T) { t.Parallel() - b := new(Bitmex) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - b.SetSaveTradeDataStatus(true) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + e.SetSaveTradeDataStatus(true) msg := []byte(`{"table":"trade","action":"insert","data":[{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.3,"tickDirection":"MinusTick","trdMatchID":"c427f7a0-6b26-1e10-5c4e-1bd74daf2a73","grossValue":2583000,"homeNotional":0.9904912836767037,"foreignNotional":255.84389857369254},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.3,"tickDirection":"ZeroMinusTick","trdMatchID":"95eb9155-b58c-70e9-44b7-34efe50302e0","grossValue":2583000,"homeNotional":0.9904912836767037,"foreignNotional":255.84389857369254},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.3,"tickDirection":"ZeroMinusTick","trdMatchID":"e607c187-f25c-86bc-cb39-8afff7aaf2d9","grossValue":2583000,"homeNotional":0.9904912836767037,"foreignNotional":255.84389857369254},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":17,"price":258.3,"tickDirection":"ZeroMinusTick","trdMatchID":"0f076814-a57d-9a59-8063-ad6b823a80ac","grossValue":439110,"homeNotional":0.1683835182250396,"foreignNotional":43.49346275752773},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.25,"tickDirection":"MinusTick","trdMatchID":"f4ef3dfd-51c4-538f-37c1-e5071ba1c75d","grossValue":2582500,"homeNotional":0.9904912836767037,"foreignNotional":255.79437400950872},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.25,"tickDirection":"ZeroMinusTick","trdMatchID":"81ef136b-8f4a-b1cf-78a8-fffbfa89bf40","grossValue":2582500,"homeNotional":0.9904912836767037,"foreignNotional":255.79437400950872},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.25,"tickDirection":"ZeroMinusTick","trdMatchID":"65a87e8c-7563-34a4-d040-94e8513c5401","grossValue":2582500,"homeNotional":0.9904912836767037,"foreignNotional":255.79437400950872},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":15,"price":258.25,"tickDirection":"ZeroMinusTick","trdMatchID":"1d11a74e-a157-3f33-036d-35a101fba50b","grossValue":387375,"homeNotional":0.14857369255150554,"foreignNotional":38.369156101426306},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":1,"price":258.25,"tickDirection":"ZeroMinusTick","trdMatchID":"40d49df1-f018-f66f-4ca5-31d4997641d7","grossValue":25825,"homeNotional":0.009904912836767036,"foreignNotional":2.5579437400950873},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.2,"tickDirection":"MinusTick","trdMatchID":"36135b51-73e5-c007-362b-a55be5830c6b","grossValue":2582000,"homeNotional":0.9904912836767037,"foreignNotional":255.7448494453249},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"6ee19edb-99aa-3030-ba63-933ffb347ade","grossValue":2582000,"homeNotional":0.9904912836767037,"foreignNotional":255.7448494453249},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":100,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"d44be603-cdb8-d676-e3e2-f91fb12b2a70","grossValue":2582000,"homeNotional":0.9904912836767037,"foreignNotional":255.7448494453249},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":5,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"a14b43b3-50b4-c075-c54d-dfb0165de33d","grossValue":129100,"homeNotional":0.04952456418383518,"foreignNotional":12.787242472266245},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":8,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"3c30e175-5194-320c-8f8c-01636c2f4a32","grossValue":206560,"homeNotional":0.07923930269413629,"foreignNotional":20.45958795562599},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":50,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"5b803378-760b-4919-21fc-bfb275d39ace","grossValue":1291000,"homeNotional":0.49524564183835185,"foreignNotional":127.87242472266244},{"timestamp":"2020-02-17T01:35:36.442Z","symbol":"ETHUSD","side":"Sell","size":244,"price":258.2,"tickDirection":"ZeroMinusTick","trdMatchID":"cf57fec1-c444-b9e5-5e2d-4fb643f4fdb7","grossValue":6300080,"homeNotional":2.416798732171157,"foreignNotional":624.0174326465927}]}`) - require.NoError(t, b.wsHandleData(msg), "Must not error handling a standard stream of trades") + require.NoError(t, e.wsHandleData(msg), "Must not error handling a standard stream of trades") msg = []byte(`{"table":"trade","action":"insert","data":[{"timestamp":"2020-02-17T01:35:36.442Z","symbol":".BGCT","size":14,"price":258.2,"side":"sell"}]}`) - require.ErrorIs(t, b.wsHandleData(msg), exchange.ErrSymbolCannotBeMatched, "Must error correctly with an unknown symbol") + require.ErrorIs(t, e.wsHandleData(msg), exchange.ErrSymbolCannotBeMatched, "Must error correctly with an unknown symbol") msg = []byte(`{"table":"trade","action":"insert","data":[{"timestamp":"2020-02-17T01:35:36.442Z","symbol":".BGCT","size":0,"price":258.2,"side":"sell"}]}`) - require.NoError(t, b.wsHandleData(msg), "Must not error that symbol is unknown when index trade is ignored due to zero size") + require.NoError(t, e.wsHandleData(msg), "Must not error that symbol is unknown when index trade is ignored due to zero size") } func TestGetRecentTrades(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(t.Context(), false) + err := e.UpdateTradablePairs(t.Context(), false) require.NoError(t, err) - currencyPair := b.CurrencyPairs.Pairs[asset.Futures].Available[0] - _, err = b.GetRecentTrades(t.Context(), currencyPair, asset.Futures) + currencyPair := e.CurrencyPairs.Pairs[asset.Futures].Available[0] + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Futures) require.NoError(t, err) } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(t.Context(), false) + err := e.UpdateTradablePairs(t.Context(), false) require.NoError(t, err) - currencyPair := b.CurrencyPairs.Pairs[asset.Futures].Available[0] - _, err = b.GetHistoricTrades(t.Context(), currencyPair, asset.Futures, time.Now().Add(-time.Minute), time.Now()) + currencyPair := e.CurrencyPairs.Pairs[asset.Futures].Available[0] + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Futures, time.Now().Add(-time.Minute), time.Now()) require.NoError(t, err) } func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.ETH, currency.USD) - _, err := b.UpdateTicker(t.Context(), cp, asset.PerpetualContract) + _, err := e.UpdateTicker(t.Context(), cp, asset.PerpetualContract) require.NoError(t, err) } func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(t.Context(), asset.PerpetualContract) + err := e.UpdateTickers(t.Context(), asset.PerpetualContract) require.NoError(t, err) } @@ -987,63 +987,63 @@ func TestNormalizeWalletInfo(t *testing.T) { func TestGetOrderType(t *testing.T) { t.Parallel() - _, err := b.getOrderType(0) + _, err := e.getOrderType(0) assert.ErrorIs(t, err, order.ErrTypeIsInvalid) - o, err := b.getOrderType(1) + o, err := e.getOrderType(1) require.NoError(t, err) assert.Equal(t, order.Market, o) } func TestGetActionFromString(t *testing.T) { t.Parallel() - _, err := b.GetActionFromString("meow") + _, err := e.GetActionFromString("meow") assert.ErrorIs(t, err, orderbook.ErrInvalidAction) - action, err := b.GetActionFromString("update") + action, err := e.GetActionFromString("update") require.NoError(t, err) assert.Equal(t, orderbook.UpdateAction, action) - action, err = b.GetActionFromString("delete") + action, err = e.GetActionFromString("delete") require.NoError(t, err) assert.Equal(t, orderbook.DeleteAction, action) - action, err = b.GetActionFromString("insert") + action, err = e.GetActionFromString("insert") require.NoError(t, err) assert.Equal(t, orderbook.InsertAction, action) - action, err = b.GetActionFromString("update/insert") + action, err = e.GetActionFromString("update/insert") require.NoError(t, err) assert.Equal(t, orderbook.UpdateOrInsertAction, action) } func TestGetAccountFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAccountFundingHistory(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountFundingHistory(t.Context()) require.NoError(t, err) } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) require.NoError(t, err) } func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetOrderInfo(t.Context(), "1234", currency.NewBTCUSD(), asset.Spot) + _, err := e.GetOrderInfo(t.Context(), "1234", currency.NewBTCUSD(), asset.Spot) require.NoError(t, err) } func TestCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1234", AssetType: asset.Spot, @@ -1055,42 +1055,42 @@ func TestCancelBatchOrders(t *testing.T) { func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := b.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = b.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetFuturesContractDetails(t.Context(), asset.Futures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.Futures) assert.NoError(t, err) - _, err = b.GetFuturesContractDetails(t.Context(), asset.PerpetualContract) + _, err = e.GetFuturesContractDetails(t.Context(), asset.PerpetualContract) assert.NoError(t, err) } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), IncludePredictedRate: true, }) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: currency.NewPair(currency.BTC, currency.KLAY), }) assert.ErrorIs(t, err, futures.ErrNotPerpetualFuture) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.PerpetualContract, }) require.NoError(t, err) cp, err := currency.NewPairFromString("ETHUSD") require.NoError(t, err) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.PerpetualContract, Pair: cp, }) @@ -1099,11 +1099,11 @@ func TestGetLatestFundingRates(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - isPerp, err := b.IsPerpetualFutureCurrency(asset.Futures, currency.NewBTCUSD()) + isPerp, err := e.IsPerpetualFutureCurrency(asset.Futures, currency.NewBTCUSD()) require.NoError(t, err) require.False(t, isPerp) - isPerp, err = b.IsPerpetualFutureCurrency(asset.PerpetualContract, currency.NewBTCUSD()) + isPerp, err = e.IsPerpetualFutureCurrency(asset.PerpetualContract, currency.NewBTCUSD()) require.NoError(t, err) require.True(t, isPerp) } @@ -1112,9 +1112,9 @@ func TestGetOpenInterest(t *testing.T) { t.Parallel() cp1 := currency.NewPair(currency.XBT, currency.USD) cp2 := currency.NewPair(currency.DOGE, currency.USD) - sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, b, asset.PerpetualContract, cp1, cp2) + sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, e, asset.PerpetualContract, cp1, cp2) - resp, err := b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.XBT.Item, Quote: currency.USD.Item, Asset: asset.PerpetualContract, @@ -1122,7 +1122,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context(), + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.XBT.Item, Quote: currency.USD.Item, @@ -1136,11 +1136,11 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) - _, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.USDT.Item, Asset: asset.Spot, @@ -1150,12 +1150,12 @@ func TestGetOpenInterest(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -1164,8 +1164,8 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(Bitmex) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") p := currency.Pairs{ currency.NewPair(currency.ETH, currency.USD), @@ -1186,36 +1186,36 @@ func TestGenerateSubscriptions(t *testing.T) { {QualifiedChannel: bitmexWSPosition + ":" + p[0].String(), Channel: bitmexWSPosition, Authenticated: true, Asset: asset.PerpetualContract, Pairs: p[:1]}, } - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := b.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") testsubs.EqualLists(t, exp, subs) - for _, a := range b.GetAssetTypes(true) { - require.NoErrorf(t, b.CurrencyPairs.SetAssetEnabled(a, false), "SetAssetEnabled must not error for %s", a) + for _, a := range e.GetAssetTypes(true) { + require.NoErrorf(t, e.CurrencyPairs.SetAssetEnabled(a, false), "SetAssetEnabled must not error for %s", a) } - _, err = b.generateSubscriptions() + _, err = e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error when no assets are enabled") } func TestSubscribe(t *testing.T) { t.Parallel() - b := new(Bitmex) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - subs, err := b.generateSubscriptions() // Note: We grab this before it's overwritten by SetupWs + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + subs, err := e.generateSubscriptions() // Note: We grab this before it's overwritten by SetupWs require.NoError(t, err, "generateSubscriptions must not error") - testexch.SetupWs(t, b) - err = b.Subscribe(subs) + testexch.SetupWs(t, e) + err = e.Subscribe(subs) require.NoError(t, err, "Subscribe must not error") for _, s := range subs { assert.Equalf(t, subscription.SubscribedState, s.State(), "%s state should be subscribed", s.QualifiedChannel) } - err = b.Unsubscribe(subs) + err = e.Unsubscribe(subs) require.NoError(t, err, "Unsubscribe must not error") for _, s := range subs { assert.Equalf(t, subscription.UnsubscribedState, s.State(), "%s state should be unsusbscribed", s.QualifiedChannel) } - err = b.Subscribe(subscription.List{{QualifiedChannel: "wibble", Channel: "wibble", Asset: asset.Spot}}) + err = e.Subscribe(subscription.List{{QualifiedChannel: "wibble", Channel: "wibble", Asset: asset.Spot}}) require.ErrorContains(t, err, "Unknown table: wibble", "Subscribe must receive errors through websocket.Match on request json") } diff --git a/exchanges/bitmex/bitmex_websocket.go b/exchanges/bitmex/bitmex_websocket.go index 9575e92768c..9d78038ff2b 100644 --- a/exchanges/bitmex/bitmex_websocket.go +++ b/exchanges/bitmex/bitmex_websocket.go @@ -83,24 +83,24 @@ var defaultSubscriptions = subscription.List{ } // WsConnect initiates a new websocket connection -func (b *Bitmex) WsConnect() error { - if !b.Websocket.IsEnabled() || !b.IsEnabled() { +func (e *Exchange) WsConnect() error { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } ctx := context.TODO() var dialer gws.Dialer - if err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}); err != nil { + if err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}); err != nil { return err } - b.Websocket.Wg.Add(1) - go b.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() - if b.Websocket.CanUseAuthenticatedEndpoints() { - if err := b.websocketSendAuth(ctx); err != nil { - b.Websocket.SetCanUseAuthenticatedEndpoints(false) - log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", b.Name, err) + if e.Websocket.CanUseAuthenticatedEndpoints() { + if err := e.websocketSendAuth(ctx); err != nil { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", e.Name, err) } } @@ -113,22 +113,22 @@ const ( ) // wsReadData receives and passes on websocket messages for processing -func (b *Bitmex) wsReadData() { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := b.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (b *Bitmex) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { // We don't need to know about errors, since we're looking optimistically into the json op, _ := jsonparser.GetString(respRaw, "request", "op") errMsg, _ := jsonparser.GetString(respRaw, "error") @@ -141,8 +141,8 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { return err } - if b.Verbose { - log.Debugf(log.ExchangeSys, "%s successfully connected to websocket API at time: %s Limit: %d", b.Name, welcomeResp.Timestamp, welcomeResp.Limit.Remaining) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s successfully connected to websocket API at time: %s Limit: %d", e.Name, welcomeResp.Timestamp, welcomeResp.Limit.Remaining) } return nil case errMsg != "", success: @@ -156,7 +156,7 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { } req = string(reqBytes) } - if err := b.Websocket.Match.RequireMatchWithData(req, respRaw); err != nil { + if err := e.Websocket.Match.RequireMatchWithData(req, respRaw); err != nil { return fmt.Errorf("%w: %s", err, op) } return nil @@ -178,17 +178,17 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { return fmt.Errorf("empty orderbook data received: %s", respRaw) } - pair, a, err := b.GetPairAndAssetTypeRequestFormatted(orderbooks.Data[0].Symbol) + pair, a, err := e.GetPairAndAssetTypeRequestFormatted(orderbooks.Data[0].Symbol) if err != nil { return err } - err = b.processOrderbook(orderbooks.Data, orderbooks.Action, pair, a) + err = e.processOrderbook(orderbooks.Data, orderbooks.Action, pair, a) if err != nil { return err } case bitmexWSTrade: - return b.handleWsTrades(respRaw) + return e.handleWsTrades(respRaw) case bitmexWSAnnouncement: var announcement AnnouncementData if err := json.Unmarshal(respRaw, &announcement); err != nil { @@ -199,13 +199,13 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { return nil } - b.Websocket.DataHandler <- announcement.Data + e.Websocket.DataHandler <- announcement.Data case bitmexWSAffiliate: var response WsAffiliateResponse if err := json.Unmarshal(respRaw, &response); err != nil { return err } - b.Websocket.DataHandler <- response + e.Websocket.DataHandler <- response case bitmexWSInstrument: // ticker case bitmexWSExecution: @@ -216,28 +216,28 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { } for i := range response.Data { - p, a, err := b.GetPairAndAssetTypeRequestFormatted(response.Data[i].Symbol) + p, a, err := e.GetPairAndAssetTypeRequestFormatted(response.Data[i].Symbol) if err != nil { return err } oStatus, err := order.StringToOrderStatus(response.Data[i].OrdStatus) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[i].OrderID, Err: err, } } oSide, err := order.StringToOrderSide(response.Data[i].Side) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[i].OrderID, Err: err, } } - b.Websocket.DataHandler <- &order.Detail{ - Exchange: b.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: response.Data[i].OrderID, AccountID: strconv.FormatInt(response.Data[i].Account, 10), AssetType: a, @@ -247,7 +247,7 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { { Price: response.Data[i].Price, Amount: response.Data[i].OrderQuantity, - Exchange: b.Name, + Exchange: e.Name, TID: response.Data[i].ExecID, Side: oSide, Timestamp: response.Data[i].Timestamp, @@ -264,38 +264,38 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { switch response.Action { case "update", "insert": for x := range response.Data { - p, a, err := b.GetRequestFormattedPairAndAssetType(response.Data[x].Symbol) + p, a, err := e.GetRequestFormattedPairAndAssetType(response.Data[x].Symbol) if err != nil { return err } oSide, err := order.StringToOrderSide(response.Data[x].Side) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } } oType, err := order.StringToOrderType(response.Data[x].OrderType) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } } oStatus, err := order.StringToOrderStatus(response.Data[x].OrderStatus) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } } - b.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: response.Data[x].Price, Amount: response.Data[x].OrderQuantity, - Exchange: b.Name, + Exchange: e.Name, OrderID: response.Data[x].OrderID, AccountID: strconv.FormatInt(response.Data[x].Account, 10), Type: oType, @@ -308,15 +308,15 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { } case "delete": for x := range response.Data { - p, a, err := b.GetRequestFormattedPairAndAssetType(response.Data[x].Symbol) + p, a, err := e.GetRequestFormattedPairAndAssetType(response.Data[x].Symbol) if err != nil { return err } var oSide order.Side oSide, err = order.StringToOrderSide(response.Data[x].Side) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } @@ -324,8 +324,8 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { var oType order.Type oType, err = order.StringToOrderType(response.Data[x].OrderType) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } @@ -333,16 +333,16 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { var oStatus order.Status oStatus, err = order.StringToOrderStatus(response.Data[x].OrderStatus) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } } - b.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: response.Data[x].Price, Amount: response.Data[x].OrderQuantity, - Exchange: b.Name, + Exchange: e.Name, OrderID: response.Data[x].OrderID, AccountID: strconv.FormatInt(response.Data[x].Account, 10), Type: oType, @@ -354,14 +354,14 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { } } default: - b.Websocket.DataHandler <- fmt.Errorf("%s - Unsupported order update %+v", b.Name, response) + e.Websocket.DataHandler <- fmt.Errorf("%s - Unsupported order update %+v", e.Name, response) } case bitmexWSMargin: var response WsMarginResponse if err := json.Unmarshal(respRaw, &response); err != nil { return err } - b.Websocket.DataHandler <- response + e.Websocket.DataHandler <- response case bitmexWSPosition: var response WsPositionResponse if err := json.Unmarshal(respRaw, &response); err != nil { @@ -372,28 +372,28 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error { if err := json.Unmarshal(respRaw, &response); err != nil { return err } - b.Websocket.DataHandler <- response + e.Websocket.DataHandler <- response case bitmexWSTransact: var response WsTransactResponse if err := json.Unmarshal(respRaw, &response); err != nil { return err } - b.Websocket.DataHandler <- response + e.Websocket.DataHandler <- response case bitmexWSWallet: var response WsWalletResponse if err := json.Unmarshal(respRaw, &response); err != nil { return err } - b.Websocket.DataHandler <- response + e.Websocket.DataHandler <- response default: - b.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: b.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} } return nil } // ProcessOrderbook processes orderbook updates -func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency.Pair, a asset.Item) error { +func (e *Exchange) processOrderbook(data []OrderBookL2, action string, p currency.Pair, a asset.Item) error { if len(data) < 1 { return errors.New("no orderbook data") } @@ -424,17 +424,17 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency. book.Asks.Reverse() // Reverse asks for correct alignment book.Asset = a book.Pair = p - book.Exchange = b.Name - book.ValidateOrderbook = b.ValidateOrderbook + book.Exchange = e.Name + book.ValidateOrderbook = e.ValidateOrderbook book.LastUpdated = data[0].Timestamp - err := b.Websocket.Orderbook.LoadSnapshot(&book) + err := e.Websocket.Orderbook.LoadSnapshot(&book) if err != nil { return fmt.Errorf("process orderbook error - %s", err) } default: - updateAction, err := b.GetActionFromString(action) + updateAction, err := e.GetActionFromString(action) if err != nil { return err } @@ -454,7 +454,7 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency. bids = append(bids, nItem) } - err = b.Websocket.Orderbook.Update(&orderbook.Update{ + err = e.Websocket.Orderbook.Update(&orderbook.Update{ Bids: bids, Asks: asks, Pair: p, @@ -469,8 +469,8 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, p currency. return nil } -func (b *Bitmex) handleWsTrades(msg []byte) error { - if !b.IsSaveTradeDataEnabled() { +func (e *Exchange) handleWsTrades(msg []byte) error { + if !e.IsSaveTradeDataEnabled() { return nil } var tradeHolder TradeData @@ -484,7 +484,7 @@ func (b *Bitmex) handleWsTrades(msg []byte) error { // These have a size of 0 and are used only to indicate a changing price continue } - p, a, err := b.GetPairAndAssetTypeRequestFormatted(t.Symbol) + p, a, err := e.GetPairAndAssetTypeRequestFormatted(t.Symbol) if err != nil { return err } @@ -495,7 +495,7 @@ func (b *Bitmex) handleWsTrades(msg []byte) error { trades = append(trades, trade.Data{ TID: t.TrdMatchID, - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Side: oSide, @@ -504,40 +504,40 @@ func (b *Bitmex) handleWsTrades(msg []byte) error { Timestamp: t.Timestamp, }) } - return b.AddTradesToBuffer(trades...) + return e.AddTradesToBuffer(trades...) } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (b *Bitmex) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *Bitmex) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, }).Parse(subTplText) } // Subscribe subscribes to a websocket channel -func (b *Bitmex) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() return common.AppendError( - b.ParallelChanOp(ctx, subs.Public(), func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsSubscribeOp, l) }, len(subs)), - b.ParallelChanOp(ctx, subs.Private(), func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsSubscribeOp, l) }, len(subs)), + e.ParallelChanOp(ctx, subs.Public(), func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsSubscribeOp, l) }, len(subs)), + e.ParallelChanOp(ctx, subs.Private(), func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsSubscribeOp, l) }, len(subs)), ) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (b *Bitmex) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() return common.AppendError( - b.ParallelChanOp(ctx, subs.Public(), func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsUnsubscribeOp, l) }, len(subs)), - b.ParallelChanOp(ctx, subs.Private(), func(ctx context.Context, l subscription.List) error { return b.manageSubs(ctx, wsUnsubscribeOp, l) }, len(subs)), + e.ParallelChanOp(ctx, subs.Public(), func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsUnsubscribeOp, l) }, len(subs)), + e.ParallelChanOp(ctx, subs.Private(), func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsUnsubscribeOp, l) }, len(subs)), ) } -func (b *Bitmex) manageSubs(ctx context.Context, op string, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.List) error { req := WebsocketRequest{ Command: op, } @@ -550,7 +550,7 @@ func (b *Bitmex) manageSubs(ctx context.Context, op string, subs subscription.Li if err != nil { return err } - resps, errs := b.Websocket.Conn.SendMessageReturnResponses(ctx, request.Unset, string(reqJSON), req, len(subs)) + resps, errs := e.Websocket.Conn.SendMessageReturnResponses(ctx, request.Unset, string(reqJSON), req, len(subs)) for _, resp := range resps { if errMsg, _ := jsonparser.GetString(resp, "error"); errMsg != "" { errs = common.AppendError(errs, errors.New(errMsg)) @@ -564,9 +564,9 @@ func (b *Bitmex) manageSubs(ctx context.Context, op string, subs subscription.Li errs = common.AppendError(errs, fmt.Errorf("%w: %s", subscription.ErrNotFound, chanName)) } else { if op == wsSubscribeOp { - errs = common.AppendError(errs, b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, s)) + errs = common.AppendError(errs, e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s)) } else { - errs = common.AppendError(errs, b.Websocket.RemoveSubscriptions(b.Websocket.Conn, s)) + errs = common.AppendError(errs, e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s)) } } } @@ -575,8 +575,8 @@ func (b *Bitmex) manageSubs(ctx context.Context, op string, subs subscription.Li } // WebsocketSendAuth sends an authenticated subscription -func (b *Bitmex) websocketSendAuth(ctx context.Context) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) websocketSendAuth(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -593,21 +593,21 @@ func (b *Bitmex) websocketSendAuth(ctx context.Context) error { Arguments: []any{creds.Key, timestamp, hex.EncodeToString(hmac)}, } - resp, err := b.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Command, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Command, req) if err != nil { return err } if errMsg, _ := jsonparser.GetString(resp, "error"); errMsg != "" { return errors.New(errMsg) } - if b.Verbose { - log.Debugf(log.ExchangeSys, "%s websocket: Successfully authenticated websocket connection", b.Name) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s websocket: Successfully authenticated websocket connection", e.Name) } return nil } // GetActionFromString matches a string action to an internal action. -func (b *Bitmex) GetActionFromString(s string) (orderbook.ActionType, error) { +func (e *Exchange) GetActionFromString(s string) (orderbook.ActionType, error) { switch s { case "update": return orderbook.UpdateAction, nil diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index 752f4cc352e..9b99dbea703 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -34,12 +34,12 @@ import ( ) // SetDefaults sets the basic defaults for Bitmex -func (b *Bitmex) SetDefaults() { - b.Name = "Bitmex" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Bitmex" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for _, a := range []asset.Item{asset.Spot, asset.PerpetualContract, asset.Futures, asset.Index} { ps := currency.PairStore{ @@ -50,16 +50,16 @@ func (b *Bitmex) SetDefaults() { if a == asset.Spot { ps.RequestFormat.Delimiter = currency.UnderscoreDelimiter } - if err := b.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", b.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } - if err := b.DisableAssetWebsocketSupport(asset.Index); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", b.Name, asset.Index, err) + if err := e.DisableAssetWebsocketSupport(asset.Index); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, asset.Index, err) } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -124,60 +124,60 @@ func (b *Bitmex) SetDefaults() { } var err error - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: bitmexAPIURL, exchange.WebsocketSpot: bitmexWSURL, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (b *Bitmex) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsEndpoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: bitmexWSURL, RunningURL: wsEndpoint, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, URL: wsEndpoint, @@ -185,8 +185,8 @@ func (b *Bitmex) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitmex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - marketInfo, err := b.GetActiveAndIndexInstruments(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + marketInfo, err := e.GetActiveAndIndexInstruments(ctx) if err != nil { return nil, err } @@ -215,7 +215,7 @@ func (b *Bitmex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency settlement := strings.Split(marketInfo[x].Symbol, currency.UnderscoreDelimiter) if len(settlement) != 2 { log.Warnf(log.ExchangeSys, "%s currency %s %s cannot be added to tradable pairs", - b.Name, + e.Name, marketInfo[x].Symbol, a) break @@ -234,7 +234,7 @@ func (b *Bitmex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency isolate := strings.Split(marketInfo[x].Symbol, currency.UnderscoreDelimiter) if len(isolate[0]) < 3 { log.Warnf(log.ExchangeSys, "%s currency %s %s be cannot added to tradable pairs", - b.Name, + e.Name, marketInfo[x].Symbol, a) break @@ -275,29 +275,29 @@ func (b *Bitmex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitmex) UpdateTradablePairs(ctx context.Context, _ bool) error { - assets := b.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, _ bool) error { + assets := e.GetAssetTypes(false) for x := range assets { - pairs, err := b.FetchTradablePairs(ctx, assets[x]) + pairs, err := e.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } - err = b.UpdatePairs(pairs, assets[x], false, false) + err = e.UpdatePairs(pairs, assets[x], false, false) if err != nil { return err } } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitmex) UpdateTickers(ctx context.Context, a asset.Item) error { - if !b.SupportsAsset(a) { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { return fmt.Errorf("%w for [%v]", asset.ErrNotSupported, a) } - tick, err := b.GetActiveAndIndexInstruments(ctx) + tick, err := e.GetActiveAndIndexInstruments(ctx) if err != nil { return err } @@ -311,7 +311,7 @@ instruments: if tick[j].Typ != futuresID { continue instruments } - pair, enabled, err = b.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) + pair, enabled, err = e.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) case asset.Index: switch tick[j].Typ { case bitMEXBasketIndexID, @@ -326,18 +326,18 @@ instruments: // contain an underscore. Calling DeriveFrom will then error and // the instruments will be missed. tick[j].Symbol = strings.Replace(tick[j].Symbol, currency.UnderscoreDelimiter, "", 1) - pair, enabled, err = b.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) + pair, enabled, err = e.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) case asset.PerpetualContract: if tick[j].Typ != perpetualContractID { continue instruments } - pair, enabled, err = b.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) + pair, enabled, err = e.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) case asset.Spot: if tick[j].Typ != spotID { continue instruments } tick[j].Symbol = strings.Replace(tick[j].Symbol, currency.UnderscoreDelimiter, "", 1) - pair, enabled, err = b.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) + pair, enabled, err = e.MatchSymbolCheckEnabled(tick[j].Symbol, a, false) } if err != nil && !errors.Is(err, currency.ErrPairNotFound) { @@ -357,7 +357,7 @@ instruments: Close: tick[j].PrevClosePrice, Pair: pair, LastUpdated: tick[j].Timestamp, - ExchangeName: b.Name, + ExchangeName: e.Name, OpenInterest: tick[j].OpenInterest, AssetType: a, }) @@ -369,44 +369,44 @@ instruments: } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitmex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := b.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - fPair, err := b.FormatExchangeCurrency(p, a) + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - return ticker.GetTicker(b.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } if assetType == asset.Index { return book, common.ErrFunctionNotSupported } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := b.GetOrderbook(ctx, + orderbookNew, err := e.GetOrderbook(ctx, OrderBookGetL2Params{ Symbol: fPair.String(), Depth: 500, @@ -441,15 +441,15 @@ func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(b.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bitmex exchange -func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - userMargins, err := b.GetAllUserMargin(ctx) + userMargins, err := e.GetAllUserMargin(ctx) if err != nil { return info, err } @@ -460,7 +460,7 @@ func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a accountID := strconv.FormatInt(userMargins[i].Account, 10) var wallet WalletInfo - wallet, err = b.GetWalletInfo(ctx, userMargins[i].Currency) + wallet, err = e.GetWalletInfo(ctx, userMargins[i].Currency) if err != nil { continue } @@ -476,9 +476,9 @@ func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a if info.Accounts, err = account.CollectBalances(accountBalances, assetType); err != nil { return account.Holdings{}, err } - info.Exchange = b.Name + info.Exchange = e.Name - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -491,15 +491,15 @@ func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitmex) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { - history, err := b.GetWalletHistory(ctx, "all") +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { + history, err := e.GetWalletHistory(ctx, "all") if err != nil { return nil, err } resp := make([]exchange.FundingHistory, len(history)) for i := range history { resp[i] = exchange.FundingHistory{ - ExchangeName: b.Name, + ExchangeName: e.Name, Status: history[i].TransactStatus, Timestamp: history[i].Timestamp, Currency: history[i].Currency, @@ -515,8 +515,8 @@ func (b *Bitmex) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fundi } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitmex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - history, err := b.GetWalletHistory(ctx, c.String()) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + history, err := e.GetWalletHistory(ctx, c.String()) if err != nil { return nil, err } @@ -538,17 +538,17 @@ func (b *Bitmex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ a } // GetServerTime returns the current exchange server time. -func (b *Bitmex) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitmex) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return b.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitmex) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if assetType == asset.Index { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } @@ -556,7 +556,7 @@ func (b *Bitmex) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTy return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - p, err = b.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -572,7 +572,7 @@ allTrades: for { req.StartTime = ts.UTC().Format("2006-01-02T15:04:05.000Z") var tradeData []Trade - tradeData, err = b.GetTrade(ctx, req) + tradeData, err = e.GetTrade(ctx, req) if err != nil { return nil, err } @@ -591,7 +591,7 @@ allTrades: continue } resp = append(resp, trade.Data{ - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -612,7 +612,7 @@ allTrades: break allTrades } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -622,8 +622,8 @@ allTrades: } // SubmitOrder submits a new order -func (b *Bitmex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -632,7 +632,7 @@ func (b *Bitmex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi errors.New("order contract amount can not have decimals") } - fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -648,7 +648,7 @@ func (b *Bitmex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi orderNewParams.Price = s.Price } - response, err := b.CreateOrder(ctx, &orderNewParams) + response, err := e.CreateOrder(ctx, &orderNewParams) if err != nil { return nil, err } @@ -657,7 +657,7 @@ func (b *Bitmex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitmex) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } @@ -666,7 +666,7 @@ func (b *Bitmex) ModifyOrder(ctx context.Context, action *order.Modify) (*order. return nil, errors.New("contract amount can not have decimals") } - o, err := b.AmendOrder(ctx, &OrderAmendParams{ + o, err := e.AmendOrder(ctx, &OrderAmendParams{ OrderID: action.OrderID, OrderQty: int32(action.Amount), Price: action.Price, @@ -687,18 +687,18 @@ func (b *Bitmex) ModifyOrder(ctx context.Context, action *order.Modify) (*order. } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitmex) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - _, err := b.CancelOrders(ctx, &OrderCancelParams{ + _, err := e.CancelOrders(ctx, &OrderCancelParams{ OrderID: o.OrderID, }) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitmex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -722,7 +722,7 @@ func (b *Bitmex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde resp := &order.CancelBatchResponse{ Status: make(map[string]string), } - cancelResponse, err := b.CancelOrders(ctx, params) + cancelResponse, err := e.CancelOrders(ctx, params) if err != nil { return nil, err } @@ -733,12 +733,12 @@ func (b *Bitmex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitmex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } var emptyParams OrderCancelAllParams - orders, err := b.CancelAllExistingOrders(ctx, emptyParams) + orders, err := e.CancelAllExistingOrders(ctx, emptyParams) if err != nil { return cancelAllOrdersResponse, err } @@ -753,15 +753,15 @@ func (b *Bitmex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Ca } // GetOrderInfo returns order information based on order ID -func (b *Bitmex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - resp, err := b.GetOrders(ctx, &OrdersRequest{ + resp, err := e.GetOrders(ctx, &OrdersRequest{ Filter: `{"orderID":"` + orderID + `"}`, }) if err != nil { @@ -777,7 +777,7 @@ func (b *Bitmex) GetOrderInfo(ctx context.Context, orderID string, pair currency return nil, err } var oType order.Type - oType, err = b.getOrderType(resp[i].OrdType) + oType, err = e.getOrderType(resp[i].OrdType) if err != nil { return nil, err } @@ -787,7 +787,7 @@ func (b *Bitmex) GetOrderInfo(ctx context.Context, orderID string, pair currency Amount: resp[i].OrderQty, ExecutedAmount: resp[i].CumQty, RemainingAmount: resp[i].LeavesQty, - Exchange: b.Name, + Exchange: e.Name, OrderID: resp[i].OrderID, Side: orderSideMap[resp[i].Side], Status: orderStatus, @@ -800,8 +800,8 @@ func (b *Bitmex) GetOrderInfo(ctx context.Context, orderID string, pair currency } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitmex) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - resp, err := b.GetCryptoDepositAddress(ctx, cryptocurrency.String()) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + resp, err := e.GetCryptoDepositAddress(ctx, cryptocurrency.String()) if err != nil { return nil, err } @@ -812,7 +812,7 @@ func (b *Bitmex) GetDepositAddress(ctx context.Context, cryptocurrency currency. // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -826,7 +826,7 @@ func (b *Bitmex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques r.Fee = withdrawRequest.Crypto.FeeAmount } - resp, err := b.UserRequestWithdrawal(ctx, r) + resp, err := e.UserRequestWithdrawal(ctx, r) if err != nil { return nil, err } @@ -839,31 +839,31 @@ func (b *Bitmex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitmex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // GetActiveOrders retrieves any orders that are active/open // This function is not concurrency safe due to orderSide/orderType maps -func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -872,12 +872,12 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque params := OrdersRequest{ Filter: "{\"open\":true}", } - resp, err := b.GetOrders(ctx, ¶ms) + resp, err := e.GetOrders(ctx, ¶ms) if err != nil { return nil, err } - format, err := b.GetPairFormat(asset.PerpetualContract, false) + format, err := e.GetPairFormat(asset.PerpetualContract, false) if err != nil { return nil, err } @@ -887,12 +887,12 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque var orderStatus order.Status orderStatus, err = order.StringToOrderStatus(resp[i].OrdStatus) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var oType order.Type - oType, err = b.getOrderType(resp[i].OrdType) + oType, err = e.getOrderType(resp[i].OrdType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderDetail := order.Detail{ Date: resp[i].Timestamp, @@ -900,7 +900,7 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque Amount: resp[i].OrderQty, ExecutedAmount: resp[i].CumQty, RemainingAmount: resp[i].LeavesQty, - Exchange: b.Name, + Exchange: e.Name, OrderID: resp[i].OrderID, Side: orderSideMap[resp[i].Side], Status: orderStatus, @@ -912,25 +912,25 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque orders[i] = orderDetail } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status // This function is not concurrency safe due to orderSide/orderType maps -func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } params := OrdersRequest{} - resp, err := b.GetOrders(ctx, ¶ms) + resp, err := e.GetOrders(ctx, ¶ms) if err != nil { return nil, err } - format, err := b.GetPairFormat(asset.PerpetualContract, false) + format, err := e.GetPairFormat(asset.PerpetualContract, false) if err != nil { return nil, err } @@ -941,15 +941,15 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var orderStatus order.Status orderStatus, err = order.StringToOrderStatus(resp[i].OrdStatus) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } pair := currency.NewPairWithDelimiter(resp[i].Symbol, resp[i].SettlCurrency, format.Delimiter) var oType order.Type - oType, err = b.getOrderType(resp[i].OrdType) + oType, err = e.getOrderType(resp[i].OrdType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderDetail := order.Detail{ @@ -960,7 +960,7 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque RemainingAmount: resp[i].LeavesQty, Date: resp[i].TransactTime, CloseTime: resp[i].Timestamp, - Exchange: b.Name, + Exchange: e.Name, OrderID: resp[i].OrderID, Side: orderSide, Status: orderStatus, @@ -971,33 +971,33 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque orders[i] = orderDetail } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // AuthenticateWebsocket sends an authentication message to the websocket -func (b *Bitmex) AuthenticateWebsocket(ctx context.Context) error { - return b.websocketSendAuth(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.websocketSendAuth(ctx) } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Bitmex) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitmex) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitmex) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // getOrderType derives an order type from bitmex int representation -func (b *Bitmex) getOrderType(id int64) (order.Type, error) { +func (e *Exchange) getOrderType(id int64) (order.Type, error) { o, ok := orderTypeMap[id] if !ok { return order.UnknownType, fmt.Errorf("unhandled order type for '%d': %w", id, order.ErrTypeIsInvalid) @@ -1006,15 +1006,15 @@ func (b *Bitmex) getOrderType(id int64) (order.Type, error) { } // GetFuturesContractDetails returns details about futures contracts -func (b *Bitmex) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !b.SupportsAsset(item) || item == asset.Index { + if !e.SupportsAsset(item) || item == asset.Index { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } - marketInfo, err := b.GetInstruments(ctx, &GenericRequestParams{Reverse: true, Count: 500}) + marketInfo, err := e.GetInstruments(ctx, &GenericRequestParams{Reverse: true, Count: 500}) if err != nil { return nil, err } @@ -1052,7 +1052,7 @@ func (b *Bitmex) GetFuturesContractDetails(ctx context.Context, item asset.Item) contractSettlementType = futures.Inverse } resp = append(resp, futures.Contract{ - Exchange: b.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, Asset: item, @@ -1083,21 +1083,21 @@ func (b *Bitmex) GetFuturesContractDetails(ctx context.Context, item asset.Item) if err != nil { return nil, err } - var s, e time.Time + var startTime, endTime time.Time if marketInfo[x].Front != "" { - s, err = time.Parse(time.RFC3339, marketInfo[x].Front) + startTime, err = time.Parse(time.RFC3339, marketInfo[x].Front) if err != nil { return nil, err } } if marketInfo[x].Expiry != "" { - e, err = time.Parse(time.RFC3339, marketInfo[x].Expiry) + endTime, err = time.Parse(time.RFC3339, marketInfo[x].Expiry) if err != nil { return nil, err } } var ct futures.ContractType - contractDuration := e.Sub(s) + contractDuration := endTime.Sub(startTime) switch { case contractDuration <= kline.OneWeek.Duration()+kline.ThreeDay.Duration(): ct = futures.Weekly @@ -1122,12 +1122,12 @@ func (b *Bitmex) GetFuturesContractDetails(ctx context.Context, item asset.Item) contractSettlementType = futures.Quanto } resp = append(resp, futures.Contract{ - Exchange: b.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, Asset: item, - StartDate: s, - EndDate: e, + StartDate: startTime, + EndDate: endTime, IsActive: marketInfo[x].State == "Open", Status: marketInfo[x].State, Type: ct, @@ -1141,7 +1141,7 @@ func (b *Bitmex) GetFuturesContractDetails(ctx context.Context, item asset.Item) } // GetLatestFundingRates returns the latest funding rates data -func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1154,7 +1154,7 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates if r.Pair.IsEmpty() { count = "500" } else { - isPerp, err := b.IsPerpetualFutureCurrency(r.Asset, r.Pair) + isPerp, err := e.IsPerpetualFutureCurrency(r.Asset, r.Pair) if err != nil { return nil, err } @@ -1163,12 +1163,12 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } } - format, err := b.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } fPair := format.Format(r.Pair) - rates, err := b.GetFullFundingHistory(ctx, fPair, count, "", "", "", true, time.Time{}, time.Time{}) + rates, err := e.GetFullFundingHistory(ctx, fPair, count, "", "", "", true, time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -1188,7 +1188,7 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } var cp currency.Pair var isEnabled bool - cp, isEnabled, err = b.MatchSymbolCheckEnabled(rates[i].Symbol, r.Asset, false) + cp, isEnabled, err = e.MatchSymbolCheckEnabled(rates[i].Symbol, r.Asset, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1196,7 +1196,7 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates continue } var isPerp bool - isPerp, err = b.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -1204,7 +1204,7 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates continue } resp = append(resp, fundingrate.LatestRateResponse{ - Exchange: b.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -1219,17 +1219,17 @@ func (b *Bitmex) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (b *Bitmex) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { return a == asset.PerpetualContract, nil } // UpdateOrderExecutionLimits updates order execution limits -func (b *Bitmex) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetOpenInterest returns the open interest rate for a given asset pair -func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { if k[i].Asset == asset.Spot || k[i].Asset == asset.Index { // avoid API calls or returning errors after a successful retrieval @@ -1237,16 +1237,16 @@ func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } } if len(k) != 1 { - activeInstruments, err := b.GetActiveAndIndexInstruments(ctx) + activeInstruments, err := e.GetActiveAndIndexInstruments(ctx) if err != nil { return nil, err } resp := make([]futures.OpenInterest, 0, len(activeInstruments)) for i := range activeInstruments { - for _, a := range b.CurrencyPairs.GetAssetTypes(true) { + for _, a := range e.CurrencyPairs.GetAssetTypes(true) { var symbol currency.Pair var enabled bool - symbol, enabled, err = b.MatchSymbolCheckEnabled(activeInstruments[i].Symbol, a, false) + symbol, enabled, err = e.MatchSymbolCheckEnabled(activeInstruments[i].Symbol, a, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1265,7 +1265,7 @@ func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: b.Name, + Exchange: e.Name, Base: symbol.Base.Item, Quote: symbol.Quote.Item, Asset: a, @@ -1276,18 +1276,18 @@ func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } return resp, nil } - _, isEnabled, err := b.MatchSymbolCheckEnabled(k[0].Pair().String(), k[0].Asset, false) + _, isEnabled, err := e.MatchSymbolCheckEnabled(k[0].Pair().String(), k[0].Asset, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } if !isEnabled { return nil, fmt.Errorf("%w %v %v", currency.ErrPairNotEnabled, k[0].Asset, k[0].Pair()) } - symbolStr, err := b.FormatSymbol(k[0].Pair(), k[0].Asset) + symbolStr, err := e.FormatSymbol(k[0].Pair(), k[0].Asset) if err != nil { return nil, err } - instrument, err := b.GetInstrument(ctx, &GenericRequestParams{Symbol: symbolStr}) + instrument, err := e.GetInstrument(ctx, &GenericRequestParams{Symbol: symbolStr}) if err != nil { return nil, err } @@ -1297,7 +1297,7 @@ func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut resp := make([]futures.OpenInterest, 1) resp[0] = futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: b.Name, + Exchange: e.Name, Base: k[0].Base, Quote: k[0].Quote, Asset: k[0].Asset, @@ -1308,8 +1308,8 @@ func (b *Bitmex) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Bitmex) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 176a87370e3..36b9541472a 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -60,18 +60,18 @@ const ( bitstampRequestRate = 8000 ) -// Bitstamp is the overarching type across the bitstamp package -type Bitstamp struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bitstamp +type Exchange struct { exchange.Base } // GetFee returns an estimate of fee based on type of transaction -func (b *Bitstamp) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - tradingFee, err := b.getTradingFee(ctx, feeBuilder) + tradingFee, err := e.getTradingFee(ctx, feeBuilder) if err != nil { return 0, fmt.Errorf("error getting trading fee: %w", err) } @@ -92,8 +92,8 @@ func (b *Bitstamp) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) } // GetTradingFee returns a trading fee based on a currency -func (b *Bitstamp) getTradingFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { - tradingFees, err := b.GetAccountTradingFee(ctx, feeBuilder.Pair) +func (e *Exchange) getTradingFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { + tradingFees, err := e.GetAccountTradingFee(ctx, feeBuilder.Pair) if err != nil { return 0, err } @@ -106,23 +106,23 @@ func (b *Bitstamp) getTradingFee(ctx context.Context, feeBuilder *exchange.FeeBu } // GetAccountTradingFee returns a TradingFee for a pair -func (b *Bitstamp) GetAccountTradingFee(ctx context.Context, pair currency.Pair) (TradingFees, error) { +func (e *Exchange) GetAccountTradingFee(ctx context.Context, pair currency.Pair) (TradingFees, error) { path := bitstampAPITradingFees + "/" + strings.ToLower(pair.String()) var resp TradingFees if pair.IsEmpty() { return resp, currency.ErrCurrencyPairEmpty } - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) return resp, err } // GetAccountTradingFees returns a slice of TradingFee -func (b *Bitstamp) GetAccountTradingFees(ctx context.Context) ([]TradingFees, error) { +func (e *Exchange) GetAccountTradingFees(ctx context.Context) ([]TradingFees, error) { path := bitstampAPITradingFees var resp []TradingFees - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) return resp, err } @@ -155,7 +155,7 @@ func getInternationalBankDepositFee(amount float64) float64 { } // GetTicker returns ticker information -func (b *Bitstamp) GetTicker(ctx context.Context, currency string, hourly bool) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, currency string, hourly bool) (*Ticker, error) { response := Ticker{} tickerEndpoint := bitstampAPITicker @@ -163,13 +163,13 @@ func (b *Bitstamp) GetTicker(ctx context.Context, currency string, hourly bool) tickerEndpoint = bitstampAPITickerHourly } path := "/v" + bitstampAPIVersion + "/" + tickerEndpoint + "/" + strings.ToLower(currency) + "/" - return &response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) + return &response, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) } // GetOrderbook Returns a JSON dictionary with "bids" and "asks". Each is a list // of open orders and each order is represented as a list holding the price and // the amount. -func (b *Bitstamp) GetOrderbook(ctx context.Context, currency string) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, currency string) (*Orderbook, error) { type response struct { Timestamp types.Time `json:"timestamp"` Bids [][2]types.Number `json:"bids"` @@ -178,7 +178,7 @@ func (b *Bitstamp) GetOrderbook(ctx context.Context, currency string) (*Orderboo path := "/v" + bitstampAPIVersion + "/" + bitstampAPIOrderbook + "/" + strings.ToLower(currency) + "/" var resp response - err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return nil, err } @@ -204,35 +204,35 @@ func (b *Bitstamp) GetOrderbook(ctx context.Context, currency string) (*Orderboo // GetTradingPairs returns a list of trading pairs which Bitstamp // currently supports -func (b *Bitstamp) GetTradingPairs(ctx context.Context) ([]TradingPair, error) { +func (e *Exchange) GetTradingPairs(ctx context.Context) ([]TradingPair, error) { var result []TradingPair path := "/v" + bitstampAPIVersion + "/" + bitstampAPITradingPairsInfo - return result, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) } // GetTransactions returns transaction information // value parameter ["time"] = "minute", "hour", "day" will collate your // response into time intervals. -func (b *Bitstamp) GetTransactions(ctx context.Context, currencyPair, timePeriod string) ([]Transactions, error) { +func (e *Exchange) GetTransactions(ctx context.Context, currencyPair, timePeriod string) ([]Transactions, error) { var transactions []Transactions requestURL := "/v" + bitstampAPIVersion + "/" + bitstampAPITransactions + "/" + strings.ToLower(currencyPair) + "/" if timePeriod != "" { requestURL += "?time=" + url.QueryEscape(timePeriod) } - return transactions, b.SendHTTPRequest(ctx, exchange.RestSpot, requestURL, &transactions) + return transactions, e.SendHTTPRequest(ctx, exchange.RestSpot, requestURL, &transactions) } // GetEURUSDConversionRate returns the conversion rate between Euro and USD -func (b *Bitstamp) GetEURUSDConversionRate(ctx context.Context) (EURUSDConversionRate, error) { +func (e *Exchange) GetEURUSDConversionRate(ctx context.Context) (EURUSDConversionRate, error) { rate := EURUSDConversionRate{} path := "/" + bitstampAPIEURUSD - return rate, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &rate) + return rate, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &rate) } // GetBalance returns full balance of currency held on the exchange -func (b *Bitstamp) GetBalance(ctx context.Context) (Balances, error) { +func (e *Exchange) GetBalance(ctx context.Context) (Balances, error) { var balance map[string]types.Number - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIBalance, true, nil, &balance) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIBalance, true, nil, &balance) if err != nil { return nil, err } @@ -258,41 +258,41 @@ func (b *Bitstamp) GetBalance(ctx context.Context) (Balances, error) { } // GetUserTransactions returns an array of transactions -func (b *Bitstamp) GetUserTransactions(ctx context.Context, currencyPair string) ([]UserTransactions, error) { +func (e *Exchange) GetUserTransactions(ctx context.Context, currencyPair string) ([]UserTransactions, error) { var resp []UserTransactions var err error if currencyPair == "" { - err = b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions, true, url.Values{}, &resp) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions, true, url.Values{}, &resp) } else { - err = b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions+"/"+currencyPair, true, url.Values{}, &resp) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions+"/"+currencyPair, true, url.Values{}, &resp) } return resp, err } // GetOpenOrders returns all open orders on the exchange -func (b *Bitstamp) GetOpenOrders(ctx context.Context, currencyPair string) ([]Order, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, currencyPair string) ([]Order, error) { var resp []Order path := bitstampAPIOpenOrders + "/" + strings.ToLower(currencyPair) - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) } // GetOrderStatus returns an the status of an order by its ID -func (b *Bitstamp) GetOrderStatus(ctx context.Context, orderID int64) (OrderStatus, error) { +func (e *Exchange) GetOrderStatus(ctx context.Context, orderID int64) (OrderStatus, error) { resp := OrderStatus{} req := url.Values{} req.Add("id", strconv.FormatInt(orderID, 10)) return resp, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOrderStatus, false, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOrderStatus, false, req, &resp) } // CancelExistingOrder cancels order by ID -func (b *Bitstamp) CancelExistingOrder(ctx context.Context, orderID int64) (CancelOrder, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) (CancelOrder, error) { req := url.Values{} req.Add("id", strconv.FormatInt(orderID, 10)) var result CancelOrder - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelOrder, true, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelOrder, true, req, &result) if err != nil { return result, err } @@ -301,15 +301,15 @@ func (b *Bitstamp) CancelExistingOrder(ctx context.Context, orderID int64) (Canc } // CancelAllExistingOrders cancels all open orders on the exchange -func (b *Bitstamp) CancelAllExistingOrders(ctx context.Context) (bool, error) { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context) (bool, error) { result := false return result, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelAllOrders, false, nil, &result) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelAllOrders, false, nil, &result) } // PlaceOrder places an order on the exchange. -func (b *Bitstamp) PlaceOrder(ctx context.Context, currencyPair string, price, amount float64, buy, market bool) (Order, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, currencyPair string, price, amount float64, buy, market bool) (Order, error) { req := url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("price", strconv.FormatFloat(price, 'f', -1, 64)) @@ -328,13 +328,13 @@ func (b *Bitstamp) PlaceOrder(ctx context.Context, currencyPair string, price, a } return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &response) } // GetWithdrawalRequests returns withdrawal requests for the account // timedelta - positive integer with max value 50000000 which returns requests // from number of seconds ago to now. -func (b *Bitstamp) GetWithdrawalRequests(ctx context.Context, timedelta int64) ([]WithdrawalRequests, error) { +func (e *Exchange) GetWithdrawalRequests(ctx context.Context, timedelta int64) ([]WithdrawalRequests, error) { var resp []WithdrawalRequests if timedelta > 50000000 || timedelta < 0 { return resp, errors.New("time delta exceeded, max: 50000000 min: 0") @@ -348,7 +348,7 @@ func (b *Bitstamp) GetWithdrawalRequests(ctx context.Context, timedelta int64) ( } return resp, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIWithdrawalRequests, false, value, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIWithdrawalRequests, false, value, &resp) } // CryptoWithdrawal withdraws a cryptocurrency into a supplied wallet, returns ID @@ -356,7 +356,7 @@ func (b *Bitstamp) GetWithdrawalRequests(ctx context.Context, timedelta int64) ( // address - The wallet address of the cryptocurrency // symbol - the type of crypto ie "ltc", "btc", "eth" // destTag - only for XRP default to "" -func (b *Bitstamp) CryptoWithdrawal(ctx context.Context, amount float64, address, symbol, destTag string) (*CryptoWithdrawalResponse, error) { +func (e *Exchange) CryptoWithdrawal(ctx context.Context, amount float64, address, symbol, destTag string) (*CryptoWithdrawalResponse, error) { req := url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("address", address) @@ -375,11 +375,11 @@ func (b *Bitstamp) CryptoWithdrawal(ctx context.Context, amount float64, address var resp CryptoWithdrawalResponse endpoint = strings.ToLower(symbol) + "_withdrawal" - return &resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, endpoint, true, req, &resp) + return &resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, endpoint, true, req, &resp) } // OpenBankWithdrawal Opens a bank withdrawal request (SEPA or international) -func (b *Bitstamp) OpenBankWithdrawal(ctx context.Context, amount float64, currency, +func (e *Exchange) OpenBankWithdrawal(ctx context.Context, amount float64, currency, name, iban, bic, address, postalCode, city, country, comment, withdrawalType string, ) (FIATWithdrawalResponse, error) { @@ -397,11 +397,11 @@ func (b *Bitstamp) OpenBankWithdrawal(ctx context.Context, amount float64, curre req.Add("comment", comment) resp := FIATWithdrawalResponse{} - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) } // OpenInternationalBankWithdrawal Opens a bank withdrawal request (international) -func (b *Bitstamp) OpenInternationalBankWithdrawal(ctx context.Context, amount float64, currency, +func (e *Exchange) OpenInternationalBankWithdrawal(ctx context.Context, amount float64, currency, name, iban, bic, address, postalCode, city, country, bankName, bankAddress, bankPostCode, bankCity, bankCountry, internationalCurrency, comment, withdrawalType string, @@ -426,27 +426,27 @@ func (b *Bitstamp) OpenInternationalBankWithdrawal(ctx context.Context, amount f req.Add("bank_country", bankCountry) resp := FIATWithdrawalResponse{} - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) } // GetCryptoDepositAddress returns a depositing address by crypto. // crypto - example "btc", "ltc", "eth", "xrp" or "bch" -func (b *Bitstamp) GetCryptoDepositAddress(ctx context.Context, crypto currency.Code) (*DepositAddress, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, crypto currency.Code) (*DepositAddress, error) { path := crypto.Lower().String() + "_address" var resp DepositAddress - return &resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) + return &resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) } // GetUnconfirmedBitcoinDeposits returns unconfirmed transactions -func (b *Bitstamp) GetUnconfirmedBitcoinDeposits(ctx context.Context) ([]UnconfirmedBTCTransactions, error) { +func (e *Exchange) GetUnconfirmedBitcoinDeposits(ctx context.Context) ([]UnconfirmedBTCTransactions, error) { var response []UnconfirmedBTCTransactions return response, - b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUnconfirmedBitcoin, false, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUnconfirmedBitcoin, false, nil, &response) } // OHLC returns OHLCV data for step (interval) -func (b *Bitstamp) OHLC(ctx context.Context, currency string, start, end time.Time, step, limit string) (resp OHLCResponse, err error) { +func (e *Exchange) OHLC(ctx context.Context, currency string, start, end time.Time, step, limit string) (resp OHLCResponse, err error) { v := url.Values{} v.Add("limit", limit) v.Add("step", step) @@ -460,7 +460,7 @@ func (b *Bitstamp) OHLC(ctx context.Context, currency string, start, end time.Ti if !end.IsZero() { v.Add("end", strconv.FormatInt(end.Unix(), 10)) } - return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampAPIOHLC+"/"+currency, v), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampAPIOHLC+"/"+currency, v), &resp) } // TransferAccountBalance transfers funds from either a main or sub account @@ -468,7 +468,7 @@ func (b *Bitstamp) OHLC(ctx context.Context, currency string, start, end time.Ti // currency - which currency to transfer // subaccount - name of account // toMain - bool either to or from account -func (b *Bitstamp) TransferAccountBalance(ctx context.Context, amount float64, currency, subAccount string, toMain bool) error { +func (e *Exchange) TransferAccountBalance(ctx context.Context, amount float64, currency, subAccount string, toMain bool) error { req := url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("currency", currency) @@ -488,12 +488,12 @@ func (b *Bitstamp) TransferAccountBalance(ctx context.Context, amount float64, c var resp any - return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &resp) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bitstamp) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := b.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -501,22 +501,22 @@ func (b *Bitstamp) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated request -func (b *Bitstamp) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, v2 bool, values url.Values, result any) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, v2 bool, values url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := b.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -526,8 +526,8 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange } interim := json.RawMessage{} - err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { - n := b.Requester.GetNonce(nonce.UnixNano).String() + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + n := e.Requester.GetNonce(nonce.UnixNano).String() values.Set("key", creds.Key) values.Set("nonce", n) @@ -559,9 +559,9 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange Body: readerValues, Result: &interim, NonceEnabled: true, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { diff --git a/exchanges/bitstamp/bitstamp_live_test.go b/exchanges/bitstamp/bitstamp_live_test.go index 52a15a3a37b..8827deeb3d1 100644 --- a/exchanges/bitstamp/bitstamp_live_test.go +++ b/exchanges/bitstamp/bitstamp_live_test.go @@ -16,13 +16,13 @@ import ( var mockTests = false func TestMain(m *testing.M) { - b = new(Bitstamp) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bitstamp Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.SetCredentials(apiKey, apiSecret, customerID, "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, customerID, "", "", "") } log.Printf(sharedtestvalues.LiveTesting, b.Name) os.Exit(m.Run()) diff --git a/exchanges/bitstamp/bitstamp_mock_test.go b/exchanges/bitstamp/bitstamp_mock_test.go index fcd79146c80..7d74f098461 100644 --- a/exchanges/bitstamp/bitstamp_mock_test.go +++ b/exchanges/bitstamp/bitstamp_mock_test.go @@ -15,12 +15,12 @@ import ( var mockTests = true func TestMain(m *testing.M) { - b = new(Bitstamp) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bitstamp Setup error: %s", err) } - if err := testexch.MockHTTPInstance(b, "api"); err != nil { + if err := testexch.MockHTTPInstance(e, "api"); err != nil { log.Fatalf("Bitstamp MockHTTPInstance error: %s", err) } diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index 8dda13e14f5..e193c310d48 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -31,7 +31,7 @@ const ( ) var ( - b = &Bitstamp{} + e *Exchange btcusdPair = currency.NewBTCUSD() ) @@ -49,10 +49,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } feeBuilder := setFeeBuilder() - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err, "GetFeeByType must not error") if mockTests { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "TradeFee should be correct") @@ -68,9 +68,9 @@ func TestGetFee(t *testing.T) { // CryptocurrencyTradeFee Basic if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - fee, err := b.GetFee(t.Context(), feeBuilder) + fee, err := e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") if mockTests { assert.NotEmpty(t, fee, "Fee should not be empty") @@ -79,13 +79,13 @@ func TestGetFee(t *testing.T) { // CryptocurrencyTradeFee High quantity feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - fee, err = b.GetFee(t.Context(), feeBuilder) + fee, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") if mockTests { assert.Positive(t, fee, "Maker fee should be positive") @@ -94,7 +94,7 @@ func TestGetFee(t *testing.T) { // CryptocurrencyTradeFee IsTaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = false - fee, err = b.GetFee(t.Context(), feeBuilder) + fee, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") if mockTests { assert.Positive(t, fee, "Taker fee should be positive") @@ -103,33 +103,33 @@ func TestGetFee(t *testing.T) { // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - fee, err = b.GetFee(t.Context(), feeBuilder) + fee, err = e.GetFee(t.Context(), feeBuilder) require.NoError(t, err, "GetFee must not error") assert.NotEmpty(t, fee, "Fee should not be empty") } @@ -138,10 +138,10 @@ func TestGetAccountTradingFee(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - fee, err := b.GetAccountTradingFee(t.Context(), currency.NewPair(currency.LTC, currency.BTC)) + fee, err := e.GetAccountTradingFee(t.Context(), currency.NewPair(currency.LTC, currency.BTC)) require.NoError(t, err, "GetAccountTradingFee must not error") if mockTests { assert.Positive(t, fee.Fees.Maker, "Maker should be positive") @@ -150,7 +150,7 @@ func TestGetAccountTradingFee(t *testing.T) { assert.NotEmpty(t, fee.Symbol, "Symbol should not be empty") assert.Equal(t, "ltcbtc", fee.Symbol, "Symbol should be correct") - _, err = b.GetAccountTradingFee(t.Context(), currency.EMPTYPAIR) + _, err = e.GetAccountTradingFee(t.Context(), currency.EMPTYPAIR) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty, "Should get back the right error") } @@ -158,10 +158,10 @@ func TestGetAccountTradingFees(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - fees, err := b.GetAccountTradingFees(t.Context()) + fees, err := e.GetAccountTradingFees(t.Context()) require.NoError(t, err, "GetAccountTradingFee must not error") if assert.NotEmpty(t, fees, "Should get back multiple fees") { fee := fees[0] @@ -176,7 +176,7 @@ func TestGetAccountTradingFees(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - tick, err := b.GetTicker(t.Context(), + tick, err := e.GetTicker(t.Context(), currency.BTC.String()+currency.USD.String(), false) require.NoError(t, err, "GetTicker must not error") assert.Positive(t, tick.Ask, "Ask should be positive") @@ -195,7 +195,7 @@ func TestGetTicker(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - ob, err := b.GetOrderbook(t.Context(), currency.BTC.String()+currency.USD.String()) + ob, err := e.GetOrderbook(t.Context(), currency.BTC.String()+currency.USD.String()) require.NoError(t, err, "GetOrderbook must not error") assert.NotEmpty(t, ob.Timestamp, "Timestamp should not be empty") for i, o := range [][]OrderbookBase{ob.Asks, ob.Bids} { @@ -211,7 +211,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTradingPairs(t *testing.T) { t.Parallel() - p, err := b.GetTradingPairs(t.Context()) + p, err := e.GetTradingPairs(t.Context()) require.NoError(t, err, "GetTradingPairs must not error") assert.NotEmpty(t, p, "Pairs should not be empty") for _, res := range p { @@ -229,14 +229,14 @@ func TestGetTradingPairs(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - p, err := b.FetchTradablePairs(t.Context(), asset.Spot) + p, err := e.FetchTradablePairs(t.Context(), asset.Spot) require.NoError(t, err, "FetchTradablePairs must not error") assert.True(t, p.Contains(currency.NewBTCUSD(), true), "Pairs should contain BTC/USD") } func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(t.Context(), true) + err := e.UpdateTradablePairs(t.Context(), true) require.NoError(t, err, "UpdateTradablePairs must not error") } @@ -256,11 +256,11 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { }, } for assetItem, limitTests := range tests { - if err := b.UpdateOrderExecutionLimits(t.Context(), assetItem); err != nil { + if err := e.UpdateOrderExecutionLimits(t.Context(), assetItem); err != nil { t.Errorf("Error fetching %s pairs for test: %v", assetItem, err) } for _, limitTest := range limitTests { - limits, err := b.GetOrderExecutionLimits(assetItem, limitTest.pair) + limits, err := e.GetOrderExecutionLimits(assetItem, limitTest.pair) if err != nil { t.Errorf("Bitstamp GetOrderExecutionLimits() error during TestExecutionLimits; Asset: %s Pair: %s Err: %v", assetItem, limitTest.pair, err) continue @@ -284,7 +284,7 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestGetTransactions(t *testing.T) { t.Parallel() - tr, err := b.GetTransactions(t.Context(), + tr, err := e.GetTransactions(t.Context(), currency.BTC.String()+currency.USD.String(), "hour") require.NoError(t, err, "GetTransactions must not error") assert.NotEmpty(t, tr, "Transactions should not be empty") @@ -299,7 +299,7 @@ func TestGetTransactions(t *testing.T) { func TestGetEURUSDConversionRate(t *testing.T) { t.Parallel() - c, err := b.GetEURUSDConversionRate(t.Context()) + c, err := e.GetEURUSDConversionRate(t.Context()) require.NoError(t, err, "GetEURUSDConversionRate must not error") assert.Positive(t, c.Sell, "Sell should be positive") assert.Positive(t, c.Buy, "Buy should be positive") @@ -309,9 +309,9 @@ func TestGetBalance(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - bal, err := b.GetBalance(t.Context()) + bal, err := e.GetBalance(t.Context()) require.NoError(t, err, "GetBalance must not error") if mockTests { for k, e := range map[string]Balance{ @@ -340,9 +340,9 @@ func TestGetUserTransactions(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - tr, err := b.GetUserTransactions(t.Context(), "btcusd") + tr, err := e.GetUserTransactions(t.Context(), "btcusd") require.NoError(t, err, "GetUserTransactions must not error") if mockTests { assert.NotEmpty(t, tr, "Transactions should not be empty") @@ -357,9 +357,9 @@ func TestGetOpenOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - o, err := b.GetOpenOrders(t.Context(), "btcusd") + o, err := e.GetOpenOrders(t.Context(), "btcusd") require.NoError(t, err, "GetOpenOrders must not error") if mockTests { assert.NotEmpty(t, o, "Orders should not be empty") @@ -381,9 +381,9 @@ func TestGetOrderStatus(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - o, err := b.GetOrderStatus(t.Context(), 1458532827766784) + o, err := e.GetOrderStatus(t.Context(), 1458532827766784) if !mockTests { assert.ErrorContains(t, err, "Order not found") } else { @@ -408,9 +408,9 @@ func TestGetWithdrawalRequests(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - r, err := b.GetWithdrawalRequests(t.Context(), 1) + r, err := e.GetWithdrawalRequests(t.Context(), 1) require.NoError(t, err, "GetWithdrawalRequests must not error") if mockTests { assert.NotEmpty(t, r, "GetWithdrawalRequests should return a withdrawal request") @@ -433,9 +433,9 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - d, err := b.GetUnconfirmedBitcoinDeposits(t.Context()) + d, err := e.GetUnconfirmedBitcoinDeposits(t.Context()) require.NoError(t, err, "GetUnconfirmedBitcoinDeposits must not error") if mockTests { assert.NotEmpty(t, d, "Deposits should not be empty") @@ -451,9 +451,9 @@ func TestTransferAccountBalance(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - err := b.TransferAccountBalance(t.Context(), + err := e.TransferAccountBalance(t.Context(), 10000, "BTC", "1234567", true) if !mockTests { assert.ErrorContains(t, err, "Sub account with identifier \"1234567\" does not exist.") @@ -468,7 +468,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText - withdrawPermissions := b.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() assert.Equal(t, expectedResult, withdrawPermissions, "Permissions should be the same") } @@ -476,9 +476,9 @@ func TestGetActiveOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - o, err := b.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ + o, err := e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, @@ -501,9 +501,9 @@ func TestGetOrderHistory(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - o, err := b.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + o, err := e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, @@ -525,10 +525,10 @@ func TestSubmitOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } - o, err := b.SubmitOrder(t.Context(), &order.Submit{ - Exchange: b.Name, + o, err := e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Pair: currency.Pair{ Base: currency.BTC, Quote: currency.USD, @@ -558,9 +558,9 @@ func TestCancelExchangeOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } - err := b.CancelOrder(t.Context(), &order.Cancel{ + err := e.CancelOrder(t.Context(), &order.Cancel{ OrderID: "1453282316578816", }) if !mockTests { @@ -574,9 +574,9 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } - resp, err := b.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot}) + resp, err := e.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot}) require.NoError(t, err, "CancelAllOrders must not error") if len(resp.Status) > 0 { t.Errorf("%v orders failed to cancel", len(resp.Status)) @@ -586,7 +586,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := b.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } @@ -596,8 +596,8 @@ func TestWithdraw(t *testing.T) { if !mockTests { t.Skip("TestWithdraw not allowed for live tests") } - w, err := b.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: b.Name, + w, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Amount: 6, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -613,15 +613,15 @@ func TestWithdrawFiat(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } withdrawFiatRequest := withdraw.Request{ Type: withdraw.Fiat, - Exchange: b.Name, + Exchange: e.Name, Fiat: withdraw.FiatRequest{ Bank: banking.Account{ - SupportedExchanges: b.Name, + SupportedExchanges: e.Name, Enabled: true, AccountName: "Satoshi Nakamoto", AccountNumber: "12345", @@ -643,7 +643,7 @@ func TestWithdrawFiat(t *testing.T) { Description: "WITHDRAW IT ALL", } - w, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + w, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if mockTests { require.NoError(t, err, "WithdrawFiat must not error") assert.Equal(t, "1", w.ID, "Withdrawal ID should be correct") @@ -656,15 +656,15 @@ func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } withdrawFiatRequest := withdraw.Request{ Type: withdraw.Fiat, - Exchange: b.Name, + Exchange: e.Name, Fiat: withdraw.FiatRequest{ Bank: banking.Account{ - SupportedExchanges: b.Name, + SupportedExchanges: e.Name, Enabled: true, AccountName: "Satoshi Nakamoto", AccountNumber: "12345", @@ -692,7 +692,7 @@ func TestWithdrawInternationalBank(t *testing.T) { Description: "WITHDRAW IT ALL", } - w, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), + w, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if mockTests { assert.Equal(t, "1", w.ID, "Withdrawal ID should be correct") @@ -705,9 +705,9 @@ func TestGetDepositAddress(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) } - a, err := b.GetDepositAddress(t.Context(), currency.XRP, "", "") + a, err := e.GetDepositAddress(t.Context(), currency.XRP, "", "") require.NoError(t, err, "GetDepositAddress must not error") assert.NotEmpty(t, a.Address, "Address should not be empty") assert.NotEmpty(t, a.Tag, "Tag should not be empty") @@ -720,7 +720,7 @@ func TestWsSubscription(t *testing.T) { "channel": "[channel_name]" } }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "TestWsSubscription must not error") } @@ -731,44 +731,44 @@ func TestWsUnsubscribe(t *testing.T) { "channel": "[channel_name]" } }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "WsUnsubscribe must not error") } func TestWsTrade(t *testing.T) { pressXToJSON := []byte(`{"data": {"microtimestamp": "1580336751488517", "amount": 0.00598803, "buy_order_id": 4621328909, "sell_order_id": 4621329035, "amount_str": "0.00598803", "price_str": "9334.73", "timestamp": "1580336751", "price": 9334.73, "type": 1, "id": 104007706}, "event": "trade", "channel": "live_trades_btcusd"}`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "TestWsTrade must not error") } func TestWsOrderbook(t *testing.T) { pressXToJSON := []byte(`{"data": {"timestamp": "1580336834", "microtimestamp": "1580336834607546", "bids": [["9328.28", "0.05925332"], ["9327.34", "0.43120000"], ["9327.29", "0.63470860"], ["9326.59", "0.41114619"], ["9326.38", "1.06910000"], ["9323.91", "2.67930000"], ["9322.69", "0.80000000"], ["9322.57", "0.03000000"], ["9322.31", "1.36010820"], ["9319.54", "0.03090000"], ["9318.97", "0.28000000"], ["9317.61", "0.02910000"], ["9316.39", "1.08000000"], ["9316.20", "2.00000000"], ["9315.48", "1.00000000"], ["9314.72", "0.11197459"], ["9314.47", "0.32207398"], ["9312.53", "0.03961501"], ["9312.29", "1.00000000"], ["9311.78", "0.03060000"], ["9311.69", "0.32217221"], ["9310.98", "3.29000000"], ["9310.18", "0.01304192"], ["9310.13", "0.02500000"], ["9309.04", "1.00000000"], ["9309.00", "0.05000000"], ["9308.96", "0.03030000"], ["9308.91", "0.32227154"], ["9307.52", "0.32191362"], ["9307.25", "2.44280000"], ["9305.92", "3.00000000"], ["9305.62", "2.37600000"], ["9305.60", "0.21815312"], ["9305.54", "2.80000000"], ["9305.13", "0.05000000"], ["9305.02", "2.90917302"], ["9303.68", "0.02316372"], ["9303.53", "12.55000000"], ["9303.00", "0.02191430"], ["9302.94", "2.38250000"], ["9302.37", "0.01000000"], ["9301.85", "2.50000000"], ["9300.89", "0.02000000"], ["9300.40", "4.10000000"], ["9300.00", "0.33936139"], ["9298.48", "1.45200000"], ["9297.80", "0.42380000"], ["9295.44", "4.54689328"], ["9295.43", "3.20000000"], ["9295.00", "0.28669566"], ["9291.66", "14.09931321"], ["9290.13", "2.87254900"], ["9290.00", "0.67530840"], ["9285.37", "0.38033002"], ["9285.15", "5.37993528"], ["9285.00", "0.09419278"], ["9283.71", "0.15679830"], ["9280.33", "12.55000000"], ["9280.13", "3.20310000"], ["9280.00", "1.36477909"], ["9276.01", "0.00707488"], ["9275.75", "0.56974291"], ["9275.00", "5.88000000"], ["9274.00", "0.00754205"], ["9271.68", "0.01400000"], ["9271.11", "15.37188500"], ["9270.00", "0.06674325"], ["9268.79", "24.54320000"], ["9257.18", "12.55000000"], ["9256.30", "0.17876365"], ["9255.71", "13.82642967"], ["9254.79", "0.96329407"], ["9250.00", "0.78214958"], ["9245.34", "4.90200000"], ["9245.13", "0.10000000"], ["9240.00", "0.44383459"], ["9238.84", "13.16615207"], ["9234.11", "0.43317656"], ["9234.10", "12.55000000"], ["9231.28", "11.79290000"], ["9230.09", "4.15059441"], ["9227.69", "0.00791097"], ["9225.00", "0.44768346"], ["9224.49", "0.85857203"], ["9223.50", "5.61001041"], ["9216.01", "0.03222653"], ["9216.00", "0.05000000"], ["9213.54", "0.71253866"], ["9212.50", "2.86768195"], ["9211.07", "12.55000000"], ["9210.00", "0.54288817"], ["9208.00", "1.00000000"], ["9206.06", "2.62587578"], ["9205.98", "15.40000000"], ["9205.52", "0.01710603"], ["9205.37", "0.03524953"], ["9205.11", "0.15000000"], ["9205.00", "0.01534763"], ["9204.76", "7.00600000"], ["9203.00", "0.01090000"]], "asks": [["9337.10", "0.03000000"], ["9340.85", "2.67820000"], ["9340.95", "0.02900000"], ["9341.17", "1.00000000"], ["9341.41", "2.13966390"], ["9341.61", "0.20000000"], ["9341.97", "0.11199911"], ["9341.98", "3.00000000"], ["9342.26", "0.32112762"], ["9343.87", "1.00000000"], ["9344.17", "3.57250000"], ["9345.04", "0.32103450"], ["9345.41", "4.90000000"], ["9345.69", "1.03000000"], ["9345.80", "0.03000000"], ["9346.00", "0.10200000"], ["9346.69", "0.02397394"], ["9347.41", "1.00000000"], ["9347.82", "0.32094177"], ["9348.23", "0.02880000"], ["9348.62", "11.96287551"], ["9349.31", "2.44270000"], ["9349.47", "0.96000000"], ["9349.86", "4.50000000"], ["9350.37", "0.03300000"], ["9350.57", "0.34682266"], ["9350.60", "0.32085527"], ["9351.45", "0.31147923"], ["9352.31", "0.28000000"], ["9352.86", "9.80000000"], ["9353.73", "0.02360739"], ["9354.00", "0.45000000"], ["9354.12", "0.03000000"], ["9354.29", "3.82446861"], ["9356.20", "0.64000000"], ["9356.90", "0.02316372"], ["9357.30", "2.50000000"], ["9357.70", "2.38240000"], ["9358.92", "6.00000000"], ["9359.97", "0.34898075"], ["9359.98", "2.30000000"], ["9362.56", "2.37600000"], ["9365.00", "0.64000000"], ["9365.16", "1.70030306"], ["9365.27", "3.03000000"], ["9369.99", "2.47102665"], ["9370.00", "3.15688574"], ["9370.21", "2.32720000"], ["9371.78", "13.20000000"], ["9371.89", "0.96293482"], ["9375.08", "4.74762500"], ["9384.34", "1.45200000"], ["9384.49", "16.42310000"], ["9385.66", "0.34382112"], ["9388.19", "0.00268265"], ["9392.20", "0.20980000"], ["9392.40", "0.10320000"], ["9393.00", "0.20980000"], ["9395.40", "0.40000000"], ["9398.86", "24.54310000"], ["9400.00", "0.05489988"], ["9400.33", "0.00495100"], ["9400.45", "0.00484700"], ["9402.92", "17.20000000"], ["9404.18", "10.00000000"], ["9418.89", "16.38000000"], ["9419.41", "3.06700000"], ["9420.40", "12.50000000"], ["9421.11", "0.10500000"], ["9434.47", "0.03215805"], ["9434.48", "0.28285714"], ["9434.49", "15.83000000"], ["9435.13", "0.15000000"], ["9438.93", "0.00368800"], ["9439.19", "0.69343985"], ["9442.86", "0.10000000"], ["9443.96", "12.50000000"], ["9444.00", "0.06004471"], ["9444.97", "0.01494896"], ["9447.00", "0.01234000"], ["9448.97", "0.14500000"], ["9449.00", "0.05000000"], ["9450.00", "11.13426018"], ["9451.87", "15.90000000"], ["9452.00", "0.20000000"], ["9454.25", "0.01100000"], ["9454.51", "0.02409062"], ["9455.05", "0.00600063"], ["9456.00", "0.27965118"], ["9456.10", "0.17000000"], ["9459.00", "0.00320000"], ["9459.98", "0.02460685"], ["9459.99", "8.11000000"], ["9460.00", "0.08500000"], ["9464.36", "0.56957951"], ["9464.54", "0.69158059"], ["9465.00", "21.00002015"], ["9467.57", "12.50000000"], ["9468.00", "0.08800000"], ["9469.09", "13.94000000"]]}, "event": "data", "channel": "order_book_btcusd"}`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "wsHandleData must not error") pressXToJSON = []byte(`{"data": {"timestamp": "1580336834", "microtimestamp": "1580336834607546", "bids": [["9328.28", "0.05925332"], ["9327.34", "0.43120000"], ["9327.29", "0.63470860"], ["9326.59", "0.41114619"], ["9326.38", "1.06910000"], ["9323.91", "2.67930000"], ["9322.69", "0.80000000"], ["9322.57", "0.03000000"], ["9322.31", "1.36010820"], ["9319.54", "0.03090000"], ["9318.97", "0.28000000"], ["9317.61", "0.02910000"], ["9316.39", "1.08000000"], ["9316.20", "2.00000000"], ["9315.48", "1.00000000"], ["9314.72", "0.11197459"], ["9314.47", "0.32207398"], ["9312.53", "0.03961501"], ["9312.29", "1.00000000"], ["9311.78", "0.03060000"], ["9311.69", "0.32217221"], ["9310.98", "3.29000000"], ["9310.18", "0.01304192"], ["9310.13", "0.02500000"], ["9309.04", "1.00000000"], ["9309.00", "0.05000000"], ["9308.96", "0.03030000"], ["9308.91", "0.32227154"], ["9307.52", "0.32191362"], ["9307.25", "2.44280000"], ["9305.92", "3.00000000"], ["9305.62", "2.37600000"], ["9305.60", "0.21815312"], ["9305.54", "2.80000000"], ["9305.13", "0.05000000"], ["9305.02", "2.90917302"], ["9303.68", "0.02316372"], ["9303.53", "12.55000000"], ["9303.00", "0.02191430"], ["9302.94", "2.38250000"], ["9302.37", "0.01000000"], ["9301.85", "2.50000000"], ["9300.89", "0.02000000"], ["9300.40", "4.10000000"], ["9300.00", "0.33936139"], ["9298.48", "1.45200000"], ["9297.80", "0.42380000"], ["9295.44", "4.54689328"], ["9295.43", "3.20000000"], ["9295.00", "0.28669566"], ["9291.66", "14.09931321"], ["9290.13", "2.87254900"], ["9290.00", "0.67530840"], ["9285.37", "0.38033002"], ["9285.15", "5.37993528"], ["9285.00", "0.09419278"], ["9283.71", "0.15679830"], ["9280.33", "12.55000000"], ["9280.13", "3.20310000"], ["9280.00", "1.36477909"], ["9276.01", "0.00707488"], ["9275.75", "0.56974291"], ["9275.00", "5.88000000"], ["9274.00", "0.00754205"], ["9271.68", "0.01400000"], ["9271.11", "15.37188500"], ["9270.00", "0.06674325"], ["9268.79", "24.54320000"], ["9257.18", "12.55000000"], ["9256.30", "0.17876365"], ["9255.71", "13.82642967"], ["9254.79", "0.96329407"], ["9250.00", "0.78214958"], ["9245.34", "4.90200000"], ["9245.13", "0.10000000"], ["9240.00", "0.44383459"], ["9238.84", "13.16615207"], ["9234.11", "0.43317656"], ["9234.10", "12.55000000"], ["9231.28", "11.79290000"], ["9230.09", "4.15059441"], ["9227.69", "0.00791097"], ["9225.00", "0.44768346"], ["9224.49", "0.85857203"], ["9223.50", "5.61001041"], ["9216.01", "0.03222653"], ["9216.00", "0.05000000"], ["9213.54", "0.71253866"], ["9212.50", "2.86768195"], ["9211.07", "12.55000000"], ["9210.00", "0.54288817"], ["9208.00", "1.00000000"], ["9206.06", "2.62587578"], ["9205.98", "15.40000000"], ["9205.52", "0.01710603"], ["9205.37", "0.03524953"], ["9205.11", "0.15000000"], ["9205.00", "0.01534763"], ["9204.76", "7.00600000"], ["9203.00", "0.01090000"]], "asks": [["9337.10", "0.03000000"], ["9340.85", "2.67820000"], ["9340.95", "0.02900000"], ["9341.17", "1.00000000"], ["9341.41", "2.13966390"], ["9341.61", "0.20000000"], ["9341.97", "0.11199911"], ["9341.98", "3.00000000"], ["9342.26", "0.32112762"], ["9343.87", "1.00000000"], ["9344.17", "3.57250000"], ["9345.04", "0.32103450"], ["9345.41", "4.90000000"], ["9345.69", "1.03000000"], ["9345.80", "0.03000000"], ["9346.00", "0.10200000"], ["9346.69", "0.02397394"], ["9347.41", "1.00000000"], ["9347.82", "0.32094177"], ["9348.23", "0.02880000"], ["9348.62", "11.96287551"], ["9349.31", "2.44270000"], ["9349.47", "0.96000000"], ["9349.86", "4.50000000"], ["9350.37", "0.03300000"], ["9350.57", "0.34682266"], ["9350.60", "0.32085527"], ["9351.45", "0.31147923"], ["9352.31", "0.28000000"], ["9352.86", "9.80000000"], ["9353.73", "0.02360739"], ["9354.00", "0.45000000"], ["9354.12", "0.03000000"], ["9354.29", "3.82446861"], ["9356.20", "0.64000000"], ["9356.90", "0.02316372"], ["9357.30", "2.50000000"], ["9357.70", "2.38240000"], ["9358.92", "6.00000000"], ["9359.97", "0.34898075"], ["9359.98", "2.30000000"], ["9362.56", "2.37600000"], ["9365.00", "0.64000000"], ["9365.16", "1.70030306"], ["9365.27", "3.03000000"], ["9369.99", "2.47102665"], ["9370.00", "3.15688574"], ["9370.21", "2.32720000"], ["9371.78", "13.20000000"], ["9371.89", "0.96293482"], ["9375.08", "4.74762500"], ["9384.34", "1.45200000"], ["9384.49", "16.42310000"], ["9385.66", "0.34382112"], ["9388.19", "0.00268265"], ["9392.20", "0.20980000"], ["9392.40", "0.10320000"], ["9393.00", "0.20980000"], ["9395.40", "0.40000000"], ["9398.86", "24.54310000"], ["9400.00", "0.05489988"], ["9400.33", "0.00495100"], ["9400.45", "0.00484700"], ["9402.92", "17.20000000"], ["9404.18", "10.00000000"], ["9418.89", "16.38000000"], ["9419.41", "3.06700000"], ["9420.40", "12.50000000"], ["9421.11", "0.10500000"], ["9434.47", "0.03215805"], ["9434.48", "0.28285714"], ["9434.49", "15.83000000"], ["9435.13", "0.15000000"], ["9438.93", "0.00368800"], ["9439.19", "0.69343985"], ["9442.86", "0.10000000"], ["9443.96", "12.50000000"], ["9444.00", "0.06004471"], ["9444.97", "0.01494896"], ["9447.00", "0.01234000"], ["9448.97", "0.14500000"], ["9449.00", "0.05000000"], ["9450.00", "11.13426018"], ["9451.87", "15.90000000"], ["9452.00", "0.20000000"], ["9454.25", "0.01100000"], ["9454.51", "0.02409062"], ["9455.05", "0.00600063"], ["9456.00", "0.27965118"], ["9456.10", "0.17000000"], ["9459.00", "0.00320000"], ["9459.98", "0.02460685"], ["9459.99", "8.11000000"], ["9460.00", "0.08500000"], ["9464.36", "0.56957951"], ["9464.54", "0.69158059"], ["9465.00", "21.00002015"], ["9467.57", "12.50000000"], ["9468.00", "0.08800000"], ["9469.09", "13.94000000"]]}, "event": "data", "channel": ""}`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) require.ErrorIs(t, err, errChannelUnderscores, "wsHandleData must error parsing channel") } func TestWsOrderbook2(t *testing.T) { pressXToJSON := []byte(`{"data":{"timestamp":"1606965727","microtimestamp":"1606965727403931","bids":[["19133.97","0.01000000"],["19131.58","0.39200000"],["19131.18","0.69581810"],["19131.17","0.48139054"],["19129.72","0.48164130"],["19129.71","0.65400000"],["19128.80","1.04500000"],["19128.59","0.65400000"],["19128.12","0.00259236"],["19127.81","0.19784245"],["19126.66","1.04500000"],["19125.74","0.26020000"],["19124.68","0.22000000"],["19122.01","0.39777840"],["19122.00","1.04600000"],["19121.27","0.16741000"],["19121.10","1.56390000"],["19119.90","1.60000000"],["19119.58","0.15593238"],["19117.70","1.14600000"],["19115.36","2.61300000"],["19114.60","1.19570000"],["19113.88","0.07500000"],["19113.86","0.15668522"],["19113.70","1.00000000"],["19113.69","1.60000000"],["19112.27","0.00166667"],["19111.00","0.15464628"],["19108.80","0.70000000"],["19108.77","0.16300000"],["19108.38","1.10000000"],["19107.53","0.10000000"],["19106.83","0.21377991"],["19106.78","3.45938881"],["19104.24","1.30000000"],["19100.81","0.00166667"],["19100.21","0.49770000"],["19099.54","2.40971961"],["19099.53","0.51223189"],["19097.40","1.55000000"],["19095.55","2.61300000"],["19092.94","0.27402906"],["19092.20","1.60000000"],["19089.36","0.00166667"],["19086.32","1.62000000"],["19085.23","1.65670000"],["19080.88","1.40000000"],["19075.45","1.16000000"],["19071.24","1.20000000"],["19065.09","1.51000000"],["19059.38","1.57000000"],["19058.11","0.37393556"],["19052.98","0.01000000"],["19052.90","0.33000000"],["19049.55","6.89000000"],["19047.61","6.03623432"],["19030.16","16.60260000"],["19026.76","23.90800000"],["19024.78","2.16656212"],["19022.11","0.02628500"],["19020.37","6.03000000"],["19000.00","0.00132020"],["18993.52","2.22000000"],["18979.21","6.03240000"],["18970.20","0.01500000"],["18969.14","7.42000000"],["18956.46","6.03240000"],["18950.22","42.37500000"],["18950.00","0.00132019"],["18949.94","0.52650000"],["18946.00","0.00791700"],["18933.74","6.03240000"],["18932.21","8.21000000"],["18926.99","0.00150000"],["18926.98","0.02641500"],["18925.00","0.02000000"],["18909.99","0.00133000"],["18908.47","7.15000000"],["18905.99","0.00133000"],["18905.20","0.00190000"],["18901.00","0.10000000"],["18900.67","0.24430000"],["18900.00","7.56529933"],["18895.99","0.00178450"],["18890.00","0.10000000"],["18889.90","0.10580000"],["18888.00","0.00362564"],["18887.00","4.00000000"],["18881.62","0.20583403"],["18880.08","5.72198740"],["18880.05","8.33480000"],["18879.09","7.33000000"],["18875.99","0.00132450"],["18875.00","0.02000000"],["18873.47","0.25934200"],["18871.99","0.00132600"],["18870.93","0.36463225"],["18864.10","43.56800000"],["18853.11","0.00540000"],["18850.01","0.38925549"]],"asks":[["19141.75","0.39300000"],["19141.78","0.10204700"],["19143.05","1.99685100"],["19143.08","0.05777900"],["19143.09","1.60700800"],["19143.10","0.48282909"],["19143.36","0.11250000"],["19144.06","0.26040000"],["19145.97","0.65400000"],["19146.02","0.22000000"],["19146.56","0.45061841"],["19147.45","0.15877831"],["19148.92","0.70431840"],["19148.93","0.78400000"],["19150.32","0.78400000"],["19151.55","0.07500000"],["19152.64","3.11400000"],["19153.32","1.04600000"],["19153.84","0.15626630"],["19155.57","3.10000000"],["19156.40","0.13438213"],["19156.92","0.16300000"],["19157.54","1.38970000"],["19158.18","0.00166667"],["19158.41","0.15317000"],["19158.78","0.15888798"],["19160.14","0.10000000"],["19160.34","1.60000000"],["19160.70","1.21590000"],["19162.17","0.00352761"],["19162.67","1.04500000"],["19163.61","0.15000000"],["19163.80","1.18050000"],["19164.62","0.86919692"],["19165.36","0.15674424"],["19166.75","1.40000000"],["19167.47","2.61300000"],["19169.68","0.00166667"],["19171.08","0.15452025"],["19171.69","0.54308236"],["19172.12","0.49000000"],["19173.47","1.34000000"],["19174.49","1.07436448"],["19175.37","0.01200000"],["19178.25","1.50000000"],["19178.80","0.49770000"],["19181.18","0.00166667"],["19182.75","1.77297176"],["19182.76","2.61099999"],["19183.03","1.20000000"],["19185.17","6.00352761"],["19189.56","0.05797137"],["19189.72","1.17000000"],["19193.94","1.60000000"],["19197.15","0.26961100"],["19200.00","0.03107838"],["19200.06","1.29000000"],["19202.73","1.65670000"],["19206.06","1.30000000"],["19208.19","6.00352761"],["19209.00","0.00132021"],["19210.70","1.20000000"],["19213.77","0.02615500"],["19217.40","8.50000000"],["19217.57","1.29000000"],["19222.61","1.19000000"],["19230.00","0.00193480"],["19231.24","6.00000000"],["19237.91","6.89152278"],["19240.13","6.90000000"],["19242.16","0.00336000"],["19243.38","0.00299103"],["19244.48","14.79300000"],["19248.25","0.01300000"],["19250.00","1.95802492"],["19251.00","0.45000000"],["19254.20","0.00366102"],["19254.32","6.00000000"],["19259.00","0.00131022"],["19266.43","0.00917191"],["19267.63","0.05000000"],["19267.79","7.10000000"],["19268.72","16.60260000"],["19277.42","6.00000000"],["19286.64","0.00916230"],["19295.49","7.77000000"],["19300.00","0.19668172"],["19306.00","0.06000000"],["19307.00","3.00000000"],["19307.40","0.19000000"],["19309.00","0.00262046"],["19310.33","0.02602500"],["19319.33","0.00213688"],["19320.00","0.00171242"],["19321.02","48.47300000"],["19322.74","0.00250000"],["19324.00","0.36983571"],["19325.54","0.02314521"],["19325.73","7.22000000"],["19326.50","0.00915272"]]},"channel":"order_book_btcusd","event":"data"}`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "WsOrderbook2 must not error") } func TestWsOrderUpdate(t *testing.T) { t.Parallel() - b := new(Bitstamp) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - testexch.FixtureToDataHandler(t, "testdata/wsMyOrders.json", b.wsHandleData) - close(b.Websocket.DataHandler) - assert.Len(t, b.Websocket.DataHandler, 8, "Should see 8 orders") - for resp := range b.Websocket.DataHandler { + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + testexch.FixtureToDataHandler(t, "testdata/wsMyOrders.json", e.wsHandleData) + close(e.Websocket.DataHandler) + assert.Len(t, e.Websocket.DataHandler, 8, "Should see 8 orders") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case *order.Detail: - switch len(b.Websocket.DataHandler) { + switch len(e.Websocket.DataHandler) { case 7: assert.Equal(t, "1658864794234880", v.OrderID, "OrderID") assert.Equal(t, time.UnixMicro(1693831262313000), v.Date, "Date") @@ -841,13 +841,13 @@ func TestWsRequestReconnect(t *testing.T) { "channel": "", "data": "" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) require.NoError(t, err, "WsRequestReconnect must not error") } func TestOHLC(t *testing.T) { t.Parallel() - o, err := b.OHLC(t.Context(), "btcusd", time.Unix(1546300800, 0), time.Unix(1577836799, 0), "60", "10") + o, err := e.OHLC(t.Context(), "btcusd", time.Unix(1546300800, 0), time.Unix(1577836799, 0), "60", "10") require.NoError(t, err, "OHLC must not error") assert.Equal(t, "BTC/USD", o.Data.Pair, "Pair should be correct") for _, req := range o.Data.OHLCV { @@ -861,7 +861,7 @@ func TestOHLC(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() - c, err := b.GetHistoricCandles(t.Context(), btcusdPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) + c, err := e.GetHistoricCandles(t.Context(), btcusdPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) require.NoError(t, err, "GetHistoricCandles must not error") assert.Equal(t, btcusdPair, c.Pair, "Pair should be correct") assert.NotEmpty(t, c, "Candles should not be empty") @@ -877,7 +877,7 @@ func TestGetHistoricCandles(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - c, err := b.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) + c, err := e.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) require.NoError(t, err, "GetHistoricCandlesExtended must not error") assert.Equal(t, btcusdPair, c.Pair, "Pair should be correct") assert.NotEmpty(t, c, "Candles should not be empty") @@ -897,7 +897,7 @@ func TestGetRecentTrades(t *testing.T) { currencyPair, err := currency.NewPairFromString("LTCUSD") require.NoError(t, err, "NewPairFromString must not error") - tr, err := b.GetRecentTrades(t.Context(), currencyPair, asset.Spot) + tr, err := e.GetRecentTrades(t.Context(), currencyPair, asset.Spot) require.NoError(t, err, "GetRecentTrades must not error") assert.NotEmpty(t, tr, "Trades should not be empty") for _, req := range tr { @@ -915,7 +915,7 @@ func TestGetHistoricTrades(t *testing.T) { currencyPair, err := currency.NewPairFromString("LTCUSD") require.NoError(t, err, "NewPairFromString must not error") - _, err = b.GetHistoricTrades(t.Context(), + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } @@ -954,9 +954,9 @@ func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - h, err := b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + h, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) require.NoError(t, err, "GetWithdrawalsHistory must not error") if mockTests { assert.NotEmpty(t, h, "WithdrawalHistory should not be empty") @@ -972,9 +972,9 @@ func TestGetOrderInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - o, err := b.GetOrderInfo(t.Context(), "1458532827766784", btcusdPair, asset.Spot) + o, err := e.GetOrderInfo(t.Context(), "1458532827766784", btcusdPair, asset.Spot) if mockTests { require.NoError(t, err, "GetOrderInfo must not error") assert.Equal(t, time.Date(2022, time.January, 31, 14, 43, 15, 0, time.UTC), o.Date, "Date should match") @@ -993,9 +993,9 @@ func TestFetchWSAuth(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - resp, err := b.FetchWSAuth(t.Context()) + resp, err := e.FetchWSAuth(t.Context()) require.NoError(t, err, "FetchWSAuth must not error") assert.NotNil(t, resp, "resp should not be nil") assert.Positive(t, resp.UserID, "UserID should be positive") @@ -1005,12 +1005,12 @@ func TestFetchWSAuth(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -1018,14 +1018,14 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - require.True(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") - subs, err := b.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + require.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - pairs, err := b.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) require.NoError(t, err, "GetEnabledPairs must not error") - for _, baseSub := range b.Features.Subscriptions { + for _, baseSub := range e.Features.Subscriptions { for _, p := range pairs.Format(currency.PairFormat{Uppercase: false}) { s := baseSub.Clone() s.Pairs = currency.Pairs{p} @@ -1043,18 +1043,18 @@ func TestGenerateSubscriptions(t *testing.T) { func TestSubscribe(t *testing.T) { t.Parallel() - b := new(Bitstamp) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - subs, err := b.Features.Subscriptions.ExpandTemplates(b) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + subs, err := e.Features.Subscriptions.ExpandTemplates(e) require.NoError(t, err, "ExpandTemplates must not error") - b.Features.Subscriptions = subscription.List{} - testexch.SetupWs(t, b) - err = b.Subscribe(subs) + e.Features.Subscriptions = subscription.List{} + testexch.SetupWs(t, e) + err = e.Subscribe(subs) require.NoError(t, err, "Subscribe must not error") for _, s := range subs { assert.Equalf(t, subscription.SubscribedState, s.State(), "Subscription %s should be subscribed", s) } - err = b.Unsubscribe(subs) + err = e.Unsubscribe(subs) require.NoError(t, err, "UnSubscribe must not error") for _, s := range subs { assert.Equalf(t, subscription.UnsubscribedState, s.State(), "Subscription %s should be subscribed", s) diff --git a/exchanges/bitstamp/bitstamp_websocket.go b/exchanges/bitstamp/bitstamp_websocket.go index 3adeb231534..c38f6f1180c 100644 --- a/exchanges/bitstamp/bitstamp_websocket.go +++ b/exchanges/bitstamp/bitstamp_websocket.go @@ -55,51 +55,51 @@ var subscriptionNames = map[string]string{ } // WsConnect connects to a websocket feed -func (b *Bitstamp) WsConnect() error { - if !b.Websocket.IsEnabled() || !b.IsEnabled() { +func (e *Exchange) WsConnect() error { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } ctx := context.TODO() var dialer gws.Dialer - err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - if b.Verbose { - log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", b.Name) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", e.Name) } - b.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: hbMsg, Delay: hbInterval, }) - err = b.seedOrderBook(ctx) + err = e.seedOrderBook(ctx) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } - b.Websocket.Wg.Add(1) - go b.wsReadData(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) return nil } // wsReadData receives and passes on websocket messages for processing -func (b *Bitstamp) wsReadData(ctx context.Context) { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - if err := b.wsHandleData(ctx, resp.Raw); err != nil { - b.Websocket.DataHandler <- err + if err := e.wsHandleData(ctx, resp.Raw); err != nil { + e.Websocket.DataHandler <- err } } } -func (b *Bitstamp) wsHandleData(_ context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(_ context.Context, respRaw []byte) error { event, err := jsonparser.GetUnsafeString(respRaw, "event") if err != nil { return fmt.Errorf("%w `event`: %w", common.ErrParsingWSField, err) @@ -110,40 +110,40 @@ func (b *Bitstamp) wsHandleData(_ context.Context, respRaw []byte) error { case "heartbeat": return nil case "subscription_succeeded", "unsubscription_succeeded": - return b.handleWSSubscription(event, respRaw) + return e.handleWSSubscription(event, respRaw) case "data": - return b.handleWSOrderbook(respRaw) + return e.handleWSOrderbook(respRaw) case "trade": - return b.handleWSTrade(respRaw) + return e.handleWSTrade(respRaw) case "order_created", "order_deleted", "order_changed": - return b.handleWSOrder(event, respRaw) + return e.handleWSOrder(event, respRaw) case "request_reconnect": go func() { - if err := b.Websocket.Shutdown(); err != nil { // Connection monitor will reconnect - log.Errorf(log.WebsocketMgr, "%s failed to shutdown websocket: %v", b.Name, err) + if err := e.Websocket.Shutdown(); err != nil { // Connection monitor will reconnect + log.Errorf(log.WebsocketMgr, "%s failed to shutdown websocket: %v", e.Name, err) } }() default: - b.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: b.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} } return nil } -func (b *Bitstamp) handleWSSubscription(event string, respRaw []byte) error { +func (e *Exchange) handleWSSubscription(event string, respRaw []byte) error { channel, err := jsonparser.GetUnsafeString(respRaw, "channel") if err != nil { return fmt.Errorf("%w `channel`: %w", common.ErrParsingWSField, err) } event = strings.TrimSuffix(event, "scription_succeeded") - return b.Websocket.Match.RequireMatchWithData(event+":"+channel, respRaw) + return e.Websocket.Match.RequireMatchWithData(event+":"+channel, respRaw) } -func (b *Bitstamp) handleWSTrade(msg []byte) error { - if !b.IsSaveTradeDataEnabled() { +func (e *Exchange) handleWSTrade(msg []byte) error { + if !e.IsSaveTradeDataEnabled() { return nil } - _, p, err := b.parseChannelName(msg) + _, p, err := e.parseChannelName(msg) if err != nil { return err } @@ -161,7 +161,7 @@ func (b *Bitstamp) handleWSTrade(msg []byte) error { Timestamp: wsTradeTemp.Data.Timestamp.Time(), CurrencyPair: p, AssetType: asset.Spot, - Exchange: b.Name, + Exchange: e.Name, Price: wsTradeTemp.Data.Price, Amount: wsTradeTemp.Data.Amount, Side: side, @@ -169,8 +169,8 @@ func (b *Bitstamp) handleWSTrade(msg []byte) error { }) } -func (b *Bitstamp) handleWSOrder(event string, msg []byte) error { - channel, p, err := b.parseChannelName(msg) +func (e *Exchange) handleWSOrder(event string, msg []byte) error { + channel, p, err := e.parseChannelName(msg) if err != nil { return err } @@ -211,7 +211,7 @@ func (b *Bitstamp) handleWSOrder(event string, msg []byte) error { Amount: r.Order.Amount, RemainingAmount: r.Order.RemainingAmount, ExecutedAmount: executedAmount, - Exchange: b.Name, + Exchange: e.Name, OrderID: r.Order.IDStr, ClientOrderID: r.Order.ClientOrderID, Side: r.Order.Side.Side(), @@ -221,43 +221,43 @@ func (b *Bitstamp) handleWSOrder(event string, msg []byte) error { Pair: p, } - b.Websocket.DataHandler <- d + e.Websocket.DataHandler <- d return nil } -func (b *Bitstamp) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *Bitstamp) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{"channelName": channelName}).Parse(subTplText) } // Subscribe sends a websocket message to receive data from a list of channels -func (b *Bitstamp) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - return b.manageSubsWithCreds(ctx, subs, "sub") + return e.manageSubsWithCreds(ctx, subs, "sub") } // Unsubscribe sends a websocket message to stop receiving data from a list of channels -func (b *Bitstamp) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - return b.manageSubsWithCreds(ctx, subs, "unsub") + return e.manageSubsWithCreds(ctx, subs, "unsub") } -func (b *Bitstamp) manageSubsWithCreds(ctx context.Context, subs subscription.List, op string) error { +func (e *Exchange) manageSubsWithCreds(ctx context.Context, subs subscription.List, op string) error { var errs error var creds *WebsocketAuthResponse if authed := subs.Private(); len(authed) > 0 { - creds, errs = b.FetchWSAuth(ctx) + creds, errs = e.FetchWSAuth(ctx) } - return common.AppendError(errs, b.ParallelChanOp(ctx, subs, func(ctx context.Context, s subscription.List) error { return b.manageSubs(ctx, s, op, creds) }, 1)) + return common.AppendError(errs, e.ParallelChanOp(ctx, subs, func(ctx context.Context, s subscription.List) error { return e.manageSubs(ctx, s, op, creds) }, 1)) } -func (b *Bitstamp) manageSubs(ctx context.Context, subs subscription.List, op string, creds *WebsocketAuthResponse) error { - subs, errs := subs.ExpandTemplates(b) +func (e *Exchange) manageSubs(ctx context.Context, subs subscription.List, op string, creds *WebsocketAuthResponse) error { + subs, errs := subs.ExpandTemplates(e) for _, s := range subs { req := websocketEventRequest{ Event: "bts:" + op + "scribe", @@ -272,12 +272,12 @@ func (b *Bitstamp) manageSubs(ctx context.Context, subs subscription.List, op st req.Data.Channel = "private-" + req.Data.Channel + "-" + strconv.Itoa(int(creds.UserID)) req.Data.Auth = creds.Token } - _, err := b.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, op+":"+req.Data.Channel, req) + _, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, op+":"+req.Data.Channel, req) if err == nil { if op == "sub" { - err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, s) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) } else { - err = b.Websocket.RemoveSubscriptions(b.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } } if err != nil { @@ -288,8 +288,8 @@ func (b *Bitstamp) manageSubs(ctx context.Context, subs subscription.List, op st return errs } -func (b *Bitstamp) handleWSOrderbook(msg []byte) error { - _, p, err := b.parseChannelName(msg) +func (e *Exchange) handleWSOrderbook(msg []byte) error { + _, p, err := e.parseChannelName(msg) if err != nil { return err } @@ -305,8 +305,8 @@ func (b *Bitstamp) handleWSOrderbook(msg []byte) error { Pair: p, LastUpdated: wsOrderBookResp.Data.Microtimestamp.Time(), Asset: asset.Spot, - Exchange: b.Name, - ValidateOrderbook: b.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, } for i := range wsOrderBookResp.Data.Asks { @@ -318,21 +318,21 @@ func (b *Bitstamp) handleWSOrderbook(msg []byte) error { obUpdate.Bids[i].Amount = wsOrderBookResp.Data.Bids[i][1].Float64() } filterOrderbookZeroBidPrice(obUpdate) - return b.Websocket.Orderbook.LoadSnapshot(obUpdate) + return e.Websocket.Orderbook.LoadSnapshot(obUpdate) } -func (b *Bitstamp) seedOrderBook(ctx context.Context) error { - p, err := b.GetEnabledPairs(asset.Spot) +func (e *Exchange) seedOrderBook(ctx context.Context) error { + p, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } for x := range p { - pairFmt, err := b.FormatExchangeCurrency(p[x], asset.Spot) + pairFmt, err := e.FormatExchangeCurrency(p[x], asset.Spot) if err != nil { return err } - orderbookSeed, err := b.GetOrderbook(ctx, pairFmt.String()) + orderbookSeed, err := e.GetOrderbook(ctx, pairFmt.String()) if err != nil { return err } @@ -340,8 +340,8 @@ func (b *Bitstamp) seedOrderBook(ctx context.Context) error { newOrderBook := &orderbook.Book{ Pair: p[x], Asset: asset.Spot, - Exchange: b.Name, - ValidateOrderbook: b.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(orderbookSeed.Bids)), Asks: make(orderbook.Levels, len(orderbookSeed.Asks)), LastUpdated: orderbookSeed.Timestamp, @@ -362,7 +362,7 @@ func (b *Bitstamp) seedOrderBook(ctx context.Context) error { filterOrderbookZeroBidPrice(newOrderBook) - err = b.Websocket.Orderbook.LoadSnapshot(newOrderBook) + err = e.Websocket.Orderbook.LoadSnapshot(newOrderBook) if err != nil { return err } @@ -372,9 +372,9 @@ func (b *Bitstamp) seedOrderBook(ctx context.Context) error { // FetchWSAuth Retrieves a userID and auth-token from REST for subscribing to a websocket channel // The token life-expectancy is only about 60s; use it immediately and do not store it -func (b *Bitstamp) FetchWSAuth(ctx context.Context) (*WebsocketAuthResponse, error) { +func (e *Exchange) FetchWSAuth(ctx context.Context) (*WebsocketAuthResponse, error) { resp := &WebsocketAuthResponse{} - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIWSAuthToken, true, nil, resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIWSAuthToken, true, nil, resp) if err != nil { return nil, fmt.Errorf("error fetching auth token: %w", err) } @@ -382,7 +382,7 @@ func (b *Bitstamp) FetchWSAuth(ctx context.Context) (*WebsocketAuthResponse, err } // parseChannelName splits the ws message channel and returns the channel name and pair -func (b *Bitstamp) parseChannelName(respRaw []byte) (string, currency.Pair, error) { +func (e *Exchange) parseChannelName(respRaw []byte) (string, currency.Pair, error) { channel, err := jsonparser.GetUnsafeString(respRaw, "channel") if err != nil { return "", currency.EMPTYPAIR, fmt.Errorf("%w `channel`: %w", common.ErrParsingWSField, err) @@ -403,7 +403,7 @@ func (b *Bitstamp) parseChannelName(respRaw []byte) (string, currency.Pair, erro return "", currency.EMPTYPAIR, fmt.Errorf("%w: %s", errChannelUnderscores, channel) } - enabledPairs, err := b.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return "", currency.EMPTYPAIR, err } diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 821a2c81510..2ccb7cc8a75 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -31,24 +31,24 @@ import ( ) // SetDefaults sets default for Bitstamp -func (b *Bitstamp) SetDefaults() { - b.Name = "Bitstamp" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true - b.API.CredentialsValidator.RequiresClientID = true +func (e *Exchange) SetDefaults() { + e.Name = "Bitstamp" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresClientID = true requestFmt := ¤cy.EMPTYFORMAT configFmt := ¤cy.PairFormat{ Uppercase: true, Delimiter: currency.ForwardSlashDelimiter, } - err := b.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -110,70 +110,70 @@ func (b *Bitstamp) SetDefaults() { Subscriptions: defaultSubscriptions.Clone(), } - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(request.NewBasicRateLimit(bitstampRateInterval, bitstampRequestRate, 1))) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: bitstampAPIURL, exchange.WebsocketSpot: bitstampWSURL, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets configuration values to bitstamp -func (b *Bitstamp) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsURL, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: bitstampWSURL, RunningURL: wsURL, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ - URL: b.Websocket.GetWebsocketURL(), + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + URL: e.Websocket.GetWebsocketURL(), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitstamp) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - symbols, err := b.GetTradingPairs(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + symbols, err := e.GetTradingPairs(ctx) if err != nil { return nil, err } @@ -194,24 +194,24 @@ func (b *Bitstamp) FetchTradablePairs(ctx context.Context, _ asset.Item) (curren // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitstamp) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = b.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateOrderExecutionLimits sets exchange execution order limits for an asset type -func (b *Bitstamp) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { if a != asset.Spot { return common.ErrNotYetImplemented } - symbols, err := b.GetTradingPairs(ctx) + symbols, err := e.GetTradingPairs(ctx) if err != nil { return err } @@ -232,25 +232,25 @@ func (b *Bitstamp) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) MinimumQuoteAmount: info.MinimumOrder, }) } - if err := b.LoadLimits(limits); err != nil { - return fmt.Errorf("%s Error loading exchange limits: %v", b.Name, err) + if err := e.LoadLimits(limits); err != nil { + return fmt.Errorf("%s Error loading exchange limits: %v", e.Name, err) } return nil } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitstamp) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitstamp) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - fPair, err := b.FormatExchangeCurrency(p, a) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := b.GetTicker(ctx, fPair.String(), false) + tick, err := e.GetTicker(ctx, fPair.String(), false) if err != nil { return nil, err } @@ -265,48 +265,48 @@ func (b *Bitstamp) UpdateTicker(ctx context.Context, p currency.Pair, a asset.It Open: tick.Open, Pair: fPair, LastUpdated: tick.Timestamp.Time(), - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(b.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitstamp) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if (!b.AreCredentialsValid(ctx) || b.SkipAuthCheck) && // Todo check connection status + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := b.GetOrderbook(ctx, fPair.String()) + orderbookNew, err := e.GetOrderbook(ctx, fPair.String()) if err != nil { return book, err } @@ -333,15 +333,15 @@ func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTy if err != nil { return book, err } - return orderbook.Get(b.Name, fPair, assetType) + return orderbook.Get(e.Name, fPair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bitstamp exchange -func (b *Bitstamp) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = b.Name - accountBalance, err := b.GetBalance(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetBalance(ctx) if err != nil { return response, err } @@ -360,7 +360,7 @@ func (b *Bitstamp) UpdateAccountInfo(ctx context.Context, assetType asset.Item) Currencies: currencies, }) - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -374,13 +374,13 @@ func (b *Bitstamp) UpdateAccountInfo(ctx context.Context, assetType asset.Item) // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitstamp) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitstamp) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - withdrawals, err := b.GetWithdrawalRequests(ctx, 0) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + withdrawals, err := e.GetWithdrawalRequests(ctx, 0) if err != nil { return nil, err } @@ -402,13 +402,13 @@ func (b *Bitstamp) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitstamp) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - p, err := b.FormatExchangeCurrency(p, assetType) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetTransactions(ctx, p.String(), "") + tradeData, err := e.GetTransactions(ctx, p.String(), "") if err != nil { return nil, err } @@ -420,7 +420,7 @@ func (b *Bitstamp) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy s = order.Sell } resp[i] = trade.Data{ - Exchange: b.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].TradeID, 10), CurrencyPair: p, AssetType: assetType, @@ -431,7 +431,7 @@ func (b *Bitstamp) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -441,22 +441,22 @@ func (b *Bitstamp) GetRecentTrades(ctx context.Context, p currency.Pair, assetTy } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitstamp) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *Bitstamp) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } - response, err := b.PlaceOrder(ctx, + response, err := e.PlaceOrder(ctx, fPair.String(), s.Price, s.Amount, @@ -470,12 +470,12 @@ func (b *Bitstamp) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Sub // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitstamp) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitstamp) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -484,18 +484,18 @@ func (b *Bitstamp) CancelOrder(ctx context.Context, o *order.Cancel) error { if err != nil { return err } - _, err = b.CancelExistingOrder(ctx, orderIDInt) + _, err = e.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitstamp) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitstamp) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { - success, err := b.CancelAllExistingOrders(ctx) +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { + success, err := e.CancelAllExistingOrders(ctx) if err != nil { return order.CancelAllResponse{}, err } @@ -507,12 +507,12 @@ func (b *Bitstamp) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order. } // GetOrderInfo returns order information based on order ID -func (b *Bitstamp) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { iOID, err := strconv.ParseInt(orderID, 10, 64) if err != nil { return nil, err } - o, err := b.GetOrderStatus(ctx, iOID) + o, err := e.GetOrderStatus(ctx, iOID) if err != nil { return nil, err } @@ -540,8 +540,8 @@ func (b *Bitstamp) GetOrderInfo(ctx context.Context, orderID string, _ currency. } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitstamp) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - addr, err := b.GetCryptoDepositAddress(ctx, cryptocurrency) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + addr, err := e.GetCryptoDepositAddress(ctx, cryptocurrency) if err != nil { return nil, err } @@ -559,11 +559,11 @@ func (b *Bitstamp) GetDepositAddress(ctx context.Context, cryptocurrency currenc // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitstamp) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.CryptoWithdrawal(ctx, + resp, err := e.CryptoWithdrawal(ctx, withdrawRequest.Amount, withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), @@ -579,11 +579,11 @@ func (b *Bitstamp) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitstamp) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.OpenBankWithdrawal(ctx, + resp, err := e.OpenBankWithdrawal(ctx, withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Fiat.Bank.AccountName, @@ -606,11 +606,11 @@ func (b *Bitstamp) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withd // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.OpenInternationalBankWithdrawal(ctx, + resp, err := e.OpenInternationalBankWithdrawal(ctx, withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Fiat.Bank.AccountName, @@ -638,7 +638,7 @@ func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(ctx context.Context, wit } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -649,14 +649,14 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.MultiOrderReq currPair = "all" } else { var fPair currency.Pair - fPair, err = b.FormatExchangeCurrency(req.Pairs[0], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[0], asset.Spot) if err != nil { return nil, err } currPair = fPair.String() } - resp, err := b.GetOpenOrders(ctx, currPair) + resp, err := e.GetOpenOrders(ctx, currPair) if err != nil { return nil, err } @@ -688,15 +688,15 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.MultiOrderReq Side: orderSide, Date: resp[i].DateTime.Time(), Pair: p, - Exchange: b.Name, + Exchange: e.Name, } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -705,19 +705,19 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq var currPair string if len(req.Pairs) == 1 { var fPair currency.Pair - fPair, err = b.FormatExchangeCurrency(req.Pairs[0], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[0], asset.Spot) if err != nil { return nil, err } currPair = fPair.String() } - format, err := b.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } - resp, err := b.GetUserTransactions(ctx, currPair) + resp, err := e.GetUserTransactions(ctx, currPair) if err != nil { return nil, err } @@ -737,7 +737,7 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq default: log.Warnf(log.ExchangeSys, "%s No base currency found for ID '%d'\n", - b.Name, + e.Name, resp[i].OrderID) } @@ -749,7 +749,7 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq default: log.Warnf(log.ExchangeSys, "%s No quote currency found for orderID '%d'\n", - b.Name, + e.Name, resp[i].OrderID) } @@ -763,32 +763,32 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq orders = append(orders, order.Detail{ OrderID: strconv.FormatInt(resp[i].OrderID, 10), Date: resp[i].Date.Time(), - Exchange: b.Name, + Exchange: e.Name, Pair: currPair, }) } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *Bitstamp) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitstamp) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - candles, err := b.OHLC(ctx, + candles, err := e.OHLC(ctx, req.RequestFormatted.String(), req.Start, req.End, - b.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), strconv.FormatUint(req.RequestLimit, 10)) if err != nil { return nil, err @@ -813,8 +813,8 @@ func (b *Bitstamp) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitstamp) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -822,11 +822,11 @@ func (b *Bitstamp) GetHistoricCandlesExtended(ctx context.Context, pair currency timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var candles OHLCResponse - candles, err = b.OHLC(ctx, + candles, err = e.OHLC(ctx, req.RequestFormatted.String(), req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time, - b.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), strconv.FormatUint(req.RequestLimit, 10), ) if err != nil { @@ -853,23 +853,23 @@ func (b *Bitstamp) GetHistoricCandlesExtended(ctx context.Context, pair currency } // GetServerTime returns the current exchange server time. -func (b *Bitstamp) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (b *Bitstamp) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (b *Bitstamp) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *Bitstamp) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index d86745df6d9..156dbb0ff69 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -94,26 +94,26 @@ const ( clientType = "api" ) -// BTCMarkets is the overarching type across the BTCMarkets package -type BTCMarkets struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with BTC Markets +type Exchange struct { exchange.Base } // GetMarkets returns the BTCMarkets instruments -func (b *BTCMarkets) GetMarkets(ctx context.Context) ([]Market, error) { +func (e *Exchange) GetMarkets(ctx context.Context) ([]Market, error) { var resp []Market - return resp, b.SendHTTPRequest(ctx, btcMarketsUnauthPath, &resp) + return resp, e.SendHTTPRequest(ctx, btcMarketsUnauthPath, &resp) } // GetTicker returns a ticker // symbol - example "btc" or "ltc" -func (b *BTCMarkets) GetTicker(ctx context.Context, marketID string) (Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, marketID string) (Ticker, error) { var tick Ticker - return tick, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsGetTicker, &tick) + return tick, e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsGetTicker, &tick) } // GetTrades returns executed trades on the exchange -func (b *BTCMarkets) GetTrades(ctx context.Context, marketID string, before, after, limit int64) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, marketID string, before, after, limit int64) ([]Trade, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -128,7 +128,7 @@ func (b *BTCMarkets) GetTrades(ctx context.Context, marketID string, before, aft if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return trades, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsGetTrades+params.Encode(), + return trades, e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsGetTrades+params.Encode(), &trades) } @@ -137,14 +137,14 @@ func (b *BTCMarkets) GetTrades(ctx context.Context, marketID string, before, aft // 0 - Returns the top bids and ask orders only. // 1 - Returns top 50 bids and asks. // 2 - Returns full orderbook. WARNING: This is cached every 10 seconds. -func (b *BTCMarkets) GetOrderbook(ctx context.Context, marketID string, level int64) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, marketID string, level int64) (*Orderbook, error) { params := url.Values{} if level != 0 { params.Set("level", strconv.FormatInt(level, 10)) } var resp tempOrderbook - if err := b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketOrderBook+params.Encode(), &resp); err != nil { + if err := e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketOrderBook+params.Encode(), &resp); err != nil { return nil, err } @@ -167,7 +167,7 @@ func (b *BTCMarkets) GetOrderbook(ctx context.Context, marketID string, level in } // GetMarketCandles gets candles for specified currency pair -func (b *BTCMarkets) GetMarketCandles(ctx context.Context, marketID, timeWindow string, from, to time.Time, before, after, limit int64) (out []CandleResponse, err error) { +func (e *Exchange) GetMarketCandles(ctx context.Context, marketID, timeWindow string, from, to time.Time, before, after, limit int64) (out []CandleResponse, err error) { if (before > 0) && (after >= 0) { return out, errors.New("BTCMarkets only supports either before or after, not both") } @@ -192,33 +192,33 @@ func (b *BTCMarkets) GetMarketCandles(ctx context.Context, marketID, timeWindow if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return out, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsCandles+params.Encode(), &out) + return out, e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+marketID+btcMarketsCandles+params.Encode(), &out) } // GetTickers gets multiple tickers -func (b *BTCMarkets) GetTickers(ctx context.Context, marketIDs currency.Pairs) ([]Ticker, error) { +func (e *Exchange) GetTickers(ctx context.Context, marketIDs currency.Pairs) ([]Ticker, error) { var tickers []Ticker params := url.Values{} - pFmt, err := b.GetPairFormat(asset.Spot, true) + pFmt, err := e.GetPairFormat(asset.Spot, true) if err != nil { return nil, err } for x := range marketIDs { params.Add("marketId", pFmt.Format(marketIDs[x])) } - return tickers, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+btcMarketsTickers+params.Encode(), + return tickers, e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+btcMarketsTickers+params.Encode(), &tickers) } // GetMultipleOrderbooks gets orderbooks -func (b *BTCMarkets) GetMultipleOrderbooks(ctx context.Context, marketIDs []string) ([]Orderbook, error) { +func (e *Exchange) GetMultipleOrderbooks(ctx context.Context, marketIDs []string) ([]Orderbook, error) { params := url.Values{} for x := range marketIDs { params.Add("marketId", marketIDs[x]) } var resp []tempOrderbook - if err := b.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+btcMarketsMultipleOrderbooks+params.Encode(), &resp); err != nil { + if err := e.SendHTTPRequest(ctx, btcMarketsUnauthPath+"/"+btcMarketsMultipleOrderbooks+params.Encode(), &resp); err != nil { return nil, err } @@ -243,17 +243,17 @@ func (b *BTCMarkets) GetMultipleOrderbooks(ctx context.Context, marketIDs []stri } // GetCurrentServerTime gets time from btcmarkets -func (b *BTCMarkets) GetCurrentServerTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (time.Time, error) { var resp TimeResp - return resp.Time, b.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsGetTime, + return resp.Time, e.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsGetTime, &resp) } // GetAccountBalance returns the full account balance -func (b *BTCMarkets) GetAccountBalance(ctx context.Context) ([]AccountData, error) { +func (e *Exchange) GetAccountBalance(ctx context.Context) ([]AccountData, error) { var resp []AccountData return resp, - b.SendAuthenticatedRequest(ctx, http.MethodGet, + e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsAccountBalance, nil, &resp, @@ -261,9 +261,9 @@ func (b *BTCMarkets) GetAccountBalance(ctx context.Context) ([]AccountData, erro } // GetTradingFees returns trading fees for all pairs based on trading activity -func (b *BTCMarkets) GetTradingFees(ctx context.Context) (TradingFeeResponse, error) { +func (e *Exchange) GetTradingFees(ctx context.Context) (TradingFeeResponse, error) { var resp TradingFeeResponse - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTradingFees, nil, &resp, @@ -271,7 +271,7 @@ func (b *BTCMarkets) GetTradingFees(ctx context.Context) (TradingFeeResponse, er } // GetTradeHistory returns trade history -func (b *BTCMarkets) GetTradeHistory(ctx context.Context, marketID, orderID string, before, after, limit int64) ([]TradeHistoryData, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, marketID, orderID string, before, after, limit int64) ([]TradeHistoryData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -292,7 +292,7 @@ func (b *BTCMarkets) GetTradeHistory(ctx context.Context, marketID, orderID stri if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTradeHistory, params), nil, &resp, @@ -300,9 +300,9 @@ func (b *BTCMarkets) GetTradeHistory(ctx context.Context, marketID, orderID stri } // GetTradeByID returns the singular trade of the ID given -func (b *BTCMarkets) GetTradeByID(ctx context.Context, id string) (TradeHistoryData, error) { +func (e *Exchange) GetTradeByID(ctx context.Context, id string) (TradeHistoryData, error) { var resp TradeHistoryData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTradeHistory+"/"+id, nil, &resp, @@ -311,7 +311,7 @@ func (b *BTCMarkets) GetTradeByID(ctx context.Context, id string) (TradeHistoryD // formatOrderType conforms order type to the exchange acceptable order type // strings -func (b *BTCMarkets) formatOrderType(o order.Type) (string, error) { +func (e *Exchange) formatOrderType(o order.Type) (string, error) { switch o { case order.Limit: return limit, nil @@ -324,25 +324,25 @@ func (b *BTCMarkets) formatOrderType(o order.Type) (string, error) { case order.TakeProfit: return takeProfit, nil default: - return "", fmt.Errorf("%s %s %w", b.Name, o, order.ErrTypeIsInvalid) + return "", fmt.Errorf("%s %s %w", e.Name, o, order.ErrTypeIsInvalid) } } // formatOrderSide conforms order side to the exchange acceptable order side // strings -func (b *BTCMarkets) formatOrderSide(o order.Side) (string, error) { +func (e *Exchange) formatOrderSide(o order.Side) (string, error) { switch o { case order.Ask: return askSide, nil case order.Bid: return bidSide, nil default: - return "", fmt.Errorf("%s %s %w", b.Name, o, order.ErrSideIsInvalid) + return "", fmt.Errorf("%s %s %w", e.Name, o, order.ErrSideIsInvalid) } } // getTimeInForce returns a string depending on the options in order.Submit -func (b *BTCMarkets) getTimeInForce(s *order.Submit) string { +func (e *Exchange) getTimeInForce(s *order.Submit) string { if s.TimeInForce.Is(order.ImmediateOrCancel) || s.TimeInForce.Is(order.FillOrKill) { return s.TimeInForce.String() } @@ -350,7 +350,7 @@ func (b *BTCMarkets) getTimeInForce(s *order.Submit) string { } // NewOrder requests a new order and returns an ID -func (b *BTCMarkets) NewOrder(ctx context.Context, price, amount, triggerPrice, targetAmount float64, marketID, orderType, side, timeInForce, selfTrade, clientOrderID string, postOnly bool) (OrderData, error) { +func (e *Exchange) NewOrder(ctx context.Context, price, amount, triggerPrice, targetAmount float64, marketID, orderType, side, timeInForce, selfTrade, clientOrderID string, postOnly bool) (OrderData, error) { req := make(map[string]any) req["marketId"] = marketID if price != 0 { @@ -378,7 +378,7 @@ func (b *BTCMarkets) NewOrder(ctx context.Context, price, amount, triggerPrice, req["clientOrderID"] = clientOrderID } var resp OrderData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsOrders, req, &resp, @@ -386,7 +386,7 @@ func (b *BTCMarkets) NewOrder(ctx context.Context, price, amount, triggerPrice, } // GetOrders returns current order information on the exchange -func (b *BTCMarkets) GetOrders(ctx context.Context, marketID string, before, after, limit int64, openOnly bool) ([]OrderData, error) { +func (e *Exchange) GetOrders(ctx context.Context, marketID string, before, after, limit int64, openOnly bool) ([]OrderData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -407,7 +407,7 @@ func (b *BTCMarkets) GetOrders(ctx context.Context, marketID string, before, aft if openOnly { params.Set("status", "open") } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsOrders, params), nil, &resp, @@ -415,7 +415,7 @@ func (b *BTCMarkets) GetOrders(ctx context.Context, marketID string, before, aft } // CancelAllOpenOrdersByPairs cancels all open orders unless pairs are specified -func (b *BTCMarkets) CancelAllOpenOrdersByPairs(ctx context.Context, marketIDs []string) ([]CancelOrderResp, error) { +func (e *Exchange) CancelAllOpenOrdersByPairs(ctx context.Context, marketIDs []string) ([]CancelOrderResp, error) { var resp []CancelOrderResp req := make(map[string]any) if len(marketIDs) > 0 { @@ -425,7 +425,7 @@ func (b *BTCMarkets) CancelAllOpenOrdersByPairs(ctx context.Context, marketIDs [ } req["marketId"] = strTemp.String()[:strTemp.Len()-1] } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsOrders, req, &resp, @@ -433,9 +433,9 @@ func (b *BTCMarkets) CancelAllOpenOrdersByPairs(ctx context.Context, marketIDs [ } // FetchOrder finds order based on the provided id -func (b *BTCMarkets) FetchOrder(ctx context.Context, id string) (*OrderData, error) { +func (e *Exchange) FetchOrder(ctx context.Context, id string) (*OrderData, error) { var resp *OrderData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsOrders+"/"+id, nil, &resp, @@ -443,9 +443,9 @@ func (b *BTCMarkets) FetchOrder(ctx context.Context, id string) (*OrderData, err } // RemoveOrder removes a given order -func (b *BTCMarkets) RemoveOrder(ctx context.Context, id string) (CancelOrderResp, error) { +func (e *Exchange) RemoveOrder(ctx context.Context, id string) (CancelOrderResp, error) { var resp CancelOrderResp - return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsOrders+"/"+id, nil, &resp, @@ -453,7 +453,7 @@ func (b *BTCMarkets) RemoveOrder(ctx context.Context, id string) (CancelOrderRes } // ReplaceOrder cancels an order and then places a new order. -func (b *BTCMarkets) ReplaceOrder(ctx context.Context, id, clientOrderID string, price, amount float64) (*OrderData, error) { +func (e *Exchange) ReplaceOrder(ctx context.Context, id, clientOrderID string, price, amount float64) (*OrderData, error) { if price <= 0 { return nil, fmt.Errorf("price %w", errInvalidAmount) } @@ -474,7 +474,7 @@ func (b *BTCMarkets) ReplaceOrder(ctx context.Context, id, clientOrderID string, } var resp *OrderData - return resp, b.SendAuthenticatedRequest(ctx, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodPut, btcMarketsOrders+"/"+id, req, @@ -483,7 +483,7 @@ func (b *BTCMarkets) ReplaceOrder(ctx context.Context, id, clientOrderID string, } // ListWithdrawals lists the withdrawal history -func (b *BTCMarkets) ListWithdrawals(ctx context.Context, before, after, limit int64) ([]TransferData, error) { +func (e *Exchange) ListWithdrawals(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -498,7 +498,7 @@ func (b *BTCMarkets) ListWithdrawals(ctx context.Context, before, after, limit i if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsWithdrawals, params), nil, &resp, @@ -506,12 +506,12 @@ func (b *BTCMarkets) ListWithdrawals(ctx context.Context, before, after, limit i } // GetWithdrawal gets withdrawawl info for a given id -func (b *BTCMarkets) GetWithdrawal(ctx context.Context, id string) (TransferData, error) { +func (e *Exchange) GetWithdrawal(ctx context.Context, id string) (TransferData, error) { var resp TransferData if id == "" { return resp, errors.New("id cannot be an empty string") } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsWithdrawals+"/"+id, nil, &resp, @@ -519,7 +519,7 @@ func (b *BTCMarkets) GetWithdrawal(ctx context.Context, id string) (TransferData } // ListDeposits lists the deposit history -func (b *BTCMarkets) ListDeposits(ctx context.Context, before, after, limit int64) ([]TransferData, error) { +func (e *Exchange) ListDeposits(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -534,7 +534,7 @@ func (b *BTCMarkets) ListDeposits(ctx context.Context, before, after, limit int6 if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsDeposits, params), nil, &resp, @@ -542,9 +542,9 @@ func (b *BTCMarkets) ListDeposits(ctx context.Context, before, after, limit int6 } // GetDeposit gets deposit info for a given ID -func (b *BTCMarkets) GetDeposit(ctx context.Context, id string) (TransferData, error) { +func (e *Exchange) GetDeposit(ctx context.Context, id string) (TransferData, error) { var resp TransferData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsDeposits+"/"+id, nil, &resp, @@ -552,7 +552,7 @@ func (b *BTCMarkets) GetDeposit(ctx context.Context, id string) (TransferData, e } // ListTransfers lists the past asset transfers -func (b *BTCMarkets) ListTransfers(ctx context.Context, before, after, limit int64) ([]TransferData, error) { +func (e *Exchange) ListTransfers(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -567,7 +567,7 @@ func (b *BTCMarkets) ListTransfers(ctx context.Context, before, after, limit int if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTransfers, params), nil, &resp, @@ -575,9 +575,9 @@ func (b *BTCMarkets) ListTransfers(ctx context.Context, before, after, limit int } // GetTransfer gets asset transfer info for a given ID -func (b *BTCMarkets) GetTransfer(ctx context.Context, id string) (TransferData, error) { +func (e *Exchange) GetTransfer(ctx context.Context, id string) (TransferData, error) { var resp TransferData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTransfers+"/"+id, nil, &resp, @@ -585,7 +585,7 @@ func (b *BTCMarkets) GetTransfer(ctx context.Context, id string) (TransferData, } // FetchDepositAddress gets deposit address for the given asset -func (b *BTCMarkets) FetchDepositAddress(ctx context.Context, curr currency.Code, before, after, limit int64) (*DepositAddress, error) { +func (e *Exchange) FetchDepositAddress(ctx context.Context, curr currency.Code, before, after, limit int64) (*DepositAddress, error) { var resp DepositAddress if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") @@ -601,7 +601,7 @@ func (b *BTCMarkets) FetchDepositAddress(ctx context.Context, curr currency.Code if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - if err := b.SendAuthenticatedRequest(ctx, + if err := e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsAddresses, params), nil, @@ -622,16 +622,16 @@ func (b *BTCMarkets) FetchDepositAddress(ctx context.Context, curr currency.Code } // GetWithdrawalFees gets withdrawal fees for all assets -func (b *BTCMarkets) GetWithdrawalFees(ctx context.Context) ([]WithdrawalFeeData, error) { +func (e *Exchange) GetWithdrawalFees(ctx context.Context) ([]WithdrawalFeeData, error) { var resp []WithdrawalFeeData - return resp, b.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsWithdrawalFees, + return resp, e.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsWithdrawalFees, &resp) } // ListAssets lists all available assets -func (b *BTCMarkets) ListAssets(ctx context.Context) ([]AssetData, error) { +func (e *Exchange) ListAssets(ctx context.Context) ([]AssetData, error) { var resp []AssetData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsAssets, nil, &resp, @@ -639,7 +639,7 @@ func (b *BTCMarkets) ListAssets(ctx context.Context) ([]AssetData, error) { } // GetTransactions gets trading fees -func (b *BTCMarkets) GetTransactions(ctx context.Context, assetName string, before, after, limit int64) ([]TransactionData, error) { +func (e *Exchange) GetTransactions(ctx context.Context, assetName string, before, after, limit int64) ([]TransactionData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -657,7 +657,7 @@ func (b *BTCMarkets) GetTransactions(ctx context.Context, assetName string, befo if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTransactions, params), nil, &resp, @@ -665,12 +665,12 @@ func (b *BTCMarkets) GetTransactions(ctx context.Context, assetName string, befo } // CreateNewReport creates a new report -func (b *BTCMarkets) CreateNewReport(ctx context.Context, reportType, format string) (CreateReportResp, error) { +func (e *Exchange) CreateNewReport(ctx context.Context, reportType, format string) (CreateReportResp, error) { var resp CreateReportResp req := make(map[string]any) req["type"] = reportType req["format"] = format - return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsReports, req, &resp, @@ -678,9 +678,9 @@ func (b *BTCMarkets) CreateNewReport(ctx context.Context, reportType, format str } // GetReport finds details bout a past report -func (b *BTCMarkets) GetReport(ctx context.Context, reportID string) (ReportData, error) { +func (e *Exchange) GetReport(ctx context.Context, reportID string) (ReportData, error) { var resp ReportData - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsReports+"/"+reportID, nil, &resp, @@ -688,7 +688,7 @@ func (b *BTCMarkets) GetReport(ctx context.Context, reportID string) (ReportData } // RequestWithdraw requests withdrawals -func (b *BTCMarkets) RequestWithdraw(ctx context.Context, assetName string, amount float64, +func (e *Exchange) RequestWithdraw(ctx context.Context, assetName string, amount float64, toAddress, accountName, accountNumber, bsbNumber, bankName string, ) (TransferData, error) { var resp TransferData @@ -711,7 +711,7 @@ func (b *BTCMarkets) RequestWithdraw(ctx context.Context, assetName string, amou req["bankName"] = bankName } } - return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsWithdrawals, req, &resp, @@ -719,7 +719,7 @@ func (b *BTCMarkets) RequestWithdraw(ctx context.Context, assetName string, amou } // BatchPlaceCancelOrders places and cancels batch orders -func (b *BTCMarkets) BatchPlaceCancelOrders(ctx context.Context, cancelOrders []CancelBatch, placeOrders []PlaceBatch) (*BatchPlaceCancelResponse, error) { +func (e *Exchange) BatchPlaceCancelOrders(ctx context.Context, cancelOrders []CancelBatch, placeOrders []PlaceBatch) (*BatchPlaceCancelResponse, error) { numActions := len(cancelOrders) + len(placeOrders) if numActions > 4 { return nil, errors.New("BTCMarkets can only handle 4 orders at a time") @@ -736,7 +736,7 @@ func (b *BTCMarkets) BatchPlaceCancelOrders(ctx context.Context, cancelOrders [] orderRequests[y] = PlaceOrderMethod{PlaceOrder: placeOrders[y]} } var resp BatchPlaceCancelResponse - return &resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, + return &resp, e.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsBatchOrders, orderRequests, &resp, @@ -744,13 +744,13 @@ func (b *BTCMarkets) BatchPlaceCancelOrders(ctx context.Context, cancelOrders [] } // GetBatchTrades gets batch trades -func (b *BTCMarkets) GetBatchTrades(ctx context.Context, ids []string) (BatchTradeResponse, error) { +func (e *Exchange) GetBatchTrades(ctx context.Context, ids []string) (BatchTradeResponse, error) { var resp BatchTradeResponse if len(ids) > 50 { return resp, errors.New("batchtrades can only handle 50 ids at a time") } marketIDs := strings.Join(ids, ",") - return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsBatchOrders+"/"+marketIDs, nil, &resp, @@ -758,10 +758,10 @@ func (b *BTCMarkets) GetBatchTrades(ctx context.Context, ids []string) (BatchTra } // CancelBatch cancels given ids -func (b *BTCMarkets) CancelBatch(ctx context.Context, ids []string) (BatchCancelResponse, error) { +func (e *Exchange) CancelBatch(ctx context.Context, ids []string) (BatchCancelResponse, error) { var resp BatchCancelResponse marketIDs := strings.Join(ids, ",") - return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, + return resp, e.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsBatchOrders+"/"+marketIDs, nil, &resp, @@ -769,23 +769,23 @@ func (b *BTCMarkets) CancelBatch(ctx context.Context, ids []string) (BatchCancel } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *BTCMarkets) SendHTTPRequest(ctx context.Context, path string, result any) error { +func (e *Exchange) SendHTTPRequest(ctx context.Context, path string, result any) error { item := &request.Item{ Method: http.MethodGet, Path: path, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedRequest sends an authenticated HTTP request -func (b *BTCMarkets) SendAuthenticatedRequest(ctx context.Context, method, path string, data, result any, f request.EndpointLimit) (err error) { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedRequest(ctx context.Context, method, path string, data, result any, f request.EndpointLimit) (err error) { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -832,22 +832,22 @@ func (b *BTCMarkets) SendAuthenticatedRequest(ctx context.Context, method, path Headers: headers, Body: body, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - return b.SendPayload(ctx, f, newRequest, request.AuthenticatedRequest) + return e.SendPayload(ctx, f, newRequest, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *BTCMarkets) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - temp, err := b.GetTradingFees(ctx) + temp, err := e.GetTradingFees(ctx) if err != nil { return fee, err } @@ -860,7 +860,7 @@ func (b *BTCMarkets) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder } } case exchange.CryptocurrencyWithdrawalFee: - temp, err := b.GetWithdrawalFees(ctx) + temp, err := e.GetWithdrawalFees(ctx) if err != nil { return fee, err } diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index 8db768b4183..7df1ddd7e25 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -21,7 +21,7 @@ import ( testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions" ) -var b = &BTCMarkets{} +var e *Exchange // Please supply your own keys here to do better tests const ( @@ -33,15 +33,15 @@ const ( var spotTestPair = currency.NewPair(currency.BTC, currency.AUD).Format(currency.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter}) func TestMain(m *testing.M) { - b = new(BTCMarkets) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("BTCMarkets Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.API.AuthenticatedWebsocketSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -49,7 +49,7 @@ func TestMain(m *testing.M) { func TestGetMarkets(t *testing.T) { t.Parallel() - _, err := b.GetMarkets(t.Context()) + _, err := e.GetMarkets(t.Context()) if err != nil { t.Error("GetTicker() error", err) } @@ -57,51 +57,51 @@ func TestGetMarkets(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(t.Context(), spotTestPair.String()) + _, err := e.GetTicker(t.Context(), spotTestPair.String()) assert.NoError(t, err, "GetTicker should not error") } func TestGetTrades(t *testing.T) { t.Parallel() - _, err := b.GetTrades(t.Context(), spotTestPair.String(), 0, 0, 5) + _, err := e.GetTrades(t.Context(), spotTestPair.String(), 0, 0, 5) assert.NoError(t, err, "GetTrades should not error") } func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(t.Context(), spotTestPair.String(), 2) + _, err := e.GetOrderbook(t.Context(), spotTestPair.String(), 2) assert.NoError(t, err, "GetOrderbook should not error") } func TestGetMarketCandles(t *testing.T) { t.Parallel() - _, err := b.GetMarketCandles(t.Context(), spotTestPair.String(), "1h", time.Now().UTC().Add(-time.Hour*24), time.Now().UTC(), -1, -1, -1) + _, err := e.GetMarketCandles(t.Context(), spotTestPair.String(), "1h", time.Now().UTC().Add(-time.Hour*24), time.Now().UTC(), -1, -1, -1) assert.NoError(t, err, "GetMarketCandles should not error") } func TestGetTickers(t *testing.T) { t.Parallel() pairs := currency.Pairs{spotTestPair, currency.NewPair(currency.LTC, currency.AUD)} - _, err := b.GetTickers(t.Context(), pairs) + _, err := e.GetTickers(t.Context(), pairs) assert.NoError(t, err, "GetTickers should not error") } func TestGetMultipleOrderbooks(t *testing.T) { t.Parallel() marketIDs := []string{spotTestPair.String(), "LTC-AUD", "ETH-AUD"} - _, err := b.GetMultipleOrderbooks(t.Context(), marketIDs) + _, err := e.GetMultipleOrderbooks(t.Context(), marketIDs) assert.NoError(t, err, "GetMultipleOrderbooks should not error") } func TestGetCurrentServerTime(t *testing.T) { t.Parallel() - _, err := b.GetCurrentServerTime(t.Context()) + _, err := e.GetCurrentServerTime(t.Context()) assert.NoError(t, err, "GetCurrentServerTime should not error") } func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := b.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) if st.IsZero() { @@ -111,8 +111,8 @@ func TestWrapperGetServerTime(t *testing.T) { func TestGetAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAccountBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountBalance(t.Context()) if err != nil { t.Error(err) } @@ -120,8 +120,8 @@ func TestGetAccountBalance(t *testing.T) { func TestGetTradingFees(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetTradingFees(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTradingFees(t.Context()) if err != nil { t.Error(err) } @@ -129,15 +129,15 @@ func TestGetTradingFees(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetTradeHistory(t.Context(), spotTestPair.String(), "", -1, -1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTradeHistory(t.Context(), spotTestPair.String(), "", -1, -1, 1) assert.NoError(t, err, "GetTradeHistory should not error") } func TestGetTradeByID(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetTradeByID(t.Context(), "4712043732") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTradeByID(t.Context(), "4712043732") if err != nil { t.Error(err) } @@ -145,8 +145,8 @@ func TestGetTradeByID(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - _, err := b.SubmitOrder(t.Context(), &order.Submit{ - Exchange: b.Name, + _, err := e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Price: 100, Amount: 1, Type: order.TrailingStop, @@ -157,8 +157,8 @@ func TestSubmitOrder(t *testing.T) { }) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = b.SubmitOrder(t.Context(), &order.Submit{ - Exchange: b.Name, + _, err = e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Price: 100, Amount: 1, Type: order.Limit, @@ -169,10 +169,10 @@ func TestSubmitOrder(t *testing.T) { }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = b.SubmitOrder(t.Context(), &order.Submit{ - Exchange: b.Name, + _, err = e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Price: 100, Amount: 1, Type: order.Limit, @@ -188,38 +188,38 @@ func TestSubmitOrder(t *testing.T) { func TestNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.NewOrder(t.Context(), 100, 1, 0, 0, spotTestPair.String(), limit, bidSide, "", "", "", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.NewOrder(t.Context(), 100, 1, 0, 0, spotTestPair.String(), limit, bidSide, "", "", "", true) assert.NoError(t, err, "NewOrder should not error") } func TestGetOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOrders(t.Context(), "", -1, -1, 2, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrders(t.Context(), "", -1, -1, 2, false) assert.NoError(t, err, "GetOrders should not error") - _, err = b.GetOrders(t.Context(), spotTestPair.String(), -1, -1, -1, true) + _, err = e.GetOrders(t.Context(), spotTestPair.String(), -1, -1, -1, true) assert.NoError(t, err, "GetOrders should not error") } func TestCancelOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) pairs := []string{spotTestPair.String(), spotTestPair.String()} - _, err := b.CancelAllOpenOrdersByPairs(t.Context(), pairs) + _, err := e.CancelAllOpenOrdersByPairs(t.Context(), pairs) assert.NoError(t, err, "CancelAllOpenOrdersByPairs should not error") } func TestFetchOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.FetchOrder(t.Context(), "4477045999") + _, err := e.FetchOrder(t.Context(), "4477045999") if err != nil { t.Error(err) } - _, err = b.FetchOrder(t.Context(), "696969") + _, err = e.FetchOrder(t.Context(), "696969") if err == nil { t.Error(err) } @@ -227,9 +227,9 @@ func TestFetchOrder(t *testing.T) { func TestRemoveOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.RemoveOrder(t.Context(), "") + _, err := e.RemoveOrder(t.Context(), "") if err != nil { t.Error(err) } @@ -237,9 +237,9 @@ func TestRemoveOrder(t *testing.T) { func TestListWithdrawals(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.ListWithdrawals(t.Context(), -1, -1, -1) + _, err := e.ListWithdrawals(t.Context(), -1, -1, -1) if err != nil { t.Error(err) } @@ -247,9 +247,9 @@ func TestListWithdrawals(t *testing.T) { func TestGetWithdrawal(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetWithdrawal(t.Context(), "4477381751") + _, err := e.GetWithdrawal(t.Context(), "4477381751") if err != nil { t.Error(err) } @@ -257,9 +257,9 @@ func TestGetWithdrawal(t *testing.T) { func TestListDeposits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.ListDeposits(t.Context(), -1, -1, -1) + _, err := e.ListDeposits(t.Context(), -1, -1, -1) if err != nil { t.Error(err) } @@ -267,9 +267,9 @@ func TestListDeposits(t *testing.T) { func TestGetDeposit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetDeposit(t.Context(), "4476769607") + _, err := e.GetDeposit(t.Context(), "4476769607") if err != nil { t.Error(err) } @@ -277,9 +277,9 @@ func TestGetDeposit(t *testing.T) { func TestListTransfers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.ListTransfers(t.Context(), -1, -1, -1) + _, err := e.ListTransfers(t.Context(), -1, -1, -1) if err != nil { t.Error(err) } @@ -287,13 +287,13 @@ func TestListTransfers(t *testing.T) { func TestGetTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetTransfer(t.Context(), "4476769607") + _, err := e.GetTransfer(t.Context(), "4476769607") if err != nil { t.Error(err) } - _, err = b.GetTransfer(t.Context(), "6969696") + _, err = e.GetTransfer(t.Context(), "6969696") if err == nil { t.Error("expected an error due to invalid transferID") } @@ -301,13 +301,13 @@ func TestGetTransfer(t *testing.T) { func TestFetchDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.FetchDepositAddress(t.Context(), currency.XRP, -1, -1, -1) + _, err := e.FetchDepositAddress(t.Context(), currency.XRP, -1, -1, -1) if err != nil { t.Error(err) } - _, err = b.FetchDepositAddress(t.Context(), currency.NewCode("MOOCOW"), -1, -1, -1) + _, err = e.FetchDepositAddress(t.Context(), currency.NewCode("MOOCOW"), -1, -1, -1) if err != nil { t.Error("expected an error due to invalid assetID") } @@ -315,7 +315,7 @@ func TestFetchDepositAddress(t *testing.T) { func TestGetWithdrawalFees(t *testing.T) { t.Parallel() - _, err := b.GetWithdrawalFees(t.Context()) + _, err := e.GetWithdrawalFees(t.Context()) if err != nil { t.Error(err) } @@ -323,9 +323,9 @@ func TestGetWithdrawalFees(t *testing.T) { func TestListAssets(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.ListAssets(t.Context()) + _, err := e.ListAssets(t.Context()) if err != nil { t.Error(err) } @@ -333,9 +333,9 @@ func TestListAssets(t *testing.T) { func TestGetTransactions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetTransactions(t.Context(), "", -1, -1, -1) + _, err := e.GetTransactions(t.Context(), "", -1, -1, -1) if err != nil { t.Error(err) } @@ -343,9 +343,9 @@ func TestGetTransactions(t *testing.T) { func TestCreateNewReport(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.CreateNewReport(t.Context(), "TransactionReport", "json") + _, err := e.CreateNewReport(t.Context(), "TransactionReport", "json") if err != nil { t.Error(err) } @@ -353,9 +353,9 @@ func TestCreateNewReport(t *testing.T) { func TestGetReport(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetReport(t.Context(), "1kv38epne5v7lek9f18m60idg6") + _, err := e.GetReport(t.Context(), "1kv38epne5v7lek9f18m60idg6") if err != nil { t.Error(err) } @@ -363,9 +363,9 @@ func TestGetReport(t *testing.T) { func TestRequestWithdaw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := b.RequestWithdraw(t.Context(), "BTC", 1, "sdjflajdslfjld", "", "", "", "") + _, err := e.RequestWithdraw(t.Context(), "BTC", 1, "sdjflajdslfjld", "", "", "", "") if err == nil { t.Error("expected an error due to invalid toAddress") } @@ -373,7 +373,7 @@ func TestRequestWithdaw(t *testing.T) { func TestBatchPlaceCancelOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) var temp []PlaceBatch o := PlaceBatch{ @@ -383,7 +383,7 @@ func TestBatchPlaceCancelOrders(t *testing.T) { OrderType: order.Limit.String(), Side: order.Bid.String(), } - _, err := b.BatchPlaceCancelOrders(t.Context(), nil, append(temp, o)) + _, err := e.BatchPlaceCancelOrders(t.Context(), nil, append(temp, o)) if err != nil { t.Error(err) } @@ -391,10 +391,10 @@ func TestBatchPlaceCancelOrders(t *testing.T) { func TestGetBatchTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) temp := []string{"4477045999", "4477381751", "4476769607"} - _, err := b.GetBatchTrades(t.Context(), temp) + _, err := e.GetBatchTrades(t.Context(), temp) if err != nil { t.Error(err) } @@ -402,10 +402,10 @@ func TestGetBatchTrades(t *testing.T) { func TestCancelBatch(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) temp := []string{"4477045999", "4477381751", "4477381751"} - _, err := b.CancelBatch(t.Context(), temp) + _, err := e.CancelBatch(t.Context(), temp) if err != nil { t.Error(err) } @@ -413,9 +413,9 @@ func TestCancelBatch(t *testing.T) { func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + _, err := e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Side: order.Buy, AssetType: asset.Spot, Type: order.AnyType, @@ -428,7 +428,7 @@ func TestGetOrderHistory(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-") - _, err := b.UpdateOrderbook(t.Context(), cp, asset.Spot) + _, err := e.UpdateOrderbook(t.Context(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -437,7 +437,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-") - _, err := b.UpdateTicker(t.Context(), cp, asset.Spot) + _, err := e.UpdateTicker(t.Context(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -445,7 +445,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) if err != nil { t.Error(err) } @@ -453,9 +453,9 @@ func TestUpdateTickers(t *testing.T) { func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.GetActiveOrders(t.Context(), + _, err := e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{AssetType: asset.Spot, Side: order.AnySide, Type: order.AnyType}) if err != nil { t.Fatal(err) @@ -471,7 +471,7 @@ func TestWsTicker(t *testing.T) { "volume24h": "299.12936654", "messageType": "tick" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -480,19 +480,19 @@ func TestWsTicker(t *testing.T) { func TestWSTrade(t *testing.T) { t.Parallel() - b := new(BTCMarkets) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - fErrs := testexch.FixtureToDataHandlerWithErrors(t, "testdata/wsAllTrades.json", b.wsHandleData) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + fErrs := testexch.FixtureToDataHandlerWithErrors(t, "testdata/wsAllTrades.json", e.wsHandleData) require.Equal(t, 2, len(fErrs), "Must get correct number of errors from wsHandleData") assert.ErrorIs(t, fErrs[0].Err, order.ErrSideIsInvalid, "Side.UnmarshalJSON errors should propagate correctly") assert.ErrorContains(t, fErrs[0].Err, "WRONG", "Side.UnmarshalJSON errors should propagate correctly") assert.ErrorIs(t, fErrs[1].Err, order.ErrSideIsInvalid, "wsHandleData errors should propagate correctly") assert.ErrorContains(t, fErrs[1].Err, "ANY", "wsHandleData errors should propagate correctly") - close(b.Websocket.DataHandler) + close(e.Websocket.DataHandler) exp := []trade.Data{ { - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: currency.NewPairWithDelimiter("BTC", "AUD", currency.DashDelimiter), Timestamp: time.Date(2025, 3, 13, 8, 27, 55, 691000000, time.UTC), Price: 131200.34, @@ -502,7 +502,7 @@ func TestWSTrade(t *testing.T) { AssetType: asset.Spot, }, { - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: currency.NewPairWithDelimiter("BTC", "AUD", currency.DashDelimiter), Timestamp: time.Date(2025, 3, 13, 8, 28, 2, 273000000, time.UTC), Price: 131065.01, @@ -512,12 +512,12 @@ func TestWSTrade(t *testing.T) { AssetType: asset.Spot, }, } - require.Len(t, b.Websocket.DataHandler, 2, "Must see correct number of trades") + require.Len(t, e.Websocket.DataHandler, 2, "Must see correct number of trades") - for resp := range b.Websocket.DataHandler { + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 1 - len(b.Websocket.DataHandler) + i := 1 - len(e.Websocket.DataHandler) require.Equalf(t, exp[i], v, "Trade[%d] must be correct", i) case error: t.Error(v) @@ -538,7 +538,7 @@ func TestWsFundChange(t *testing.T) { "fee": "0", "messageType": "fundChange" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -560,7 +560,7 @@ func TestWsOrderbookUpdate(t *testing.T) { [ "101", "6.32", 2 ] ], "messageType": "orderbookUpdate" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -573,7 +573,7 @@ func TestWsOrderbookUpdate(t *testing.T) { "messageType": "orderbookUpdate", "checksum": "2513007604" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -585,7 +585,7 @@ func TestWsHeartbeats(t *testing.T) { "code": 3, "message": "invalid channel names" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err == nil { t.Error("expected error") } @@ -595,7 +595,7 @@ func TestWsHeartbeats(t *testing.T) { "code": 3, "message": "invalid marketIds" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err == nil { t.Error("expected error") } @@ -605,7 +605,7 @@ func TestWsHeartbeats(t *testing.T) { "code": 1, "message": "authentication failed. invalid key" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err == nil { t.Error("expected error") } @@ -624,7 +624,7 @@ func TestWsOrders(t *testing.T) { "timestamp": "2019-04-08T20:41:19.339Z", "messageType": "orderChange" }`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -647,7 +647,7 @@ func TestWsOrders(t *testing.T) { "timestamp": "2019-04-08T20:50:39.658Z", "messageType": "orderChange" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -664,7 +664,7 @@ func TestWsOrders(t *testing.T) { "timestamp": "2019-04-08T20:41:41.857Z", "messageType": "orderChange" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -687,7 +687,7 @@ func TestWsOrders(t *testing.T) { "timestamp": "2019-04-08T20:41:41.857Z", "messageType": "orderChange" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -704,7 +704,7 @@ func TestWsOrders(t *testing.T) { "timestamp": "2019-04-08T20:41:41.857Z", "messageType": "orderChange" }`) - err = b.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -712,13 +712,13 @@ func TestWsOrders(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() - _, err := b.GetHistoricCandles(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().Add(-time.Hour*24), time.Now()) + _, err := e.GetHistoricCandles(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().Add(-time.Hour*24), time.Now()) assert.NoError(t, err, "GetHistoricCandles should not error") } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - _, err := b.GetHistoricCandlesExtended(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().AddDate(0, 0, -1), time.Now()) + _, err := e.GetHistoricCandlesExtended(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().AddDate(0, 0, -1), time.Now()) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") } @@ -739,20 +739,20 @@ func TestFormatExchangeKlineInterval(t *testing.T) { } { t.Run(tc.interval.String(), func(t *testing.T) { t.Parallel() - assert.Equal(t, tc.output, b.FormatExchangeKlineInterval(tc.interval)) + assert.Equal(t, tc.output, e.FormatExchangeKlineInterval(tc.interval)) }) } } func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := b.GetRecentTrades(t.Context(), spotTestPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), spotTestPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades should not error") } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricTrades(t.Context(), spotTestPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), spotTestPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } @@ -800,38 +800,38 @@ func TestTrim(t *testing.T) { func TestFormatOrderType(t *testing.T) { t.Parallel() - _, err := b.formatOrderType(0) + _, err := e.formatOrderType(0) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - r, err := b.formatOrderType(order.Limit) + r, err := e.formatOrderType(order.Limit) require.NoError(t, err) if r != limit { t.Fatal("unexpected value") } - r, err = b.formatOrderType(order.Market) + r, err = e.formatOrderType(order.Market) require.NoError(t, err) if r != market { t.Fatal("unexpected value") } - r, err = b.formatOrderType(order.StopLimit) + r, err = e.formatOrderType(order.StopLimit) require.NoError(t, err) if r != stopLimit { t.Fatal("unexpected value") } - r, err = b.formatOrderType(order.Stop) + r, err = e.formatOrderType(order.Stop) require.NoError(t, err) if r != stop { t.Fatal("unexpected value") } - r, err = b.formatOrderType(order.TakeProfit) + r, err = e.formatOrderType(order.TakeProfit) require.NoError(t, err) if r != takeProfit { @@ -841,17 +841,17 @@ func TestFormatOrderType(t *testing.T) { func TestFormatOrderSide(t *testing.T) { t.Parallel() - _, err := b.formatOrderSide(255) + _, err := e.formatOrderSide(255) require.ErrorIs(t, err, order.ErrSideIsInvalid) - f, err := b.formatOrderSide(order.Bid) + f, err := e.formatOrderSide(order.Bid) require.NoError(t, err) if f != bidSide { t.Fatal("unexpected value") } - f, err = b.formatOrderSide(order.Ask) + f, err = e.formatOrderSide(order.Ask) require.NoError(t, err) if f != askSide { @@ -861,41 +861,41 @@ func TestFormatOrderSide(t *testing.T) { func TestGetTimeInForce(t *testing.T) { t.Parallel() - f := b.getTimeInForce(&order.Submit{}) + f := e.getTimeInForce(&order.Submit{}) require.Empty(t, f) - f = b.getTimeInForce(&order.Submit{TimeInForce: order.ImmediateOrCancel}) + f = e.getTimeInForce(&order.Submit{TimeInForce: order.ImmediateOrCancel}) require.Equal(t, "IOC", f) - f = b.getTimeInForce(&order.Submit{TimeInForce: order.FillOrKill}) + f = e.getTimeInForce(&order.Submit{TimeInForce: order.FillOrKill}) assert.Equal(t, "FOK", f) } func TestReplaceOrder(t *testing.T) { t.Parallel() - _, err := b.ReplaceOrder(t.Context(), "", "bro", 0, 0) + _, err := e.ReplaceOrder(t.Context(), "", "bro", 0, 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = b.ReplaceOrder(t.Context(), "", "bro", 1, 0) + _, err = e.ReplaceOrder(t.Context(), "", "bro", 1, 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = b.ReplaceOrder(t.Context(), "", "bro", 1, 1) + _, err = e.ReplaceOrder(t.Context(), "", "bro", 1, 1) require.ErrorIs(t, err, errIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = b.ReplaceOrder(t.Context(), "8207096301", "bruh", 100000, 0.001) + _, err = e.ReplaceOrder(t.Context(), "8207096301", "bruh", 100000, 0.001) require.NoError(t, err) } func TestWrapperModifyOrder(t *testing.T) { t.Parallel() - _, err := b.ModifyOrder(t.Context(), &order.Modify{}) + _, err := e.ModifyOrder(t.Context(), &order.Modify{}) require.ErrorIs(t, err, order.ErrPairIsEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - mo, err := b.ModifyOrder(t.Context(), &order.Modify{ + mo, err := e.ModifyOrder(t.Context(), &order.Modify{ Pair: currency.NewPair(currency.BTC, currency.AUD), AssetType: asset.Spot, Price: 100000, @@ -912,13 +912,13 @@ func TestWrapperModifyOrder(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits(t.Context(), asset.Empty) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Empty) require.ErrorIs(t, err, asset.ErrNotSupported) - err = b.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) require.NoError(t, err) - lim, err := b.ExecutionLimits.GetOrderExecutionLimits(asset.Spot, currency.NewPair(currency.BTC, currency.AUD)) + lim, err := e.ExecutionLimits.GetOrderExecutionLimits(asset.Spot, currency.NewPair(currency.BTC, currency.AUD)) require.NoError(t, err) if lim == (order.MinMaxLevel{}) { @@ -928,8 +928,8 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) if err != nil { t.Error(err) } @@ -937,8 +937,8 @@ func TestGetWithdrawalsHistory(t *testing.T) { func TestCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1234", AssetType: asset.Spot, @@ -952,12 +952,12 @@ func TestCancelBatchOrders(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -965,19 +965,19 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(BTCMarkets) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") p := currency.Pairs{currency.NewPairWithDelimiter("BTC", "USD", "_"), currency.NewPairWithDelimiter("ETH", "BTC", "_")} - require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, false)) - require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, true)) - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - require.True(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") - subs, err := b.generateSubscriptions() + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, false)) + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, true)) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + require.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") - pairs, err := b.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) require.NoError(t, err, "GetEnabledPairs must not error") exp := subscription.List{} - for _, baseSub := range b.Features.Subscriptions { + for _, baseSub := range e.Features.Subscriptions { s := baseSub.Clone() if !s.Authenticated && s.Channel != subscription.HeartbeatChannel { s.Pairs = pairs diff --git a/exchanges/btcmarkets/btcmarkets_websocket.go b/exchanges/btcmarkets/btcmarkets_websocket.go index 37363048670..8be7f61702d 100644 --- a/exchanges/btcmarkets/btcmarkets_websocket.go +++ b/exchanges/btcmarkets/btcmarkets_websocket.go @@ -50,37 +50,37 @@ var subscriptionNames = map[string]string{ } // WsConnect connects to a websocket feed -func (b *BTCMarkets) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !b.Websocket.IsEnabled() || !b.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - if b.Verbose { - log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", b.Name) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", e.Name) } - b.Websocket.Wg.Add(1) - go b.wsReadData(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) return nil } // wsReadData receives and passes on websocket messages for processing -func (b *BTCMarkets) wsReadData(ctx context.Context) { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := b.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } @@ -101,7 +101,7 @@ func (w *WebsocketOrderbook) UnmarshalJSON(data []byte) error { return nil } -func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, respRaw []byte) error { var wsResponse WsMessageType err := json.Unmarshal(respRaw, &wsResponse) if err != nil { @@ -109,8 +109,8 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } switch wsResponse.MessageType { case heartbeat: - if b.Verbose { - log.Debugf(log.ExchangeSys, "%v - Websocket heartbeat received %s", b.Name, respRaw) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%v - Websocket heartbeat received %s", e.Name, respRaw) } case wsOrderbookUpdate: var ob WsOrderbook @@ -120,18 +120,18 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } if ob.Snapshot { - err = b.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Pair: ob.Currency, Bids: orderbook.Levels(ob.Bids), Asks: orderbook.Levels(ob.Asks), LastUpdated: ob.Timestamp, LastUpdateID: ob.SnapshotID, Asset: asset.Spot, - Exchange: b.Name, - ValidateOrderbook: b.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, }) } else { - err = b.Websocket.Orderbook.Update(&orderbook.Update{ + err = e.Websocket.Orderbook.Update(&orderbook.Update{ UpdateTime: ob.Timestamp, UpdateID: ob.SnapshotID, Asset: asset.Spot, @@ -145,7 +145,7 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } if err != nil { if errors.Is(err, orderbook.ErrOrderbookInvalid) { - err2 := b.ReSubscribeSpecificOrderbook(ob.Currency) + err2 := e.ReSubscribeSpecificOrderbook(ob.Currency) if err2 != nil { return err2 } @@ -154,8 +154,8 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } return nil case tradeEndPoint: - tradeFeed := b.IsTradeFeedEnabled() - saveTradeData := b.IsSaveTradeDataEnabled() + tradeFeed := e.IsTradeFeedEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() if !saveTradeData && !tradeFeed { return nil } @@ -180,7 +180,7 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { Timestamp: t.Timestamp, CurrencyPair: t.MarketID, AssetType: asset.Spot, - Exchange: b.Name, + Exchange: e.Name, Price: t.Price, Amount: t.Volume, Side: side, @@ -188,7 +188,7 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } if tradeFeed { - b.Websocket.DataHandler <- td + e.Websocket.DataHandler <- td } if saveTradeData { return trade.AddTradesToBuffer(td) @@ -200,8 +200,8 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { return err } - b.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: b.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Volume: tick.Volume, High: tick.High24, Low: tick.Low24h, @@ -218,7 +218,7 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { if err != nil { return err } - b.Websocket.DataHandler <- transferData + e.Websocket.DataHandler <- transferData case orderChange: var orderData WsOrderChange err := json.Unmarshal(respRaw, &orderData) @@ -238,7 +238,7 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { Price: orderData.Trades[x].Price, Amount: orderData.Trades[x].Volume, Fee: orderData.Trades[x].Fee, - Exchange: b.Name, + Exchange: e.Name, TID: strconv.FormatInt(orderData.Trades[x].TradeID, 10), IsMaker: isMaker, }) @@ -247,33 +247,33 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { } oType, err := order.StringToOrderType(orderData.OrderType) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } oSide, err := order.StringToOrderSide(orderData.Side) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } oStatus, err := order.StringToOrderStatus(orderData.Status) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } clientID := "" - if creds, err := b.GetCredentials(ctx); err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + if creds, err := e.GetCredentials(ctx); err != nil { + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -281,11 +281,11 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { clientID = creds.ClientID } - b.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: price, Amount: originalAmount, RemainingAmount: orderData.OpenVolume, - Exchange: b.Name, + Exchange: e.Name, OrderID: orderID, ClientID: clientID, Type: oType, @@ -302,25 +302,25 @@ func (b *BTCMarkets) wsHandleData(ctx context.Context, respRaw []byte) error { if err != nil { return err } - return fmt.Errorf("%v websocket error. Code: %v Message: %v", b.Name, wsErr.Code, wsErr.Message) + return fmt.Errorf("%v websocket error. Code: %v Message: %v", e.Name, wsErr.Code, wsErr.Message) default: - b.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: b.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } return nil } -func (b *BTCMarkets) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *BTCMarkets) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{"channelName": channelName}).Parse(subTplText) } // Subscribe sends a websocket message to receive data from the channel -func (b *BTCMarkets) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() baseReq := &WsSubscribe{ MessageType: subscribe, @@ -328,7 +328,7 @@ func (b *BTCMarkets) Subscribe(subs subscription.List) error { var errs error if authed := subs.Private(); len(authed) > 0 { - if err := b.signWsReq(ctx, baseReq); err != nil { + if err := e.signWsReq(ctx, baseReq); err != nil { errs = err for _, s := range authed { errs = common.AppendError(errs, fmt.Errorf("%w: %s", request.ErrAuthRequestFailed, s)) @@ -338,7 +338,7 @@ func (b *BTCMarkets) Subscribe(subs subscription.List) error { } for _, batch := range subs.GroupByPairs() { - if baseReq.MessageType == subscribe && len(b.Websocket.GetSubscriptions()) != 0 { + if baseReq.MessageType == subscribe && len(e.Websocket.GetSubscriptions()) != 0 { baseReq.MessageType = addSubscription // After first *successful* subscription API requires addSubscription baseReq.ClientType = clientType // Note: Only addSubscription requires/accepts clientType } @@ -351,9 +351,9 @@ func (b *BTCMarkets) Subscribe(subs subscription.List) error { r.Channels[i] = s.QualifiedChannel } - err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) if err == nil { - err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, batch...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, batch...) } if err != nil { errs = common.AppendError(errs, err) @@ -363,8 +363,8 @@ func (b *BTCMarkets) Subscribe(subs subscription.List) error { return errs } -func (b *BTCMarkets) signWsReq(ctx context.Context, r *WsSubscribe) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) signWsReq(ctx context.Context, r *WsSubscribe) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -380,7 +380,7 @@ func (b *BTCMarkets) signWsReq(ctx context.Context, r *WsSubscribe) error { } // Unsubscribe sends a websocket message to manage and remove a subscription. -func (b *BTCMarkets) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() var errs error for _, s := range subs { @@ -391,9 +391,9 @@ func (b *BTCMarkets) Unsubscribe(subs subscription.List) error { MarketIDs: s.Pairs.Strings(), } - err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) if err == nil { - err = b.Websocket.RemoveSubscriptions(b.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } if err != nil { errs = common.AppendError(errs, err) @@ -404,18 +404,18 @@ func (b *BTCMarkets) Unsubscribe(subs subscription.List) error { // ReSubscribeSpecificOrderbook removes the subscription and the subscribes // again to fetch a new snapshot in the event of a de-sync event. -func (b *BTCMarkets) ReSubscribeSpecificOrderbook(pair currency.Pair) error { +func (e *Exchange) ReSubscribeSpecificOrderbook(pair currency.Pair) error { sub := subscription.List{{ Channel: wsOrderbookUpdate, Pairs: currency.Pairs{pair}, Asset: asset.Spot, }} - if err := b.Unsubscribe(sub); err != nil && !errors.Is(err, subscription.ErrNotFound) { + if err := e.Unsubscribe(sub); err != nil && !errors.Is(err, subscription.ErrNotFound) { // ErrNotFound is okay, because we might be re-subscribing a single pair from a larger list // BTC-Market handles unsub/sub of one pair gracefully and the other pairs are unaffected return err } - return b.Subscribe(sub) + return e.Subscribe(sub) } // orderbookChecksum calculates a checksum for the orderbook liquidity diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index a7dd46d7c02..79506f9a5e0 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -32,21 +32,21 @@ import ( ) // SetDefaults sets basic defaults -func (b *BTCMarkets) SetDefaults() { - b.Name = "BTC Markets" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true - b.API.CredentialsValidator.RequiresBase64DecodeSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "BTC Markets" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresBase64DecodeSecret = true requestFmt := ¤cy.PairFormat{Delimiter: currency.DashDelimiter, Uppercase: true} configFmt := ¤cy.PairFormat{Delimiter: currency.DashDelimiter, Uppercase: true} - err := b.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -111,55 +111,55 @@ func (b *BTCMarkets) SetDefaults() { Subscriptions: defaultSubscriptions.Clone(), } - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: btcMarketsAPIURL, exchange.WebsocketSpot: btcMarketsWSURL, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in an exchange configuration and sets all parameters -func (b *BTCMarkets) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsURL, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: btcMarketsWSURL, RunningURL: wsURL, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, }, @@ -168,18 +168,18 @@ func (b *BTCMarkets) Setup(exch *config.Exchange) error { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *BTCMarkets) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { if a != asset.Spot { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - markets, err := b.GetMarkets(ctx) + markets, err := e.GetMarkets(ctx) if err != nil { return nil, err } @@ -192,26 +192,26 @@ func (b *BTCMarkets) FetchTradablePairs(ctx context.Context, a asset.Item) (curr // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *BTCMarkets) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = b.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *BTCMarkets) UpdateTickers(ctx context.Context, a asset.Item) error { - allPairs, err := b.GetEnabledPairs(a) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + allPairs, err := e.GetEnabledPairs(a) if err != nil { return err } - tickers, err := b.GetTickers(ctx, allPairs) + tickers, err := e.GetTickers(ctx, allPairs) if err != nil { return err } @@ -230,7 +230,7 @@ func (b *BTCMarkets) UpdateTickers(ctx context.Context, a asset.Item) error { Ask: tickers[x].BestAsk, Volume: tickers[x].Volume, LastUpdated: time.Now(), - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }); err != nil { return err @@ -240,37 +240,37 @@ func (b *BTCMarkets) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *BTCMarkets) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := b.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(b.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, PriceDuplication: true, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } // Retrieve level one book which is the top 50 ask and bids, this is not // cached. - tempResp, err := b.GetOrderbook(ctx, fPair.String(), 1) + tempResp, err := e.GetOrderbook(ctx, fPair.String(), 1) if err != nil { return book, err } @@ -294,13 +294,13 @@ func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, asset if err != nil { return book, err } - return orderbook.Get(b.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies -func (b *BTCMarkets) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var resp account.Holdings - data, err := b.GetAccountBalance(ctx) + data, err := e.GetAccountBalance(ctx) if err != nil { return resp, err } @@ -315,9 +315,9 @@ func (b *BTCMarkets) UpdateAccountInfo(ctx context.Context, assetType asset.Item }) } resp.Accounts = append(resp.Accounts, acc) - resp.Exchange = b.Name + resp.Exchange = e.Name - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -331,13 +331,13 @@ func (b *BTCMarkets) UpdateAccountInfo(ctx context.Context, assetType asset.Item // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *BTCMarkets) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *BTCMarkets) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - withdrawals, err := b.ListWithdrawals(ctx, -1, -1, -1) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + withdrawals, err := e.ListWithdrawals(ctx, -1, -1, -1) if err != nil { return nil, err } @@ -361,15 +361,15 @@ func (b *BTCMarkets) GetWithdrawalsHistory(ctx context.Context, c currency.Code, } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = b.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData []Trade - tradeData, err = b.GetTrades(ctx, p.String(), 0, 0, 200) + tradeData, err = e.GetTrades(ctx, p.String(), 0, 0, 200) if err != nil { return nil, err } @@ -384,7 +384,7 @@ func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, asset } } resp[i] = trade.Data{ - Exchange: b.Name, + Exchange: e.Name, TID: tradeData[i].TradeID, CurrencyPair: p, AssetType: assetType, @@ -395,7 +395,7 @@ func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, asset } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -405,13 +405,13 @@ func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, asset } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *BTCMarkets) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -422,22 +422,22 @@ func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S s.Side = order.Ask } - fPair, err := b.FormatExchangeCurrency(s.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pair, asset.Spot) if err != nil { return nil, err } - fOrderType, err := b.formatOrderType(s.Type) + fOrderType, err := e.formatOrderType(s.Type) if err != nil { return nil, err } - fOrderSide, err := b.formatOrderSide(s.Side) + fOrderSide, err := e.formatOrderSide(s.Side) if err != nil { return nil, err } - tempResp, err := b.NewOrder(ctx, + tempResp, err := e.NewOrder(ctx, s.Price, s.Amount, s.TriggerPrice, @@ -445,7 +445,7 @@ func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S fPair.String(), fOrderType, fOrderSide, - b.getTimeInForce(s), + e.getTimeInForce(s), "", s.ClientID, s.TimeInForce.Is(order.PostOnly)) @@ -461,14 +461,14 @@ func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S if tempResp.Amount != 0 { err = submitResp.AdjustBaseAmount(tempResp.Amount) if err != nil { - log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s base amount conversion error: %s\n", b.Name, submitResp.OrderID, err) + log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s base amount conversion error: %s\n", e.Name, submitResp.OrderID, err) } } if tempResp.TargetAmount != 0 { err = submitResp.AdjustQuoteAmount(tempResp.TargetAmount) if err != nil { - log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s quote amount conversion error: %s\n", b.Name, submitResp.OrderID, err) + log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s quote amount conversion error: %s\n", e.Name, submitResp.OrderID, err) } } // With market orders the price is optional, so we can set it to the @@ -479,11 +479,11 @@ func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTCMarkets) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } - resp, err := b.ReplaceOrder(ctx, action.OrderID, action.ClientOrderID, action.Price, action.Amount) + resp, err := e.ReplaceOrder(ctx, action.OrderID, action.ClientOrderID, action.Price, action.Amount) if err != nil { return nil, err } @@ -513,17 +513,17 @@ func (b *BTCMarkets) ModifyOrder(ctx context.Context, action *order.Modify) (*or } // CancelOrder cancels an order by its corresponding ID number -func (b *BTCMarkets) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { err := o.Validate(o.StandardCancel()) if err != nil { return err } - _, err = b.RemoveOrder(ctx, o.OrderID) + _, err = e.RemoveOrder(ctx, o.OrderID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *BTCMarkets) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -538,7 +538,7 @@ func (b *BTCMarkets) CancelBatchOrders(ctx context.Context, o []order.Cancel) (* return nil, order.ErrOrderIDNotSet } } - batchResp, err := b.CancelBatch(ctx, ids) + batchResp, err := e.CancelBatch(ctx, ids) if err != nil { return nil, err } @@ -556,9 +556,9 @@ func (b *BTCMarkets) CancelBatchOrders(ctx context.Context, o []order.Cancel) (* } // CancelAllOrders cancels all orders associated with a currency pair -func (b *BTCMarkets) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { resp := order.CancelAllResponse{Status: map[string]string{}} - orders, err := b.GetOrders(ctx, "", -1, -1, -1, true) + orders, err := e.GetOrders(ctx, "", -1, -1, -1, true) if err != nil { return resp, err } @@ -568,7 +568,7 @@ func (b *BTCMarkets) CancelAllOrders(ctx context.Context, _ *order.Cancel) (orde orderIDs[x] = orders[x].OrderID } for _, batch := range common.Batch(orderIDs, 20) { - cancelResp, err := b.CancelBatch(ctx, batch) + cancelResp, err := e.CancelBatch(ctx, batch) if err != nil { return resp, err } @@ -583,14 +583,14 @@ func (b *BTCMarkets) CancelAllOrders(ctx context.Context, _ *order.Cancel) (orde } // GetOrderInfo returns order information based on order ID -func (b *BTCMarkets) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { var resp order.Detail - o, err := b.FetchOrder(ctx, orderID) + o, err := e.FetchOrder(ctx, orderID) if err != nil { return nil, err } - resp.Exchange = b.Name + resp.Exchange = e.Name resp.OrderID = orderID resp.Pair = o.MarketID resp.Price = o.Price @@ -637,8 +637,8 @@ func (b *BTCMarkets) GetOrderInfo(ctx context.Context, orderID string, _ currenc } // GetDepositAddress returns a deposit address for a specified currency -func (b *BTCMarkets) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - depositAddr, err := b.FetchDepositAddress(ctx, cryptocurrency, -1, -1, -1) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + depositAddr, err := e.FetchDepositAddress(ctx, cryptocurrency, -1, -1, -1) if err != nil { return nil, err } @@ -649,11 +649,11 @@ func (b *BTCMarkets) GetDepositAddress(ctx context.Context, cryptocurrency curre } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (b *BTCMarkets) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - a, err := b.RequestWithdraw(ctx, + a, err := e.RequestWithdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Crypto.Address, @@ -672,14 +672,14 @@ func (b *BTCMarkets) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRe // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *BTCMarkets) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } if withdrawRequest.Currency != currency.AUD { return nil, errors.New("only aud is supported for withdrawals") } - a, err := b.RequestWithdraw(ctx, + a, err := e.RequestWithdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.Amount, "", @@ -698,30 +698,30 @@ func (b *BTCMarkets) WithdrawFiatFunds(ctx context.Context, withdrawRequest *wit // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *BTCMarkets) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *BTCMarkets) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } if len(req.Pairs) == 0 { - allPairs, err := b.GetEnabledPairs(asset.Spot) + allPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } @@ -730,17 +730,17 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.MultiOrderR var resp []order.Detail for x := range req.Pairs { - fPair, err := b.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + fPair, err := e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } - tempData, err := b.GetOrders(ctx, fPair.String(), -1, -1, -1, true) + tempData, err := e.GetOrders(ctx, fPair.String(), -1, -1, -1, true) if err != nil { return resp, err } for y := range tempData { var tempResp order.Detail - tempResp.Exchange = b.Name + tempResp.Exchange = e.Name tempResp.Pair = req.Pairs[x] tempResp.OrderID = tempData[y].OrderID tempResp.Side = order.Bid @@ -757,7 +757,7 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.MultiOrderR default: log.Errorf(log.ExchangeSys, "%s unknown order type %s getting order", - b.Name, + e.Name, tempData[y].Type) tempResp.Type = order.UnknownType } @@ -771,7 +771,7 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.MultiOrderR default: log.Errorf(log.ExchangeSys, "%s unexpected status %s on order %v", - b.Name, + e.Name, tempData[y].Status, tempData[y].OrderID) tempResp.Status = order.UnknownStatus @@ -783,12 +783,12 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.MultiOrderR resp = append(resp, tempResp) } } - return req.Filter(b.Name, resp), nil + return req.Filter(e.Name, resp), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -797,7 +797,7 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderR var tempResp order.Detail var tempArray []string if len(req.Pairs) == 0 { - orders, err := b.GetOrders(ctx, "", -1, -1, -1, false) + orders, err := e.GetOrders(ctx, "", -1, -1, -1, false) if err != nil { return resp, err } @@ -806,12 +806,12 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderR } } for y := range req.Pairs { - fPair, err := b.FormatExchangeCurrency(req.Pairs[y], asset.Spot) + fPair, err := e.FormatExchangeCurrency(req.Pairs[y], asset.Spot) if err != nil { return nil, err } - orders, err := b.GetOrders(ctx, fPair.String(), -1, -1, -1, false) + orders, err := e.GetOrders(ctx, fPair.String(), -1, -1, -1, false) if err != nil { return resp, err } @@ -820,7 +820,7 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderR } } for _, batch := range common.Batch(tempArray, 50) { - tempData, err := b.GetBatchTrades(ctx, batch) + tempData, err := e.GetBatchTrades(ctx, batch) if err != nil { return resp, err } @@ -842,7 +842,7 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderR continue } - tempResp.Exchange = b.Name + tempResp.Exchange = e.Name tempResp.Pair = tempData.Orders[c].MarketID tempResp.Side = order.Bid if tempData.Orders[c].Side == ask { @@ -858,15 +858,15 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.MultiOrderR resp = append(resp, tempResp) } } - return req.Filter(b.Name, resp), nil + return req.Filter(e.Name, resp), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *BTCMarkets) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) if err != nil { - if b.CheckTransientError(err) == nil { + if e.CheckTransientError(err) == nil { return nil } // Check for specific auth errors; all other errors can be disregarded @@ -883,7 +883,7 @@ func (b *BTCMarkets) ValidateAPICredentials(ctx context.Context, assetType asset } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (b *BTCMarkets) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { switch in { case kline.OneMin: return "1m" @@ -908,15 +908,15 @@ func (b *BTCMarkets) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *BTCMarkets) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - candles, err := b.GetMarketCandles(ctx, + candles, err := e.GetMarketCandles(ctx, req.RequestFormatted.String(), - b.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), req.Start, req.End, -1, @@ -941,8 +941,8 @@ func (b *BTCMarkets) GetHistoricCandles(ctx context.Context, pair currency.Pair, } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *BTCMarkets) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := b.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -950,9 +950,9 @@ func (b *BTCMarkets) GetHistoricCandlesExtended(ctx context.Context, pair curren timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var candles []CandleResponse - candles, err = b.GetMarketCandles(ctx, + candles, err = e.GetMarketCandles(ctx, req.RequestFormatted.String(), - b.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time, -1, @@ -977,17 +977,17 @@ func (b *BTCMarkets) GetHistoricCandlesExtended(ctx context.Context, pair curren } // GetServerTime returns the current exchange server time. -func (b *BTCMarkets) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - return b.GetCurrentServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + return e.GetCurrentServerTime(ctx) } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (b *BTCMarkets) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { if a != asset.Spot { return fmt.Errorf("%s %w", a, asset.ErrNotSupported) } - markets, err := b.GetMarkets(ctx) + markets, err := e.GetMarkets(ctx) if err != nil { return err } @@ -1009,22 +1009,22 @@ func (b *BTCMarkets) UpdateOrderExecutionLimits(ctx context.Context, a asset.Ite PriceStepIncrementSize: math.Pow(10, -markets[x].PriceDecimals), } } - return b.LoadLimits(limits) + return e.LoadLimits(limits) } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (b *BTCMarkets) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (b *BTCMarkets) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *BTCMarkets) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index 786ca99f956..f5e46a6514d 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -21,8 +21,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/request" ) -// BTSE is the overarching type across this package -type BTSE struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with BTSE +type Exchange struct { exchange.Base } @@ -60,28 +60,28 @@ const ( ) // FetchFundingHistory gets funding history -func (b *BTSE) FetchFundingHistory(ctx context.Context, symbol string) (map[string][]FundingHistoryData, error) { +func (e *Exchange) FetchFundingHistory(ctx context.Context, symbol string) (map[string][]FundingHistoryData, error) { var resp map[string][]FundingHistoryData params := url.Values{} if symbol != "" { params.Set("symbol", symbol) } - return resp, b.SendHTTPRequest(ctx, exchange.RestFutures, http.MethodGet, btseFuturesFunding+params.Encode(), &resp, false, queryFunc) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, http.MethodGet, btseFuturesFunding+params.Encode(), &resp, false, queryFunc) } // GetRawMarketSummary returns an unfiltered list of market pairs // Consider using the wrapper function GetMarketSummary instead -func (b *BTSE) GetRawMarketSummary(ctx context.Context, symbol string, spot bool) (MarketSummary, error) { +func (e *Exchange) GetRawMarketSummary(ctx context.Context, symbol string, spot bool) (MarketSummary, error) { var m MarketSummary path := btseMarketOverview if symbol != "" { path += "?symbol=" + url.QueryEscape(symbol) } - return m, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &m, spot, queryFunc) + return m, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &m, spot, queryFunc) } // FetchOrderbook gets orderbook data for a given symbol -func (b *BTSE) FetchOrderbook(ctx context.Context, symbol string, group, limitBids, limitAsks int, spot bool) (*Orderbook, error) { +func (e *Exchange) FetchOrderbook(ctx context.Context, symbol string, group, limitBids, limitAsks int, spot bool) (*Orderbook, error) { var o Orderbook urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -94,22 +94,22 @@ func (b *BTSE) FetchOrderbook(ctx context.Context, symbol string, group, limitBi if group > 0 { urlValues.Add("group", strconv.Itoa(group)) } - return &o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return &o, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, common.EncodeURLValues(btseOrderbook, urlValues), &o, spot, queryFunc) } // FetchOrderbookL2 retrieve level 2 orderbook for requested symbol and depth -func (b *BTSE) FetchOrderbookL2(ctx context.Context, symbol string, depth int) (*Orderbook, error) { +func (e *Exchange) FetchOrderbookL2(ctx context.Context, symbol string, depth int) (*Orderbook, error) { var o Orderbook urlValues := url.Values{} urlValues.Add("symbol", symbol) urlValues.Add("depth", strconv.FormatInt(int64(depth), 10)) endpoint := common.EncodeURLValues(btseOrderbook+"/L2", urlValues) - return &o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) + return &o, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) } // GetTrades returns a list of trades for the specified symbol -func (b *BTSE) GetTrades(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld, spot bool) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld, spot bool) ([]Trade, error) { var t []Trade urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -134,12 +134,12 @@ func (b *BTSE) GetTrades(ctx context.Context, symbol string, start, end time.Tim if includeOld { urlValues.Add("includeOld", "true") } - return t, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return t, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, common.EncodeURLValues(btseTrades, urlValues), &t, spot, queryFunc) } // GetOHLCV retrieve and return OHLCV candle data for requested symbol -func (b *BTSE) GetOHLCV(ctx context.Context, symbol string, start, end time.Time, resolution int, a asset.Item) (OHLCV, error) { +func (e *Exchange) GetOHLCV(ctx context.Context, symbol string, start, end time.Time, resolution int, a asset.Item) (OHLCV, error) { var o OHLCV urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -158,40 +158,40 @@ func (b *BTSE) GetOHLCV(ctx context.Context, symbol string, start, end time.Time urlValues.Add("resolution", strconv.FormatInt(int64(res), 10)) endpoint := common.EncodeURLValues(btseOHLCV, urlValues) - return o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, a == asset.Spot, queryFunc) + return o, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, a == asset.Spot, queryFunc) } // GetPrice get current price for requested symbol -func (b *BTSE) GetPrice(ctx context.Context, symbol string) (Price, error) { +func (e *Exchange) GetPrice(ctx context.Context, symbol string) (Price, error) { var p Price path := btsePrice + "?symbol=" + url.QueryEscape(symbol) - return p, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &p, true, queryFunc) + return p, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &p, true, queryFunc) } // GetCurrentServerTime returns the exchanges server time -func (b *BTSE) GetCurrentServerTime(ctx context.Context) (*ServerTime, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (*ServerTime, error) { var s ServerTime - return &s, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseTime, &s, true, queryFunc) + return &s, e.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseTime, &s, true, queryFunc) } // GetWalletInformation returns the users account balance -func (b *BTSE) GetWalletInformation(ctx context.Context) ([]CurrencyBalance, error) { +func (e *Exchange) GetWalletInformation(ctx context.Context) ([]CurrencyBalance, error) { var a []CurrencyBalance - return a, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWallet, true, nil, nil, &a, queryFunc) + return a, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWallet, true, nil, nil, &a, queryFunc) } // GetFeeInformation retrieve fee's (maker/taker) for requested symbol -func (b *BTSE) GetFeeInformation(ctx context.Context, symbol string) ([]AccountFees, error) { +func (e *Exchange) GetFeeInformation(ctx context.Context, symbol string) ([]AccountFees, error) { var resp []AccountFees urlValues := url.Values{} if symbol != "" { urlValues.Add("symbol", symbol) } - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseUserFee, true, urlValues, nil, &resp, queryFunc) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseUserFee, true, urlValues, nil, &resp, queryFunc) } // GetWalletHistory returns the users account balance -func (b *BTSE) GetWalletHistory(ctx context.Context, symbol string, start, end time.Time, count int) (WalletHistory, error) { +func (e *Exchange) GetWalletHistory(ctx context.Context, symbol string, start, end time.Time, count int) (WalletHistory, error) { var resp WalletHistory urlValues := url.Values{} @@ -208,11 +208,11 @@ func (b *BTSE) GetWalletHistory(ctx context.Context, symbol string, start, end t if count > 0 { urlValues.Add("count", strconv.Itoa(count)) } - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletHistory, true, urlValues, nil, &resp, queryFunc) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletHistory, true, urlValues, nil, &resp, queryFunc) } // GetWalletAddress returns the users account balance -func (b *BTSE) GetWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { +func (e *Exchange) GetWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { var resp WalletAddress urlValues := url.Values{} @@ -220,15 +220,15 @@ func (b *BTSE) GetWalletAddress(ctx context.Context, currency string) (WalletAdd urlValues.Add("currency", currency) } - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletAddress, true, urlValues, nil, &resp, queryFunc) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletAddress, true, urlValues, nil, &resp, queryFunc) } // CreateWalletAddress create new deposit address for requested currency -func (b *BTSE) CreateWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { +func (e *Exchange) CreateWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { var resp WalletAddress req := make(map[string]any, 1) req["currency"] = currency - err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletAddress, true, nil, req, &resp, queryFunc) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletAddress, true, nil, req, &resp, queryFunc) if err != nil { errResp := ErrorResponse{} errResponseStr := strings.Split(err.Error(), "raw response: ") @@ -251,18 +251,18 @@ func (b *BTSE) CreateWalletAddress(ctx context.Context, currency string) (Wallet } // WalletWithdrawal submit request to withdraw crypto currency -func (b *BTSE) WalletWithdrawal(ctx context.Context, currency, address, tag, amount string) (WithdrawalResponse, error) { +func (e *Exchange) WalletWithdrawal(ctx context.Context, currency, address, tag, amount string) (WithdrawalResponse, error) { var resp WithdrawalResponse req := make(map[string]any, 4) req["currency"] = currency req["address"] = address req["tag"] = tag req["amount"] = amount - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletWithdrawal, true, nil, req, &resp, queryFunc) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletWithdrawal, true, nil, req, &resp, queryFunc) } // CreateOrder creates an order -func (b *BTSE) CreateOrder(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { +func (e *Exchange) CreateOrder(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { req := make(map[string]any) if clOrderID != "" { req["clOrderID"] = clOrderID @@ -308,11 +308,11 @@ func (b *BTSE) CreateOrder(ctx context.Context, clOrderID string, deviation floa } var r []Order - return r, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseOrder, true, url.Values{}, req, &r, orderFunc) + return r, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseOrder, true, url.Values{}, req, &r, orderFunc) } // GetOrders returns all pending orders -func (b *BTSE) GetOrders(ctx context.Context, symbol, orderID, clOrderID string) ([]OpenOrder, error) { +func (e *Exchange) GetOrders(ctx context.Context, symbol, orderID, clOrderID string) ([]OpenOrder, error) { req := url.Values{} if orderID != "" { req.Add("orderID", orderID) @@ -322,11 +322,11 @@ func (b *BTSE) GetOrders(ctx context.Context, symbol, orderID, clOrderID string) req.Add("clOrderID", clOrderID) } var o []OpenOrder - return o, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btsePendingOrders, true, req, nil, &o, orderFunc) + return o, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btsePendingOrders, true, req, nil, &o, orderFunc) } // CancelExistingOrder cancels an order -func (b *BTSE) CancelExistingOrder(ctx context.Context, orderID, symbol, clOrderID string) (CancelOrder, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID, symbol, clOrderID string) (CancelOrder, error) { var c CancelOrder req := url.Values{} if orderID != "" { @@ -337,18 +337,18 @@ func (b *BTSE) CancelExistingOrder(ctx context.Context, orderID, symbol, clOrder req.Add("clOrderID", clOrderID) } - return c, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, btseOrder, true, req, nil, &c, orderFunc) + return c, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, btseOrder, true, req, nil, &c, orderFunc) } // CancelAllAfter cancels all orders after timeout -func (b *BTSE) CancelAllAfter(ctx context.Context, timeout int) error { +func (e *Exchange) CancelAllAfter(ctx context.Context, timeout int) error { req := make(map[string]any) req["timeout"] = timeout - return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseCancelAllAfter, true, url.Values{}, req, nil, orderFunc) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseCancelAllAfter, true, url.Values{}, req, nil, orderFunc) } // IndexOrderPeg create peg order that will track a certain percentage above/below the index price -func (b *BTSE) IndexOrderPeg(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { +func (e *Exchange) IndexOrderPeg(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { var o []Order req := make(map[string]any) if clOrderID != "" { @@ -394,11 +394,11 @@ func (b *BTSE) IndexOrderPeg(ctx context.Context, clOrderID string, deviation fl req["type"] = orderType } - return o, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btsePegOrder, true, url.Values{}, req, nil, orderFunc) + return o, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btsePegOrder, true, url.Values{}, req, nil, orderFunc) } // TradeHistory returns previous trades on exchange -func (b *BTSE) TradeHistory(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld bool, clOrderID, orderID string) (TradeHistory, error) { +func (e *Exchange) TradeHistory(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld bool, clOrderID, orderID string) (TradeHistory, error) { var resp TradeHistory urlValues := url.Values{} if symbol != "" { @@ -429,12 +429,12 @@ func (b *BTSE) TradeHistory(ctx context.Context, symbol string, start, end time. if orderID != "" { urlValues.Add("orderID", orderID) } - return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseExchangeHistory, true, urlValues, nil, &resp, queryFunc) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseExchangeHistory, true, urlValues, nil, &resp, queryFunc) } // SendHTTPRequest sends an HTTP request to the desired endpoint -func (b *BTSE) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, result any, spotEndpoint bool, f request.EndpointLimit) error { - ePoint, err := b.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, result any, spotEndpoint bool, f request.EndpointLimit) error { + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -446,23 +446,23 @@ func (b *BTSE) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, end Method: method, Path: ePoint + p + endpoint, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return b.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the desired endpoint -func (b *BTSE) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, isSpot bool, values url.Values, req map[string]any, result any, f request.EndpointLimit) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, isSpot bool, values url.Values, req map[string]any, result any, f request.EndpointLimit) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := b.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -525,21 +525,21 @@ func (b *BTSE) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL Headers: headers, Body: body, Result: result, - Verbose: b.Verbose, - HTTPDebugging: b.HTTPDebugging, - HTTPRecording: b.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - return b.SendPayload(ctx, f, newRequest, request.AuthenticatedRequest) + return e.SendPayload(ctx, f, newRequest, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *BTSE) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - fee = b.calculateTradingFee(ctx, feeBuilder) * feeBuilder.Amount * feeBuilder.PurchasePrice + fee = e.calculateTradingFee(ctx, feeBuilder) * feeBuilder.Amount * feeBuilder.PurchasePrice case exchange.CryptocurrencyWithdrawalFee: switch feeBuilder.Pair.Base { case currency.USDT: @@ -595,15 +595,15 @@ func getInternationalBankWithdrawalFee(amount float64) float64 { } // calculateTradingFee return fee based on users current fee tier or default values -func (b *BTSE) calculateTradingFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) float64 { - formattedPair, err := b.FormatExchangeCurrency(feeBuilder.Pair, asset.Spot) +func (e *Exchange) calculateTradingFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) float64 { + formattedPair, err := e.FormatExchangeCurrency(feeBuilder.Pair, asset.Spot) if err != nil { if feeBuilder.IsMaker { return 0.001 } return 0.002 } - feeTiers, err := b.GetFeeInformation(ctx, formattedPair.String()) + feeTiers, err := e.GetFeeInformation(ctx, formattedPair.String()) if err != nil { // TODO: Return actual error, we shouldn't pivot around errors. if feeBuilder.IsMaker { diff --git a/exchanges/btse/btse_test.go b/exchanges/btse/btse_test.go index 13d7e6fcdc3..7868e778403 100644 --- a/exchanges/btse/btse_test.go +++ b/exchanges/btse/btse_test.go @@ -34,20 +34,20 @@ const ( ) var ( - b *BTSE + e *Exchange futuresPair = currency.NewPair(currency.ENJ, currency.PFC) spotPair = currency.NewPairWithDelimiter("BTC", "USD", "-") ) func TestMain(m *testing.M) { - b = new(BTSE) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("BTSE Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -55,227 +55,227 @@ func TestMain(m *testing.M) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) + testexch.UpdatePairsOnce(t, e) expected := map[asset.Item][]string{ asset.Spot: {"BTCUSD", "BTCUSDT", "ETHBTC"}, asset.Futures: {"BTCPFC", "ETHPFC"}, } for a, pairs := range expected { for _, symb := range pairs { - _, err := b.CurrencyPairs.Match(symb, a) + _, err := e.CurrencyPairs.Match(symb, a) assert.NoErrorf(t, err, "Should find pair %s for %s", symb, a) } } } func TestFetchFundingHistory(t *testing.T) { - _, err := b.FetchFundingHistory(t.Context(), "") + _, err := e.FetchFundingHistory(t.Context(), "") assert.NoError(t, err, "FetchFundingHistory should not error") } func TestGetMarketsSummary(t *testing.T) { t.Parallel() - _, err := b.GetMarketSummary(t.Context(), "", true) + _, err := e.GetMarketSummary(t.Context(), "", true) assert.NoError(t, err, "GetMarketSummary should not error") - ret, err := b.GetMarketSummary(t.Context(), spotPair.String(), true) + ret, err := e.GetMarketSummary(t.Context(), spotPair.String(), true) assert.NoError(t, err, "GetMarketSummary should not error") assert.Len(t, ret, 1, "expected only one result when requesting BTC-USD data received") - _, err = b.GetMarketSummary(t.Context(), "", false) + _, err = e.GetMarketSummary(t.Context(), "", false) assert.NoError(t, err, "GetMarketSummary should not error") } func TestFetchOrderBook(t *testing.T) { t.Parallel() - _, err := b.FetchOrderbook(t.Context(), spotPair.String(), 0, 1, 1, true) + _, err := e.FetchOrderbook(t.Context(), spotPair.String(), 0, 1, 1, true) assert.NoError(t, err, "FetchOrderBook should not error") - _, err = b.FetchOrderbook(t.Context(), futuresPair.String(), 0, 1, 1, false) + _, err = e.FetchOrderbook(t.Context(), futuresPair.String(), 0, 1, 1, false) assert.NoError(t, err, "FetchOrderBook should not error") - _, err = b.FetchOrderbook(t.Context(), spotPair.String(), 1, 1, 1, true) + _, err = e.FetchOrderbook(t.Context(), spotPair.String(), 1, 1, 1, true) assert.NoError(t, err, "FetchOrderBook should not error") } func TestUpdateOrderbook(t *testing.T) { t.Parallel() - _, err := b.UpdateOrderbook(t.Context(), spotPair, asset.Spot) + _, err := e.UpdateOrderbook(t.Context(), spotPair, asset.Spot) assert.NoError(t, err, "UpdateOrderbook should not error") - _, err = b.UpdateOrderbook(t.Context(), futuresPair, asset.Futures) + _, err = e.UpdateOrderbook(t.Context(), futuresPair, asset.Futures) assert.NoError(t, err, "UpdateOrderbook should not error") } func TestFetchOrderBookL2(t *testing.T) { t.Parallel() - _, err := b.FetchOrderbookL2(t.Context(), spotPair.String(), 20) + _, err := e.FetchOrderbookL2(t.Context(), spotPair.String(), 20) assert.NoError(t, err, "FetchOrderBookL2 should not error") } func TestOHLCV(t *testing.T) { t.Parallel() - _, err := b.GetOHLCV(t.Context(), spotPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 60, asset.Spot) + _, err := e.GetOHLCV(t.Context(), spotPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 60, asset.Spot) assert.NoError(t, err, "GetOHLCV should not error") - _, err = b.GetOHLCV(t.Context(), spotPair.String(), time.Now(), time.Now().AddDate(0, 0, -1), 60, asset.Spot) + _, err = e.GetOHLCV(t.Context(), spotPair.String(), time.Now(), time.Now().AddDate(0, 0, -1), 60, asset.Spot) assert.ErrorIs(t, err, common.ErrStartAfterEnd, "GetOHLCV should error if start date after end date") - _, err = b.GetOHLCV(t.Context(), futuresPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 60, asset.Futures) + _, err = e.GetOHLCV(t.Context(), futuresPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 60, asset.Futures) assert.NoError(t, err, "GetOHLCV should not error") } func TestGetPrice(t *testing.T) { t.Parallel() - _, err := b.GetPrice(t.Context(), spotPair.String()) + _, err := e.GetPrice(t.Context(), spotPair.String()) assert.NoError(t, err, "GetPrice should not error") } func TestFormatExchangeKlineInterval(t *testing.T) { - ret := b.FormatExchangeKlineInterval(kline.OneDay) + ret := e.FormatExchangeKlineInterval(kline.OneDay) assert.Equal(t, "1440", ret, "FormatExchangeKlineInterval should return correct value") } func TestGetHistoricCandles(t *testing.T) { t.Parallel() - r := b.Requester - b := new(BTSE) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test exchange Setup must not error") - b.Requester = r + r := e.Requester + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test exchange Setup must not error") + e.Requester = r start := time.Now().AddDate(0, 0, -3) - _, err := b.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneHour, start, time.Now()) + _, err := e.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneHour, start, time.Now()) assert.NoError(t, err, "GetHistoricCandles should not error") - _, err = b.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneDay, start, time.Now()) + _, err = e.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneDay, start, time.Now()) assert.NoError(t, err, "GetHistoricCandles should not error") } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - r := b.Requester - b := new(BTSE) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test exchange Setup must not error") - b.Requester = r - err := b.CurrencyPairs.StorePairs(asset.Futures, currency.Pairs{futuresPair}, true) + r := e.Requester + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test exchange Setup must not error") + e.Requester = r + err := e.CurrencyPairs.StorePairs(asset.Futures, currency.Pairs{futuresPair}, true) assert.NoError(t, err, "StorePairs should not error") start := time.Now().AddDate(0, 0, -1) - _, err = b.GetHistoricCandlesExtended(t.Context(), spotPair, asset.Spot, kline.OneHour, start, time.Now()) + _, err = e.GetHistoricCandlesExtended(t.Context(), spotPair, asset.Spot, kline.OneHour, start, time.Now()) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") - _, err = b.GetHistoricCandlesExtended(t.Context(), futuresPair, asset.Futures, kline.OneHour, start, time.Now()) + _, err = e.GetHistoricCandlesExtended(t.Context(), futuresPair, asset.Futures, kline.OneHour, start, time.Now()) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") } func TestGetTrades(t *testing.T) { t.Parallel() - _, err := b.GetTrades(t.Context(), spotPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, true) + _, err := e.GetTrades(t.Context(), spotPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, true) assert.NoError(t, err, "GetTrades should not error") - _, err = b.GetTrades(t.Context(), spotPair.String(), time.Now(), time.Now().AddDate(0, -1, 0), 0, 0, 50, false, true) + _, err = e.GetTrades(t.Context(), spotPair.String(), time.Now(), time.Now().AddDate(0, -1, 0), 0, 0, 50, false, true) assert.ErrorIs(t, err, common.ErrStartAfterEnd, "GetTrades should error if start date after end date") - _, err = b.GetTrades(t.Context(), futuresPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, false) + _, err = e.GetTrades(t.Context(), futuresPair.String(), time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, false) assert.NoError(t, err, "GetTrades should not error") } func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := b.UpdateTicker(t.Context(), spotPair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), spotPair, asset.Spot) assert.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTickers may only error about locked markets") - _, err = b.UpdateTicker(t.Context(), futuresPair, asset.Futures) + _, err = e.UpdateTicker(t.Context(), futuresPair, asset.Futures) assert.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTickers may only error about locked markets") } func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) assert.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTickers may only error about locked markets") - err = b.UpdateTickers(t.Context(), asset.Futures) + err = e.UpdateTickers(t.Context(), asset.Futures) assert.NoError(t, common.ExcludeError(err, ticker.ErrBidEqualsAsk), "UpdateTickers may only error about locked markets") } func TestGetCurrentServerTime(t *testing.T) { t.Parallel() - _, err := b.GetCurrentServerTime(t.Context()) + _, err := e.GetCurrentServerTime(t.Context()) assert.NoError(t, err, "GetCurrentServerTime should not error") } func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := b.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) assert.NoError(t, err, "GetServerTime should not error") assert.WithinRange(t, st, time.Now().Add(-24*time.Hour), time.Now().Add(24*time.Hour), "Time should be within a day of now") } func TestGetWalletInformation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWalletInformation(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWalletInformation(t.Context()) assert.NoError(t, err, "GetWalletInformation should not error") } func TestGetFeeInformation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetFeeInformation(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFeeInformation(t.Context(), "") assert.NoError(t, err, "GetFeeInformation should not error") } func TestGetWalletHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWalletHistory(t.Context(), spotPair.String(), time.Time{}, time.Time{}, 50) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWalletHistory(t.Context(), spotPair.String(), time.Time{}, time.Time{}, 50) assert.NoError(t, err, "GetWalletHistory should not error") } func TestGetWalletAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWalletAddress(t.Context(), "XRP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWalletAddress(t.Context(), "XRP") assert.NoError(t, err, "GetWalletAddress should not error") } func TestCreateWalletAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.CreateWalletAddress(t.Context(), "XRP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CreateWalletAddress(t.Context(), "XRP") assert.NoError(t, err, "CreateWalletAddress should not error") } func TestGetDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetDepositAddress(t.Context(), currency.BTC, "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") assert.NoError(t, err, "GetDepositAddress should not error") } func TestCreateOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CreateOrder(t.Context(), "", 0.0, false, -1, "BUY", 100, 0, 0, spotPair.String(), "GTC", 0.0, 0.0, "LIMIT", "LIMIT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CreateOrder(t.Context(), "", 0.0, false, -1, "BUY", 100, 0, 0, spotPair.String(), "GTC", 0.0, 0.0, "LIMIT", "LIMIT") assert.NoError(t, err, "CreateOrder should not error") } func TestBTSEIndexOrderPeg(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.IndexOrderPeg(t.Context(), "", 0.0, false, -1, "BUY", 100, 0, 0, spotPair.String(), "GTC", 0.0, 0.0, "", "LIMIT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.IndexOrderPeg(t.Context(), "", 0.0, false, -1, "BUY", 100, 0, 0, spotPair.String(), "GTC", 0.0, 0.0, "", "LIMIT") assert.NoError(t, err, "IndexOrderPeg should not error") } func TestGetOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOrders(t.Context(), spotPair.String(), "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrders(t.Context(), spotPair.String(), "", "") assert.NoError(t, err, "GetOrders should not error") } func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Pairs: []currency.Pair{ @@ -295,34 +295,34 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err, "GetActiveOrders should not error") } func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Spot, Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err, "GetOrderHistory should not error") } func TestTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := b.TradeHistory(t.Context(), "", time.Time{}, time.Time{}, 0, 0, 0, false, "", "") + _, err := e.TradeHistory(t.Context(), "", time.Time{}, time.Time{}, 0, 0, 0, false, "", "") assert.NoError(t, err, "TradeHistory should not error") } func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() - assert.Equal(t, exchange.NoAPIWithdrawalMethodsText, b.FormatWithdrawPermissions(), "FormatWithdrawPermissions should return correct format") + assert.Equal(t, exchange.NoAPIWithdrawalMethodsText, e.FormatWithdrawPermissions(), "FormatWithdrawPermissions should return correct format") } // TestGetFeeByTypeOfflineTradeFee logic test @@ -335,9 +335,9 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { PurchasePrice: 1000, } - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) assert.NoError(t, err, "GetFeeByType should not error") - if !sharedtestvalues.AreAPICredentialsSet(b) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "FeeBuilder should give offline trade fee type") } else { assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType, "FeeBuilder should give crypto trade fee type") @@ -355,44 +355,44 @@ func TestGetFee(t *testing.T) { PurchasePrice: 1000, } - _, err := b.GetFee(t.Context(), feeBuilder) + _, err := e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for maker") feeBuilder.IsMaker = false - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for taker") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for withdrawal") feeBuilder.Pair.Base = currency.USDT - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for USDT") feeBuilder.FeeType = exchange.InternationalBankDepositFee - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for International deposits") feeBuilder.Amount = 1000000 - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for a squillion") feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for International withdrawals") feeBuilder.Amount = 1000 - _, err = b.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "fee builuder should not error for a fraction of a squillion") } func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.BTC, Quote: currency.USD, @@ -404,22 +404,22 @@ func TestSubmitOrder(t *testing.T) { ClientID: "", AssetType: asset.Spot, } - response, err := b.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) assert.NoError(t, err, "SubmitOrder should not error") assert.Equal(t, order.New, response.Status, "Response Status should be New") } func TestCancelAllAfter(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - err := b.CancelAllAfter(t.Context(), 1) + err := e.CancelAllAfter(t.Context(), 1) assert.NoError(t, err, "CancelAllAfter should not error") } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) // TODO: Place an order to make sure we can cancel it orderCancellation := &order.Cancel{ @@ -428,22 +428,22 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: spotPair, AssetType: asset.Spot, } - err := b.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err, "CancelOrder should not error") } func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) // TODO: Place an order to make sure we can cancel it - _, err := b.CancelExistingOrder(t.Context(), "", spotPair.String(), "") + _, err := e.CancelExistingOrder(t.Context(), "", spotPair.String(), "") assert.NoError(t, err, "CancelExistingOrder should not error") } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", @@ -451,7 +451,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { Pair: spotPair, AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) assert.NoError(t, err, "CancelAllOrders should not error") for k, v := range resp.Status { @@ -462,7 +462,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestWsOrderbook(t *testing.T) { t.Parallel() pressXToJSON := []byte(`{"topic":"orderBookL2Api:BTC-USD_0","data":{"buyQuote":[{"price":"9272.0","size":"0.077"},{"price":"9271.0","size":"1.122"},{"price":"9270.0","size":"2.548"},{"price":"9267.5","size":"1.015"},{"price":"9265.5","size":"0.930"},{"price":"9265.0","size":"0.475"},{"price":"9264.5","size":"2.216"},{"price":"9264.0","size":"9.709"},{"price":"9263.5","size":"3.667"},{"price":"9263.0","size":"8.481"},{"price":"9262.5","size":"7.660"},{"price":"9262.0","size":"9.689"},{"price":"9261.5","size":"4.213"},{"price":"9261.0","size":"1.491"},{"price":"9260.5","size":"6.264"},{"price":"9260.0","size":"1.690"},{"price":"9259.5","size":"5.718"},{"price":"9259.0","size":"2.706"},{"price":"9258.5","size":"0.192"},{"price":"9258.0","size":"1.592"},{"price":"9257.5","size":"1.749"},{"price":"9257.0","size":"8.104"},{"price":"9256.0","size":"0.161"},{"price":"9252.0","size":"1.544"},{"price":"9249.5","size":"1.462"},{"price":"9247.5","size":"1.833"},{"price":"9247.0","size":"0.168"},{"price":"9245.5","size":"1.941"},{"price":"9244.0","size":"1.423"},{"price":"9243.5","size":"0.175"}],"currency":"USD","sellQuote":[{"price":"9303.5","size":"1.839"},{"price":"9303.0","size":"2.067"},{"price":"9302.0","size":"0.117"},{"price":"9298.5","size":"1.569"},{"price":"9297.0","size":"1.527"},{"price":"9295.0","size":"0.184"},{"price":"9294.0","size":"1.785"},{"price":"9289.0","size":"1.673"},{"price":"9287.5","size":"4.194"},{"price":"9287.0","size":"6.622"},{"price":"9286.5","size":"2.147"},{"price":"9286.0","size":"3.348"},{"price":"9285.5","size":"5.655"},{"price":"9285.0","size":"10.423"},{"price":"9284.5","size":"6.233"},{"price":"9284.0","size":"8.860"},{"price":"9283.5","size":"9.441"},{"price":"9283.0","size":"3.455"},{"price":"9282.5","size":"11.033"},{"price":"9282.0","size":"11.471"},{"price":"9281.5","size":"4.742"},{"price":"9281.0","size":"14.789"},{"price":"9280.5","size":"11.117"},{"price":"9280.0","size":"0.807"},{"price":"9279.5","size":"1.651"},{"price":"9279.0","size":"0.244"},{"price":"9278.5","size":"0.533"},{"price":"9277.0","size":"1.447"},{"price":"9273.0","size":"1.976"},{"price":"9272.5","size":"0.093"}]}}`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) assert.NoError(t, err, "wsHandleData orderBookL2Api should not error") // TODO: Meaningful test of data parsing } @@ -470,14 +470,14 @@ func TestWsOrderbook(t *testing.T) { func TestWSTrades(t *testing.T) { t.Parallel() - b := new(BTSE) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Setup Instance must not error") - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", b.wsHandleData) - close(b.Websocket.DataHandler) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) exp := []trade.Data{ { - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: spotPair, Timestamp: time.UnixMilli(1741836562893).UTC(), Price: 83894.01, @@ -487,7 +487,7 @@ func TestWSTrades(t *testing.T) { AssetType: asset.Spot, }, { - Exchange: b.Name, + Exchange: e.Name, CurrencyPair: spotPair, Timestamp: time.UnixMilli(1741836562687).UTC(), Price: 83894.87, @@ -497,11 +497,11 @@ func TestWSTrades(t *testing.T) { AssetType: asset.Spot, }, } - require.Len(t, b.Websocket.DataHandler, 2, "Must see the correct number of trades") - for resp := range b.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, 2, "Must see the correct number of trades") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 1 - len(b.Websocket.DataHandler) + i := 1 - len(e.Websocket.DataHandler) require.Equalf(t, exp[i], v, "Trade [%d] must be correct", i) case error: t.Error(v) @@ -516,7 +516,7 @@ func TestWsOrderNotification(t *testing.T) { status := []string{"ORDER_INSERTED", "ORDER_CANCELLED", "TRIGGER_INSERTED", "ORDER_FULL_TRANSACTED", "ORDER_PARTIALLY_TRANSACTED", "INSUFFICIENT_BALANCE", "TRIGGER_ACTIVATED", "MARKET_UNAVAILABLE"} for i := range status { pressXToJSON := []byte(`{"topic": "notificationApi","data": [{"symbol": "BTC-USD","orderID": "1234","orderMode": "MODE_BUY","orderType": "TYPE_LIMIT","price": "1","size": "1","status": "` + status[i] + `","timestamp": "1580349090693","type": "STOP","triggerPrice": "1"}]}`) - err := b.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) assert.NoErrorf(t, err, "wsHandleData notificationApi should not error on %s", status[i]) // TODO: Meaningful test of data parsing } @@ -549,9 +549,9 @@ func TestStatusToStandardStatus(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - assets := b.GetAssetTypes(false) + assets := e.GetAssetTypes(false) for i := range assets { - data, err := b.FetchTradablePairs(t.Context(), assets[i]) + data, err := e.FetchTradablePairs(t.Context(), assets[i]) assert.NoErrorf(t, err, "FetchTradablePairs should not error for %s", assets[i]) assert.NotEmpty(t, data, "FetchTradablePairs should return some pairs") } @@ -575,17 +575,17 @@ func TestMatchType(t *testing.T) { // TestUpdateOrderExecutionLimits exercises UpdateOrderExecutionLimits func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - err := b.UpdateOrderExecutionLimits(t.Context(), a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateOrderExecutionLimits(t.Context(), a) require.NoErrorf(t, err, "UpdateOrderExecutionLimits must not error for %s", a) - pairs, err := b.GetAvailablePairs(a) + pairs, err := e.GetAvailablePairs(a) require.NoErrorf(t, err, "GetAvailablePairs must not error for %s", a) require.NotEmpty(t, pairs, "GetAvailablePairs must return some pairs") for _, p := range pairs { - limits, err := b.GetOrderExecutionLimits(a, p) + limits, err := e.GetOrderExecutionLimits(a, p) require.NoErrorf(t, err, "GetOrderExecutionLimits must not error for %s %s", a, p) assert.Positivef(t, limits.MinimumBaseAmount, "MinimumBaseAmount should be positive for %s %s", a, p) assert.Positivef(t, limits.MaximumBaseAmount, "MaximumBaseAmount should be positive for %s %s", a, p) @@ -598,81 +598,81 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := b.GetRecentTrades(t.Context(), spotPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), spotPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades Should not error") - _, err = b.GetRecentTrades(t.Context(), futuresPair, asset.Futures) + _, err = e.GetRecentTrades(t.Context(), futuresPair, asset.Futures) assert.NoError(t, err, "GetRecentTrades Should not error") } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "GetHistoricTrades should not be supported") } func TestOrderbookFilter(t *testing.T) { t.Parallel() - assert.True(t, b.orderbookFilter(0, 1), "orderbookFilter should return correctly") - assert.True(t, b.orderbookFilter(1, 0), "orderbookFilter should return correctly") - assert.True(t, b.orderbookFilter(0, 0), "orderbookFilter should return correctly") - assert.False(t, b.orderbookFilter(1, 1), "orderbookFilter should return correctly") + assert.True(t, e.orderbookFilter(0, 1), "orderbookFilter should return correctly") + assert.True(t, e.orderbookFilter(1, 0), "orderbookFilter should return correctly") + assert.True(t, e.orderbookFilter(0, 0), "orderbookFilter should return correctly") + assert.False(t, e.orderbookFilter(1, 1), "orderbookFilter should return correctly") } func TestWsLogin(t *testing.T) { t.Parallel() data := []byte(`{"event":"login","success":true}`) - err := b.wsHandleData(t.Context(), data) + err := e.wsHandleData(t.Context(), data) assert.NoError(t, err, "wsHandleData login should not error") - assert.True(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints should be true after login") + assert.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints should be true after login") data = []byte(`{"event":"login","success":false}`) - err = b.wsHandleData(t.Context(), data) + err = e.wsHandleData(t.Context(), data) assert.NoError(t, err, "wsHandleData login should not error") - assert.False(t, b.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints should be false failed login") + assert.False(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints should be false failed login") } func TestWsSubscription(t *testing.T) { t.Parallel() data := []byte(`{"event":"subscribe","channel":["orderBookL2Api:SFI-ETH_0","tradeHistory:SFI-ETH"]}`) - err := b.wsHandleData(t.Context(), data) + err := e.wsHandleData(t.Context(), data) assert.NoError(t, err, "wsHandleData subscribe should not error") } func TestWsUnexpectedData(t *testing.T) { t.Parallel() data := []byte(`{}`) - err := b.wsHandleData(t.Context(), data) + err := e.wsHandleData(t.Context(), data) assert.ErrorContains(t, err, websocket.UnhandledMessage, "wsHandleData should error on empty message") } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := b.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset, "GetFuturesContractDetails should error correctly on Spot") - _, err = b.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) assert.ErrorIs(t, err, asset.ErrNotSupported, "GetFuturesContractDetails should error correctly on Margin") - _, err = b.GetFuturesContractDetails(t.Context(), asset.Futures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.Futures) assert.NoError(t, err, "GetFuturesContractDetails should not error on Futures") } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), IncludePredictedRate: true, }) assert.ErrorIs(t, err, asset.ErrNotSupported, "GetLatestFundingRates should error on Margin") - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, }) assert.NoError(t, err, "GetLatestFundingRates should not error on futures") - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: futuresPair, }) @@ -681,31 +681,31 @@ func TestGetLatestFundingRates(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - isPerp, err := b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSD()) + isPerp, err := e.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSD()) assert.NoError(t, err, "IsPerpetualFutureCurrency should not error") assert.False(t, isPerp, "IsPerpetualFutureCurrency should return true for a Margin pair") - isPerp, err = b.IsPerpetualFutureCurrency(asset.Futures, futuresPair) + isPerp, err = e.IsPerpetualFutureCurrency(asset.Futures, futuresPair) assert.NoError(t, err, "IsPerpetualFutureCurrency should not error") assert.True(t, isPerp, "IsPerpetualFutureCurrency should return true for a futures pair") - isPerp, err = b.IsPerpetualFutureCurrency(asset.Futures, spotPair) + isPerp, err = e.IsPerpetualFutureCurrency(asset.Futures, spotPair) assert.NoError(t, err, "IsPerpetualFutureCurrency should not error") assert.False(t, isPerp, "IsPerpetualFutureCurrency should return false for a spot pair") } func TestGetOpenInterest(t *testing.T) { t.Parallel() - r := b.Requester - b := new(BTSE) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(b), "Test exchange Setup must not error") - testexch.UpdatePairsOnce(t, b) - b.Requester = r + r := e.Requester + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test exchange Setup must not error") + testexch.UpdatePairsOnce(t, e) + e.Requester = r cp1 := currency.NewPair(currency.BTC, currency.PFC) cp2 := currency.NewPair(currency.ETH, currency.PFC) - sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, b, asset.Futures, futuresPair, cp1, cp2) + sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, e, asset.Futures, futuresPair, cp1, cp2) - resp, err := b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: cp1.Base.Item, Quote: cp1.Quote.Item, Asset: asset.Futures, @@ -713,7 +713,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context(), + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: cp1.Base.Item, Quote: cp1.Quote.Item, @@ -727,11 +727,11 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) - _, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.USDT.Item, Asset: asset.Spot, @@ -741,12 +741,12 @@ func TestGetOpenInterest(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -798,19 +798,19 @@ func TestMarketPair(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(BTSE) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") exp := subscription.List{ {Channel: subscription.AllTradesChannel, QualifiedChannel: "tradeHistoryApi:BTC-USD", Asset: asset.Spot, Pairs: currency.Pairs{spotPair}}, {Channel: subscription.MyTradesChannel, QualifiedChannel: "notificationApi"}, } - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := b.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") testsubs.EqualLists(t, exp, subs) - _, err = subscription.List{{Channel: subscription.OrderbookChannel}}.ExpandTemplates(b) + _, err = subscription.List{{Channel: subscription.OrderbookChannel}}.ExpandTemplates(e) assert.ErrorContains(t, err, "Channel not supported", "Sub template should error on unsupported channels") } diff --git a/exchanges/btse/btse_websocket.go b/exchanges/btse/btse_websocket.go index af4ae3eae33..22c545fc55b 100644 --- a/exchanges/btse/btse_websocket.go +++ b/exchanges/btse/btse_websocket.go @@ -40,29 +40,29 @@ var defaultSubscriptions = subscription.List{ } // WsConnect connects the websocket client -func (b *BTSE) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !b.Websocket.IsEnabled() || !b.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - b.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.PingMessage, Delay: btseWebsocketTimer, }) - b.Websocket.Wg.Add(1) - go b.wsReadData(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) - if b.IsWebsocketAuthenticationSupported() { - err = b.WsAuthenticate(ctx) + if e.IsWebsocketAuthenticationSupported() { + err = e.WsAuthenticate(ctx) if err != nil { - b.Websocket.DataHandler <- err - b.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.DataHandler <- err + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } @@ -70,8 +70,8 @@ func (b *BTSE) WsConnect() error { } // WsAuthenticate Send an authentication message to receive auth data -func (b *BTSE) WsAuthenticate(ctx context.Context) error { - creds, err := b.GetCredentials(ctx) +func (e *Exchange) WsAuthenticate(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -87,7 +87,7 @@ func (b *BTSE) WsAuthenticate(ctx context.Context) error { Operation: "authKeyExpires", Arguments: []string{creds.Key, nonce, hex.EncodeToString(hmac)}, } - return b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + return e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) } func stringToOrderStatus(status string) (order.Status, error) { @@ -112,22 +112,22 @@ func stringToOrderStatus(status string) (order.Status, error) { } // wsReadData receives and passes on websocket messages for processing -func (b *BTSE) wsReadData(ctx context.Context) { - defer b.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := b.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := b.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - b.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(_ context.Context, respRaw []byte) error { type Result map[string]any var result Result err := json.Unmarshal(respRaw, &result) @@ -144,7 +144,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { if result["event"] != nil { event, ok := result["event"].(string) if !ok { - return errors.New(b.Name + websocket.UnhandledMessage + string(respRaw)) + return errors.New(e.Name + websocket.UnhandledMessage + string(respRaw)) } switch event { case "subscribe": @@ -153,8 +153,8 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - if b.Verbose { - log.Infof(log.WebsocketMgr, "%v subscribed to %v", b.Name, strings.Join(subscribe.Channel, ", ")) + if e.Verbose { + log.Infof(log.WebsocketMgr, "%v subscribed to %v", e.Name, strings.Join(subscribe.Channel, ", ")) } case "login": var login WsLoginAcknowledgement @@ -162,19 +162,19 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - b.Websocket.SetCanUseAuthenticatedEndpoints(login.Success) - if b.Verbose { - log.Infof(log.WebsocketMgr, "%v websocket authenticated: %v", b.Name, login.Success) + e.Websocket.SetCanUseAuthenticatedEndpoints(login.Success) + if e.Verbose { + log.Infof(log.WebsocketMgr, "%v websocket authenticated: %v", e.Name, login.Success) } default: - return errors.New(b.Name + websocket.UnhandledMessage + string(respRaw)) + return errors.New(e.Name + websocket.UnhandledMessage + string(respRaw)) } return nil } topic, ok := result["topic"].(string) if !ok { - return errors.New(b.Name + websocket.UnhandledMessage + string(respRaw)) + return errors.New(e.Name + websocket.UnhandledMessage + string(respRaw)) } switch { case topic == "notificationApi": @@ -189,24 +189,24 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { var oStatus order.Status oType, err = order.StringToOrderType(notification.Data[i].Type) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: notification.Data[i].OrderID, Err: err, } } oSide, err = order.StringToOrderSide(notification.Data[i].OrderMode) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: notification.Data[i].OrderID, Err: err, } } oStatus, err = stringToOrderStatus(notification.Data[i].Status) if err != nil { - b.Websocket.DataHandler <- order.ClassificationError{ - Exchange: b.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: notification.Data[i].OrderID, Err: err, } @@ -219,16 +219,16 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { } var a asset.Item - a, err = b.GetPairAssetType(p) + a, err = e.GetPairAssetType(p) if err != nil { return err } - b.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: notification.Data[i].Price, Amount: notification.Data[i].Size, TriggerPrice: notification.Data[i].TriggerPrice, - Exchange: b.Name, + Exchange: e.Name, OrderID: notification.Data[i].OrderID, Type: oType, Side: oSide, @@ -239,8 +239,8 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { } } case strings.Contains(topic, "tradeHistoryApi"): - saveTradeData := b.IsSaveTradeDataEnabled() - tradeFeed := b.IsTradeFeedEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() + tradeFeed := e.IsTradeFeedEnabled() if !saveTradeData && !tradeFeed { return nil } @@ -258,7 +258,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { return err } var a asset.Item - a, err = b.GetPairAssetType(p) + a, err = e.GetPairAssetType(p) if err != nil { return err } @@ -266,7 +266,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { Timestamp: tradeHistory.Data[x].Timestamp.Time().UTC(), CurrencyPair: p, AssetType: a, - Exchange: b.Name, + Exchange: e.Name, Price: tradeHistory.Data[x].Price, Amount: tradeHistory.Data[x].Size, Side: tradeHistory.Data[x].Side, @@ -275,7 +275,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { } if tradeFeed { for i := range trades { - b.Websocket.DataHandler <- trades[i] + e.Websocket.DataHandler <- trades[i] } } if saveTradeData { @@ -303,7 +303,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - if b.orderbookFilter(price, amount) { + if e.orderbookFilter(price, amount) { continue } newOB.Asks = append(newOB.Asks, orderbook.Level{ @@ -322,7 +322,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - if b.orderbookFilter(price, amount) { + if e.orderbookFilter(price, amount) { continue } newOB.Bids = append(newOB.Bids, orderbook.Level{ @@ -335,22 +335,22 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { return err } var a asset.Item - a, err = b.GetPairAssetType(p) + a, err = e.GetPairAssetType(p) if err != nil { return err } newOB.Pair = p newOB.Asset = a - newOB.Exchange = b.Name + newOB.Exchange = e.Name newOB.Asks.Reverse() // Reverse asks for correct alignment - newOB.ValidateOrderbook = b.ValidateOrderbook + newOB.ValidateOrderbook = e.ValidateOrderbook newOB.LastUpdated = time.Now() // NOTE: Temp to fix test. - err = b.Websocket.Orderbook.LoadSnapshot(&newOB) + err = e.Websocket.Orderbook.LoadSnapshot(&newOB) if err != nil { return err } default: - return errors.New(b.Name + websocket.UnhandledMessage + string(respRaw)) + return errors.New(e.Name + websocket.UnhandledMessage + string(respRaw)) } return nil @@ -358,7 +358,7 @@ func (b *BTSE) wsHandleData(_ context.Context, respRaw []byte) error { // orderbookFilter is needed on book levels from this exchange as their data // is incorrect -func (b *BTSE) orderbookFilter(price, amount float64) bool { +func (e *Exchange) orderbookFilter(price, amount float64) bool { // Amount filtering occurs when the amount exceeds the decimal returned. // e.g. {"price":"1.37","size":"0.00"} currency: SFI-ETH // Opted to not round up to 0.01 as this might skew calculations @@ -372,12 +372,12 @@ func (b *BTSE) orderbookFilter(price, amount float64) bool { } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (b *BTSE) generateSubscriptions() (subscription.List, error) { - return b.Features.Subscriptions.ExpandTemplates(b) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (b *BTSE) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "isSymbolChannel": isSymbolChannel, @@ -385,29 +385,29 @@ func (b *BTSE) GetSubscriptionTemplate(_ *subscription.Subscription) (*template. } // Subscribe sends a websocket message to receive data from a list of channels -func (b *BTSE) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() req := wsSub{Operation: "subscribe"} for _, s := range subs { req.Arguments = append(req.Arguments, s.QualifiedChannel) } - err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) if err == nil { - err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, subs...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, subs...) } return err } // Unsubscribe sends a websocket message to stop receiving data from a list of channels -func (b *BTSE) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() req := wsSub{Operation: "unsubscribe"} for _, s := range subs { req.Arguments = append(req.Arguments, s.QualifiedChannel) } - err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) if err == nil { - err = b.Websocket.RemoveSubscriptions(b.Websocket.Conn, subs...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, subs...) } return err } diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 6d8931741ea..3e72593e8ec 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -38,12 +38,12 @@ var ( ) // SetDefaults sets the basic defaults for BTSE -func (b *BTSE) SetDefaults() { - b.Name = "BTSE" - b.Enabled = true - b.Verbose = true - b.API.CredentialsValidator.RequiresKey = true - b.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "BTSE" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for _, a := range []asset.Item{asset.Spot, asset.Futures} { ps := currency.PairStore{ @@ -54,12 +54,12 @@ func (b *BTSE) SetDefaults() { if a == asset.Spot { ps.RequestFormat.Delimiter = currency.DashDelimiter } - if err := b.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", b.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } - b.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -129,14 +129,14 @@ func (b *BTSE) SetDefaults() { } var err error - b.Requester, err = request.New(b.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - b.API.Endpoints = b.NewEndpoints() - err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: btseAPIURL, exchange.RestFutures: btseAPIURL, exchange.WebsocketSpot: btseWebsocket, @@ -144,55 +144,55 @@ func (b *BTSE) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - b.Websocket = websocket.NewManager() - b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - b.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (b *BTSE) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - b.SetEnabled(false) + e.SetEnabled(false) return nil } - err = b.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = b.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: btseWebsocket, RunningURL: wsRunningURL, - Connector: b.WsConnect, - Subscriber: b.Subscribe, - Unsubscriber: b.Unsubscribe, - GenerateSubscriptions: b.generateSubscriptions, - Features: &b.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *BTSE) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - m, err := b.GetMarketSummary(ctx, "", a == asset.Spot) +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + m, err := e.GetMarketSummary(ctx, "", a == asset.Spot) if err != nil { return nil, err } @@ -210,27 +210,27 @@ func (b *BTSE) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.P // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *BTSE) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - a := b.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + a := e.GetAssetTypes(false) for i := range a { - pairs, err := b.FetchTradablePairs(ctx, a[i]) + pairs, err := e.FetchTradablePairs(ctx, a[i]) if err != nil { return err } - err = b.UpdatePairs(pairs, a[i], false, forceUpdate) + err = e.UpdatePairs(pairs, a[i], false, forceUpdate) if err != nil { return err } } - return b.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *BTSE) UpdateTickers(ctx context.Context, a asset.Item) error { - if !b.SupportsAsset(a) { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - tickers, err := b.GetMarketSummary(ctx, "", a == asset.Spot) + tickers, err := e.GetMarketSummary(ctx, "", a == asset.Spot) if err != nil { return err } @@ -247,7 +247,7 @@ func (b *BTSE) UpdateTickers(ctx context.Context, a asset.Item) error { Volume: tickers[x].Volume, High: tickers[x].High24Hr, OpenInterest: tickers[x].OpenInterest, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) } @@ -260,18 +260,18 @@ func (b *BTSE) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *BTSE) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if !b.SupportsAsset(a) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - symbol, err := b.FormatSymbol(p, a) + symbol, err := e.FormatSymbol(p, a) if err != nil { return nil, err } - ticks, err := b.GetMarketSummary(ctx, symbol, a == asset.Spot) + ticks, err := e.GetMarketSummary(ctx, symbol, a == asset.Spot) if err != nil { return nil, err } @@ -286,41 +286,41 @@ func (b *BTSE) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) Last: ticks[0].Last, Volume: ticks[0].Volume, High: ticks[0].High24Hr, - ExchangeName: b.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(b.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: b.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: b.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := b.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - a, err := b.FetchOrderbook(ctx, fPair.String(), 0, 0, 0, assetType == asset.Spot) + a, err := e.FetchOrderbook(ctx, fPair.String(), 0, 0, 0, assetType == asset.Spot) if err != nil { return book, err } book.Bids = make(orderbook.Levels, 0, len(a.BuyQuote)) for x := range a.BuyQuote { - if b.orderbookFilter(a.BuyQuote[x].Price, a.BuyQuote[x].Size) { + if e.orderbookFilter(a.BuyQuote[x].Price, a.BuyQuote[x].Size) { continue } book.Bids = append(book.Bids, orderbook.Level{ @@ -330,7 +330,7 @@ func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a } book.Asks = make(orderbook.Levels, 0, len(a.SellQuote)) for x := range a.SellQuote { - if b.orderbookFilter(a.SellQuote[x].Price, a.SellQuote[x].Size) { + if e.orderbookFilter(a.SellQuote[x].Price, a.SellQuote[x].Size) { continue } book.Asks = append(book.Asks, orderbook.Level{ @@ -340,20 +340,20 @@ func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a } book.Asks.SortAsks() book.Pair = p - book.Exchange = b.Name + book.Exchange = e.Name book.Asset = assetType err = book.Process() if err != nil { return book, err } - return orderbook.Get(b.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // BTSE exchange -func (b *BTSE) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var a account.Holdings - balance, err := b.GetWalletInformation(ctx) + balance, err := e.GetWalletInformation(ctx) if err != nil { return a, err } @@ -367,7 +367,7 @@ func (b *BTSE) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc Free: balance[b].Available, } } - a.Exchange = b.Name + a.Exchange = e.Name a.Accounts = []account.SubAccount{ { AssetType: assetType, @@ -375,7 +375,7 @@ func (b *BTSE) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc }, } - creds, err := b.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -389,26 +389,26 @@ func (b *BTSE) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (b *BTSE) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *BTSE) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { return nil, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *BTSE) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = b.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } const limit = 500 var tradeData []Trade - tradeData, err = b.GetTrades(ctx, + tradeData, err = e.GetTrades(ctx, p.String(), time.Time{}, time.Time{}, 0, 0, limit, @@ -425,7 +425,7 @@ func (b *BTSE) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a return nil, err } resp[i] = trade.Data{ - Exchange: b.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].SerialID, 10), CurrencyPair: p, AssetType: assetType, @@ -435,7 +435,7 @@ func (b *BTSE) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a Timestamp: tradeData[i].Time.Time(), } } - err = b.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -445,22 +445,22 @@ func (b *BTSE) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *BTSE) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *BTSE) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(b.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } - r, err := b.CreateOrder(ctx, + r, err := e.CreateOrder(ctx, s.ClientID, 0.0, false, s.Price, @@ -485,22 +485,22 @@ func (b *BTSE) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTSE) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *BTSE) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - fPair, err := b.FormatExchangeCurrency(o.Pair, o.AssetType) + fPair, err := e.FormatExchangeCurrency(o.Pair, o.AssetType) if err != nil { return err } - _, err = b.CancelExistingOrder(ctx, o.OrderID, fPair.String(), o.ClientOrderID) + _, err = e.CancelExistingOrder(ctx, o.OrderID, fPair.String(), o.ClientOrderID) if err != nil { return err } @@ -509,27 +509,27 @@ func (b *BTSE) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *BTSE) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair // If product ID is sent, all orders of that specified market will be cancelled // If not specified, all orders of all markets will be cancelled -func (b *BTSE) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } var resp order.CancelAllResponse - fPair, err := b.FormatExchangeCurrency(orderCancellation.Pair, + fPair, err := e.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) if err != nil { return resp, err } - allOrders, err := b.CancelExistingOrder(ctx, "", fPair.String(), "") + allOrders, err := e.CancelExistingOrder(ctx, "", fPair.String(), "") if err != nil { return resp, err } @@ -555,8 +555,8 @@ func orderIntToType(i int) order.Type { } // GetOrderInfo returns order information based on order ID -func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { - o, err := b.GetOrders(ctx, "", orderID, "") +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { + o, err := e.GetOrders(ctx, "", orderID, "") if err != nil { return nil, err } @@ -566,7 +566,7 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair return nil, errors.New("no orders found") } - format, err := b.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -586,10 +586,10 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair if err != nil { log.Errorf(log.ExchangeSys, "%s GetOrderInfo unable to parse currency pair: %s\n", - b.Name, + e.Name, err) } - od.Exchange = b.Name + od.Exchange = e.Name od.Amount = o[i].Size od.OrderID = o[i].OrderID od.Date = o[i].Timestamp.Time() @@ -599,10 +599,10 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair od.Price = o[i].Price if od.Status, err = order.StringToOrderStatus(o[i].OrderState); err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } - th, err := b.TradeHistory(ctx, + th, err := e.TradeHistory(ctx, "", time.Time{}, time.Time{}, 0, 0, 0, @@ -623,7 +623,7 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair TID: th[i].TradeID, Price: th[i].Price, Amount: th[i].Size, - Exchange: b.Name, + Exchange: e.Name, Side: orderSide, Fee: th[i].FeeAmount, }) @@ -633,8 +633,8 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair } // GetDepositAddress returns a deposit address for a specified currency -func (b *BTSE) GetDepositAddress(ctx context.Context, c currency.Code, _, _ string) (*deposit.Address, error) { - address, err := b.GetWalletAddress(ctx, c.String()) +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, _, _ string) (*deposit.Address, error) { + address, err := e.GetWalletAddress(ctx, c.String()) if err != nil { return nil, err } @@ -648,7 +648,7 @@ func (b *BTSE) GetDepositAddress(ctx context.Context, c currency.Code, _, _ stri } if len(address) == 0 { - addressCreate, err := b.CreateWalletAddress(ctx, c.String()) + addressCreate, err := e.CreateWalletAddress(ctx, c.String()) if err != nil { return nil, err } @@ -670,12 +670,12 @@ func (b *BTSE) GetDepositAddress(ctx context.Context, c currency.Code, _, _ stri // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } amountToString := strconv.FormatFloat(withdrawRequest.Amount, 'f', 8, 64) - resp, err := b.WalletWithdrawal(ctx, + resp, err := e.WalletWithdrawal(ctx, withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, @@ -684,25 +684,25 @@ func (b *BTSE) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest return nil, err } return &withdraw.ExchangeResponse{ - Name: b.Name, + Name: e.Name, ID: resp.WithdrawID, }, nil } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -714,16 +714,16 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest var orders []order.Detail for x := range req.Pairs { - formattedPair, err := b.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + formattedPair, err := e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } - resp, err := b.GetOrders(ctx, formattedPair.String(), "", "") + resp, err := e.GetOrders(ctx, formattedPair.String(), "", "") if err != nil { return nil, err } - format, err := b.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -736,7 +736,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest status, err := order.StringToOrderStatus(resp[i].OrderState) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } p, err := currency.NewPairDelimiter(resp[i].Symbol, @@ -744,13 +744,13 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest if err != nil { log.Errorf(log.ExchangeSys, "%s GetActiveOrders unable to parse currency pair: %s\n", - b.Name, + e.Name, err) } openOrder := order.Detail{ Pair: p, - Exchange: b.Name, + Exchange: e.Name, Amount: resp[i].Size, ExecutedAmount: resp[i].FilledSize, RemainingAmount: resp[i].Size - resp[i].FilledSize, @@ -762,7 +762,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest Type: orderIntToType(resp[i].OrderType), } - fills, err := b.TradeHistory(ctx, + fills, err := e.TradeHistory(ctx, "", time.Time{}, time.Time{}, 0, 0, 0, @@ -771,7 +771,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest if err != nil { log.Errorf(log.ExchangeSys, "%s: Unable to get order fills for orderID %s", - b.Name, + e.Name, resp[i].OrderID) continue } @@ -787,7 +787,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest TID: fills[i].TradeID, Price: fills[i].Price, Amount: fills[i].Size, - Exchange: b.Name, + Exchange: e.Name, Side: orderSide, Fee: fills[i].FeeAmount, }) @@ -795,7 +795,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest orders = append(orders, openOrder) } } - return req.Filter(b.Name, orders), nil + return req.Filter(e.Name, orders), nil } func matchType(input int, required order.Type) bool { @@ -807,7 +807,7 @@ func matchType(input int, required order.Type) bool { // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { err := getOrdersRequest.Validate() if err != nil { return nil, err @@ -816,18 +816,18 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mult var resp []order.Detail if len(getOrdersRequest.Pairs) == 0 { var err error - getOrdersRequest.Pairs, err = b.GetEnabledPairs(asset.Spot) + getOrdersRequest.Pairs, err = e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } } orderDeref := *getOrdersRequest for x := range orderDeref.Pairs { - fPair, err := b.FormatExchangeCurrency(orderDeref.Pairs[x], asset.Spot) + fPair, err := e.FormatExchangeCurrency(orderDeref.Pairs[x], asset.Spot) if err != nil { return nil, err } - currentOrder, err := b.GetOrders(ctx, fPair.String(), "", "") + currentOrder, err := e.GetOrders(ctx, fPair.String(), "", "") if err != nil { return nil, err } @@ -837,7 +837,7 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mult } orderStatus, err := order.StringToOrderStatus(currentOrder[y].OrderState) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", b.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var orderSide order.Side orderSide, err = order.StringToOrderSide(currentOrder[y].Side) @@ -847,7 +847,7 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mult tempOrder := order.Detail{ OrderID: currentOrder[y].OrderID, ClientID: currentOrder[y].ClOrderID, - Exchange: b.Name, + Exchange: e.Name, Price: currentOrder[y].Price, AverageExecutedPrice: currentOrder[y].AverageFillPrice, Amount: currentOrder[y].Size, @@ -862,51 +862,51 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mult resp = append(resp, tempOrder) } } - return getOrdersRequest.Filter(b.Name, resp), nil + return getOrdersRequest.Filter(e.Name, resp), nil } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *BTSE) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !b.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (b *BTSE) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := b.UpdateAccountInfo(ctx, assetType) - return b.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval formats kline interval to exchange requested type -func (b *BTSE) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { return strconv.FormatFloat(in.Duration().Minutes(), 'f', 0, 64) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *BTSE) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { switch a { case asset.Spot, asset.Futures: default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - req, err := b.GetKlineRequest(pair, a, interval, start, end, false) + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - intervalInt, err := strconv.Atoi(b.FormatExchangeKlineInterval(req.ExchangeInterval)) + intervalInt, err := strconv.Atoi(e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } - candles, err := b.GetOHLCV(ctx, + candles, err := e.GetOHLCV(ctx, req.RequestFormatted.String(), req.Start, req.End.Add(-req.ExchangeInterval.Duration()), // End time is inclusive, so we need to subtract the interval. @@ -931,25 +931,25 @@ func (b *BTSE) GetHistoricCandles(ctx context.Context, pair currency.Pair, a ass } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *BTSE) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { switch a { case asset.Spot, asset.Futures: default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - req, err := b.GetKlineExtendedRequest(pair, a, interval, start, end) + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } - intervalInt, err := strconv.Atoi(b.FormatExchangeKlineInterval(req.ExchangeInterval)) + intervalInt, err := strconv.Atoi(e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } timeSeries := make([]kline.Candle, req.Size()) for i := range req.RangeHolder.Ranges { var candles OHLCV - candles, err = b.GetOHLCV(ctx, + candles, err = e.GetOHLCV(ctx, req.RequestFormatted.String(), req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time, @@ -974,8 +974,8 @@ func (b *BTSE) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pai } // GetServerTime returns the current exchange server time. -func (b *BTSE) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - st, err := b.GetCurrentServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + st, err := e.GetCurrentServerTime(ctx) if err != nil { return time.Time{}, err } @@ -1049,8 +1049,8 @@ func (m *MarketPair) Pair() (currency.Pair, error) { // - Pairs with an exponent counterpart pair are removed // BTSE lists M_ symbols for very small pairs, in millions. For those listings, we want to take the M_ listing in preference // to the native listing, since they're often going to appear as locked markets due to size (bid == ask, e.g. 0.0000000003) -func (b *BTSE) GetMarketSummary(ctx context.Context, symbol string, spot bool) (MarketSummary, error) { - m, err := b.GetRawMarketSummary(ctx, symbol, spot) +func (e *Exchange) GetMarketSummary(ctx context.Context, symbol string, spot bool) (MarketSummary, error) { + m, err := e.GetRawMarketSummary(ctx, symbol, spot) if err != nil { return m, err } @@ -1077,14 +1077,14 @@ func (b *BTSE) GetMarketSummary(ctx context.Context, symbol string, spot bool) ( } // GetFuturesContractDetails returns details about futures contracts -func (b *BTSE) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } if item != asset.Futures { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } - marketSummary, err := b.GetMarketSummary(ctx, "", false) + marketSummary, err := e.GetMarketSummary(ctx, "", false) if err != nil { return nil, err } @@ -1096,16 +1096,16 @@ func (b *BTSE) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( return nil, err } settlementCurrencies := make(currency.Currencies, len(marketSummary[i].AvailableSettlement)) - var s, e time.Time + var startTime, endTime time.Time var ct futures.ContractType if !marketSummary[i].OpenTime.Time().IsZero() { - s = marketSummary[i].OpenTime.Time() + startTime = marketSummary[i].OpenTime.Time() } if !marketSummary[i].CloseTime.Time().IsZero() { - e = marketSummary[i].CloseTime.Time() + endTime = marketSummary[i].CloseTime.Time() } if marketSummary[i].TimeBasedContract { - if e.Sub(s) > kline.OneMonth.Duration() { + if endTime.Sub(startTime) > kline.OneMonth.Duration() { ct = futures.Quarterly } else { ct = futures.Monthly @@ -1130,13 +1130,13 @@ func (b *BTSE) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( } c := futures.Contract{ - Exchange: b.Name, + Exchange: e.Name, Name: cp, Underlying: currency.NewPair(currency.NewCode(marketSummary[i].Base), currency.NewCode(marketSummary[i].Quote)), Asset: item, SettlementCurrencies: settlementCurrencies, - StartDate: s, - EndDate: e, + StartDate: startTime, + EndDate: endTime, SettlementType: contractSettlementType, IsActive: marketSummary[i].Active, Type: ct, @@ -1154,7 +1154,7 @@ func (b *BTSE) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( } // GetLatestFundingRates returns the latest funding rates data -func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1165,12 +1165,12 @@ func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR return nil, fmt.Errorf("%w IncludePredictedRate", common.ErrFunctionNotSupported) } - format, err := b.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } fPair := format.Format(r.Pair) - rates, err := b.GetMarketSummary(ctx, fPair, false) + rates, err := e.GetMarketSummary(ctx, fPair, false) if err != nil { return nil, err } @@ -1179,7 +1179,7 @@ func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR for i := range rates { var cp currency.Pair var isEnabled bool - cp, isEnabled, err = b.MatchSymbolCheckEnabled(rates[i].Symbol, r.Asset, true) + cp, isEnabled, err = e.MatchSymbolCheckEnabled(rates[i].Symbol, r.Asset, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1187,7 +1187,7 @@ func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR continue } var isPerp bool - isPerp, err = b.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -1196,7 +1196,7 @@ func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR } tt := time.Now().Truncate(time.Hour) resp = append(resp, fundingrate.LatestRateResponse{ - Exchange: b.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -1211,13 +1211,13 @@ func (b *BTSE) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (b *BTSE) IsPerpetualFutureCurrency(a asset.Item, p currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, p currency.Pair) (bool, error) { return a == asset.Futures && p.Quote.Equal(currency.PFC), nil } // UpdateOrderExecutionLimits updates order execution limits -func (b *BTSE) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { - summary, err := b.GetMarketSummary(ctx, "", a == asset.Spot) +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { + summary, err := e.GetMarketSummary(ctx, "", a == asset.Spot) if err != nil { return err } @@ -1239,21 +1239,21 @@ func (b *BTSE) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) err PriceStepIncrementSize: marketInfo.MinPriceIncrement, }) } - if err = b.LoadLimits(limits); err != nil { + if err = e.LoadLimits(limits); err != nil { errs = common.AppendError(errs, err) } return errs } // GetOpenInterest returns the open interest rate for a given asset pair -func (b *BTSE) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { if k[i].Asset != asset.Futures { // avoid API calls or returning errors after a successful retrieval return nil, fmt.Errorf("%w %v %v", asset.ErrNotSupported, k[i].Asset, k[i].Pair()) } } - tickers, err := b.GetMarketSummary(ctx, "", false) + tickers, err := e.GetMarketSummary(ctx, "", false) if err != nil { return nil, err } @@ -1261,7 +1261,7 @@ func (b *BTSE) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur for i := range tickers { var symbol currency.Pair var enabled bool - symbol, enabled, err = b.MatchSymbolCheckEnabled(tickers[i].Symbol, asset.Futures, false) + symbol, enabled, err = e.MatchSymbolCheckEnabled(tickers[i].Symbol, asset.Futures, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1280,7 +1280,7 @@ func (b *BTSE) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: b.Name, + Exchange: e.Name, Base: symbol.Base.Item, Quote: symbol.Quote.Item, Asset: asset.Futures, @@ -1292,8 +1292,8 @@ func (b *BTSE) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (b *BTSE) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := b.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/bybit/bybit.go b/exchanges/bybit/bybit.go index 1510db65c88..302cd7a8905 100644 --- a/exchanges/bybit/bybit.go +++ b/exchanges/bybit/bybit.go @@ -26,8 +26,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/types" ) -// Bybit is the overarching type across this package -type Bybit struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bybit +type Exchange struct { exchange.Base account accountTypeHolder } @@ -114,13 +114,13 @@ func stringToInterval(s string) (kline.Interval, error) { } // GetBybitServerTime retrieves bybit server time -func (by *Bybit) GetBybitServerTime(ctx context.Context) (*ServerTime, error) { +func (e *Exchange) GetBybitServerTime(ctx context.Context) (*ServerTime, error) { var resp *ServerTime - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, "market/time", defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, "market/time", defaultEPL, &resp) } // GetKlines query for historical klines (also known as candles/candlesticks). Charts are returned in groups based on the requested interval. -func (by *Bybit) GetKlines(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit uint64) ([]KlineItem, error) { +func (e *Exchange) GetKlines(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit uint64) ([]KlineItem, error) { switch category { case "": return nil, errCategoryNotSet @@ -149,7 +149,7 @@ func (by *Bybit) GetKlines(ctx context.Context, category, symbol string, interva params.Set("limit", strconv.FormatUint(limit, 10)) } var resp KlineResponse - err = by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/kline", params), defaultEPL, &resp) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/kline", params), defaultEPL, &resp) if err != nil { return nil, err } @@ -157,7 +157,7 @@ func (by *Bybit) GetKlines(ctx context.Context, category, symbol string, interva } // GetInstrumentInfo retrieves the list of instrument details given the category and symbol. -func (by *Bybit) GetInstrumentInfo(ctx context.Context, category, symbol, status, baseCoin, cursor string, limit int64) (*InstrumentsInfo, error) { +func (e *Exchange) GetInstrumentInfo(ctx context.Context, category, symbol, status, baseCoin, cursor string, limit int64) (*InstrumentsInfo, error) { params, err := fillCategoryAndSymbol(category, symbol, true) if err != nil { return nil, err @@ -175,11 +175,11 @@ func (by *Bybit) GetInstrumentInfo(ctx context.Context, category, symbol, status params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *InstrumentsInfo - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/instruments-info", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/instruments-info", params), defaultEPL, &resp) } // GetMarkPriceKline query for historical mark price klines. Charts are returned in groups based on the requested interval. -func (by *Bybit) GetMarkPriceKline(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit int64) ([]KlineItem, error) { +func (e *Exchange) GetMarkPriceKline(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit int64) ([]KlineItem, error) { params, err := fillCategoryAndSymbol(category, symbol) if err != nil { return nil, err @@ -199,7 +199,7 @@ func (by *Bybit) GetMarkPriceKline(ctx context.Context, category, symbol string, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp MarkPriceKlineResponse - err = by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/mark-price-kline", params), defaultEPL, &resp) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/mark-price-kline", params), defaultEPL, &resp) if err != nil { return nil, err } @@ -207,7 +207,7 @@ func (by *Bybit) GetMarkPriceKline(ctx context.Context, category, symbol string, } // GetIndexPriceKline query for historical index price klines. Charts are returned in groups based on the requested interval. -func (by *Bybit) GetIndexPriceKline(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit int64) ([]KlineItem, error) { +func (e *Exchange) GetIndexPriceKline(ctx context.Context, category, symbol string, interval kline.Interval, startTime, endTime time.Time, limit int64) ([]KlineItem, error) { params, err := fillCategoryAndSymbol(category, symbol) if err != nil { return nil, err @@ -227,7 +227,7 @@ func (by *Bybit) GetIndexPriceKline(ctx context.Context, category, symbol string params.Set("limit", strconv.FormatInt(limit, 10)) } var resp KlineResponse - err = by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/index-price-kline", params), defaultEPL, &resp) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/index-price-kline", params), defaultEPL, &resp) if err != nil { return nil, err } @@ -235,7 +235,7 @@ func (by *Bybit) GetIndexPriceKline(ctx context.Context, category, symbol string } // GetOrderBook retrieves for orderbook depth data. -func (by *Bybit) GetOrderBook(ctx context.Context, category, symbol string, limit int64) (*Orderbook, error) { +func (e *Exchange) GetOrderBook(ctx context.Context, category, symbol string, limit int64) (*Orderbook, error) { params, err := fillCategoryAndSymbol(category, symbol) if err != nil { return nil, err @@ -244,7 +244,7 @@ func (by *Bybit) GetOrderBook(ctx context.Context, category, symbol string, limi params.Set("limit", strconv.FormatInt(limit, 10)) } var resp orderbookResponse - err = by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/orderbook", params), defaultEPL, &resp) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/orderbook", params), defaultEPL, &resp) if err != nil { return nil, err } @@ -268,7 +268,7 @@ func fillCategoryAndSymbol(category, symbol string, optionalSymbol ...bool) (url } // GetTickers returns the latest price snapshot, best bid/ask price, and trading volume in the last 24 hours. -func (by *Bybit) GetTickers(ctx context.Context, category, symbol, baseCoin string, expiryDate time.Time) (*TickerData, error) { +func (e *Exchange) GetTickers(ctx context.Context, category, symbol, baseCoin string, expiryDate time.Time) (*TickerData, error) { params, err := fillCategoryAndSymbol(category, symbol, true) if err != nil { return nil, err @@ -283,12 +283,12 @@ func (by *Bybit) GetTickers(ctx context.Context, category, symbol, baseCoin stri params.Set("expData", expiryDate.Format(longDatedFormat)) } var resp *TickerData - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/tickers", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/tickers", params), defaultEPL, &resp) } // GetFundingRateHistory retrieves historical funding rates. Each symbol has a different funding interval. // For example, if the interval is 8 hours and the current time is UTC 12, then it returns the last funding rate, which settled at UTC 8. -func (by *Bybit) GetFundingRateHistory(ctx context.Context, category, symbol string, startTime, endTime time.Time, limit int64) (*FundingRateHistory, error) { +func (e *Exchange) GetFundingRateHistory(ctx context.Context, category, symbol string, startTime, endTime time.Time, limit int64) (*FundingRateHistory, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse { @@ -310,12 +310,12 @@ func (by *Bybit) GetFundingRateHistory(ctx context.Context, category, symbol str params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *FundingRateHistory - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/funding/history", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/funding/history", params), defaultEPL, &resp) } // GetPublicTradingHistory retrieves recent public trading data. // Option type. 'Call' or 'Put'. For option only -func (by *Bybit) GetPublicTradingHistory(ctx context.Context, category, symbol, baseCoin, optionType string, limit int64) (*TradingHistory, error) { +func (e *Exchange) GetPublicTradingHistory(ctx context.Context, category, symbol, baseCoin, optionType string, limit int64) (*TradingHistory, error) { params, err := fillCategoryAndSymbol(category, symbol) if err != nil { return nil, err @@ -333,11 +333,11 @@ func (by *Bybit) GetPublicTradingHistory(ctx context.Context, category, symbol, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *TradingHistory - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/recent-trade", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/recent-trade", params), defaultEPL, &resp) } // GetOpenInterestData retrieves open interest of each symbol. -func (by *Bybit) GetOpenInterestData(ctx context.Context, category, symbol, intervalTime string, startTime, endTime time.Time, limit int64, cursor string) (*OpenInterest, error) { +func (e *Exchange) GetOpenInterestData(ctx context.Context, category, symbol, intervalTime string, startTime, endTime time.Time, limit int64, cursor string) (*OpenInterest, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse { @@ -365,7 +365,7 @@ func (by *Bybit) GetOpenInterestData(ctx context.Context, category, symbol, inte params.Set("cursor", cursor) } var resp *OpenInterest - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/open-interest", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/open-interest", params), defaultEPL, &resp) } // GetHistoricalVolatility retrieves option historical volatility. @@ -373,7 +373,7 @@ func (by *Bybit) GetOpenInterestData(ctx context.Context, category, symbol, inte // If both 'startTime' and 'endTime' are not specified, it will return the most recent 1 hours worth of data. // 'startTime' and 'endTime' are a pair of params. Either both are passed or they are not passed at all. // This endpoint can query the last 2 years worth of data, but make sure [endTime - startTime] <= 30 days. -func (by *Bybit) GetHistoricalVolatility(ctx context.Context, category, baseCoin string, period int64, startTime, endTime time.Time) ([]HistoricVolatility, error) { +func (e *Exchange) GetHistoricalVolatility(ctx context.Context, category, baseCoin string, period int64, startTime, endTime time.Time) ([]HistoricVolatility, error) { if category == "" { return nil, errCategoryNotSet } else if category != cOption { @@ -397,21 +397,21 @@ func (by *Bybit) GetHistoricalVolatility(ctx context.Context, category, baseCoin params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } var resp []HistoricVolatility - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/historical-volatility", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/historical-volatility", params), defaultEPL, &resp) } // GetInsurance retrieves insurance pool data (BTC/USDT/USDC etc). The data is updated every 24 hours. -func (by *Bybit) GetInsurance(ctx context.Context, coin string) (*InsuranceHistory, error) { +func (e *Exchange) GetInsurance(ctx context.Context, coin string) (*InsuranceHistory, error) { params := url.Values{} if coin != "" { params.Set("coin", coin) } var resp *InsuranceHistory - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/insurance", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/insurance", params), defaultEPL, &resp) } // GetRiskLimit retrieves risk limit history -func (by *Bybit) GetRiskLimit(ctx context.Context, category, symbol string) (*RiskLimitHistory, error) { +func (e *Exchange) GetRiskLimit(ctx context.Context, category, symbol string) (*RiskLimitHistory, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse { @@ -423,11 +423,11 @@ func (by *Bybit) GetRiskLimit(ctx context.Context, category, symbol string) (*Ri params.Set("symbol", symbol) } var resp *RiskLimitHistory - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/risk-limit", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/risk-limit", params), defaultEPL, &resp) } // GetDeliveryPrice retrieves delivery price. -func (by *Bybit) GetDeliveryPrice(ctx context.Context, category, symbol, baseCoin, cursor string, limit int64) (*DeliveryPrice, error) { +func (e *Exchange) GetDeliveryPrice(ctx context.Context, category, symbol, baseCoin, cursor string, limit int64) (*DeliveryPrice, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse && category != cOption { @@ -448,7 +448,7 @@ func (by *Bybit) GetDeliveryPrice(ctx context.Context, category, symbol, baseCoi params.Set("cursor", cursor) } var resp *DeliveryPrice - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/delivery-price", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/delivery-price", params), defaultEPL, &resp) } func isValidCategory(category string) error { @@ -463,7 +463,7 @@ func isValidCategory(category string) error { } // PlaceOrder creates an order for spot, spot margin, USDT perpetual, USDC perpetual, USDC futures, inverse futures and options. -func (by *Bybit) PlaceOrder(ctx context.Context, arg *PlaceOrderParams) (*OrderResponse, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, arg *PlaceOrderParams) (*OrderResponse, error) { if arg == nil { return nil, errNilArgument } @@ -513,11 +513,11 @@ func (by *Bybit) PlaceOrder(ctx context.Context, arg *PlaceOrderParams) (*OrderR if arg.Category == "spot" { epl = createSpotOrderEPL } - return &resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/create", nil, arg, &resp, epl) + return &resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/create", nil, arg, &resp, epl) } // AmendOrder amends an open unfilled or partially filled orders. -func (by *Bybit) AmendOrder(ctx context.Context, arg *AmendOrderParams) (*OrderResponse, error) { +func (e *Exchange) AmendOrder(ctx context.Context, arg *AmendOrderParams) (*OrderResponse, error) { if arg == nil { return nil, errNilArgument } @@ -532,11 +532,11 @@ func (by *Bybit) AmendOrder(ctx context.Context, arg *AmendOrderParams) (*OrderR return nil, currency.ErrCurrencyPairEmpty } var resp *OrderResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/amend", nil, arg, &resp, amendOrderEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/amend", nil, arg, &resp, amendOrderEPL) } // CancelTradeOrder cancels an open unfilled or partially filled order. -func (by *Bybit) CancelTradeOrder(ctx context.Context, arg *CancelOrderParams) (*OrderResponse, error) { +func (e *Exchange) CancelTradeOrder(ctx context.Context, arg *CancelOrderParams) (*OrderResponse, error) { if arg == nil { return nil, errNilArgument } @@ -566,12 +566,12 @@ func (by *Bybit) CancelTradeOrder(ctx context.Context, arg *CancelOrderParams) ( if arg.Category == "spot" { epl = cancelSpotEPL } - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel", nil, arg, &resp, epl) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel", nil, arg, &resp, epl) } // GetOpenOrders retrieves unfilled or partially filled orders in real-time. To query older order records, please use the order history interface. // orderFilter: possible values are 'Order', 'StopOrder', 'tpslOrder', and 'OcoOrder' -func (by *Bybit) GetOpenOrders(ctx context.Context, category, symbol, baseCoin, settleCoin, orderID, orderLinkID, orderFilter, cursor string, openOnly, limit int64) (*TradeOrders, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, category, symbol, baseCoin, settleCoin, orderID, orderLinkID, orderFilter, cursor string, openOnly, limit int64) (*TradeOrders, error) { params, err := fillCategoryAndSymbol(category, symbol, true) if err != nil { return nil, err @@ -601,11 +601,11 @@ func (by *Bybit) GetOpenOrders(ctx context.Context, category, symbol, baseCoin, params.Set("cursor", cursor) } var resp *TradeOrders - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/realtime", params, nil, &resp, getOrderEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/realtime", params, nil, &resp, getOrderEPL) } // CancelAllTradeOrders cancel all open orders -func (by *Bybit) CancelAllTradeOrders(ctx context.Context, arg *CancelAllOrdersParam) ([]OrderResponse, error) { +func (e *Exchange) CancelAllTradeOrders(ctx context.Context, arg *CancelAllOrdersParam) ([]OrderResponse, error) { if arg == nil { return nil, errNilArgument } @@ -621,13 +621,13 @@ func (by *Bybit) CancelAllTradeOrders(ctx context.Context, arg *CancelAllOrdersP if arg.Category == "spot" { epl = cancelAllSpotEPL } - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel-all", nil, arg, &resp, epl) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel-all", nil, arg, &resp, epl) } // GetTradeOrderHistory retrieves order history. As order creation/cancellation is asynchronous, the data returned from this endpoint may delay. // If you want to get real-time order information, you could query this endpoint or rely on the websocket stream (recommended). // orderFilter: possible values are 'Order', 'StopOrder', 'tpslOrder', and 'OcoOrder' -func (by *Bybit) GetTradeOrderHistory(ctx context.Context, category, symbol, orderID, orderLinkID, +func (e *Exchange) GetTradeOrderHistory(ctx context.Context, category, symbol, orderID, orderLinkID, baseCoin, settleCoin, orderFilter, orderStatus, cursor string, startTime, endTime time.Time, limit int64, ) (*TradeOrders, error) { @@ -666,11 +666,11 @@ func (by *Bybit) GetTradeOrderHistory(ctx context.Context, category, symbol, ord params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *TradeOrders - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/history", params, nil, &resp, getOrderHistoryEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/history", params, nil, &resp, getOrderHistoryEPL) } // PlaceBatchOrder place batch or trade order. -func (by *Bybit) PlaceBatchOrder(ctx context.Context, arg *PlaceBatchOrderParam) ([]BatchOrderResponse, error) { +func (e *Exchange) PlaceBatchOrder(ctx context.Context, arg *PlaceBatchOrderParam) ([]BatchOrderResponse, error) { if arg == nil { return nil, errNilArgument } @@ -701,11 +701,11 @@ func (by *Bybit) PlaceBatchOrder(ctx context.Context, arg *PlaceBatchOrderParam) } } var resp BatchOrdersList - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/create-batch", nil, arg, &resp, createBatchOrderEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/create-batch", nil, arg, &resp, createBatchOrderEPL) } // BatchAmendOrder represents a batch amend order. -func (by *Bybit) BatchAmendOrder(ctx context.Context, category string, args []BatchAmendOrderParamItem) (*BatchOrderResponse, error) { +func (e *Exchange) BatchAmendOrder(ctx context.Context, category string, args []BatchAmendOrderParamItem) (*BatchOrderResponse, error) { if len(args) == 0 { return nil, errNilArgument } @@ -724,14 +724,14 @@ func (by *Bybit) BatchAmendOrder(ctx context.Context, category string, args []Ba } } var resp *BatchOrderResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/amend-batch", nil, &BatchAmendOrderParams{ + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/amend-batch", nil, &BatchAmendOrderParams{ Category: category, Request: args, }, &resp, amendBatchOrderEPL) } // CancelBatchOrder cancel more than one open order in a single request. -func (by *Bybit) CancelBatchOrder(ctx context.Context, arg *CancelBatchOrder) ([]CancelBatchResponseItem, error) { +func (e *Exchange) CancelBatchOrder(ctx context.Context, arg *CancelBatchOrder) ([]CancelBatchResponseItem, error) { if arg == nil { return nil, errNilArgument } @@ -750,11 +750,11 @@ func (by *Bybit) CancelBatchOrder(ctx context.Context, arg *CancelBatchOrder) ([ } } var resp cancelBatchResponse - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel-batch", nil, arg, &resp, cancelBatchOrderEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/cancel-batch", nil, arg, &resp, cancelBatchOrderEPL) } // GetBorrowQuota retrieves the qty and amount of borrowable coins in spot account. -func (by *Bybit) GetBorrowQuota(ctx context.Context, category, symbol, side string) (*BorrowQuota, error) { +func (e *Exchange) GetBorrowQuota(ctx context.Context, category, symbol, side string) (*BorrowQuota, error) { if category == "" { return nil, errCategoryNotSet } else if category != cSpot { @@ -771,23 +771,23 @@ func (by *Bybit) GetBorrowQuota(ctx context.Context, category, symbol, side stri } params.Set("side", side) var resp *BorrowQuota - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/spot-borrow-check", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/order/spot-borrow-check", params, nil, &resp, defaultEPL) } // SetDisconnectCancelAll You can use this endpoint to get your current DCP configuration. // Your private websocket connection must subscribe "dcp" topic in order to trigger DCP successfully -func (by *Bybit) SetDisconnectCancelAll(ctx context.Context, arg *SetDCPParams) error { +func (e *Exchange) SetDisconnectCancelAll(ctx context.Context, arg *SetDCPParams) error { if arg == nil { return errNilArgument } if arg.TimeWindow == 0 { return errDisconnectTimeWindowNotSet } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/disconnected-cancel-all", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/order/disconnected-cancel-all", nil, arg, &struct{}{}, defaultEPL) } // GetPositionInfo retrieves real-time position data, such as position size, cumulative realizedPNL. -func (by *Bybit) GetPositionInfo(ctx context.Context, category, symbol, baseCoin, settleCoin, cursor string, limit int64) (*PositionInfoList, error) { +func (e *Exchange) GetPositionInfo(ctx context.Context, category, symbol, baseCoin, settleCoin, cursor string, limit int64) (*PositionInfoList, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse && category != cOption { @@ -814,11 +814,11 @@ func (by *Bybit) GetPositionInfo(ctx context.Context, category, symbol, baseCoin params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *PositionInfoList - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/position/list", params, nil, &resp, getPositionListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/position/list", params, nil, &resp, getPositionListEPL) } // SetLeverageLevel sets a leverage from 0 to max leverage of corresponding risk limit -func (by *Bybit) SetLeverageLevel(ctx context.Context, arg *SetLeverageParams) error { +func (e *Exchange) SetLeverageLevel(ctx context.Context, arg *SetLeverageParams) error { if arg == nil { return errNilArgument } @@ -838,12 +838,12 @@ func (by *Bybit) SetLeverageLevel(ctx context.Context, arg *SetLeverageParams) e case arg.BuyLeverage != arg.SellLeverage: return fmt.Errorf("%w, buy leverage not equal sell leverage", errInvalidLeverage) } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-leverage", nil, arg, &struct{}{}, postPositionSetLeverageEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-leverage", nil, arg, &struct{}{}, postPositionSetLeverageEPL) } // SwitchTradeMode sets the trade mode value either to 'cross' or 'isolated'. // Select cross margin mode or isolated margin mode per symbol level -func (by *Bybit) SwitchTradeMode(ctx context.Context, arg *SwitchTradeModeParams) error { +func (e *Exchange) SwitchTradeMode(ctx context.Context, arg *SwitchTradeModeParams) error { if arg == nil { return errNilArgument } @@ -864,11 +864,11 @@ func (by *Bybit) SwitchTradeMode(ctx context.Context, arg *SwitchTradeModeParams case arg.TradeMode != 0 && arg.TradeMode != 1: return errInvalidTradeModeValue } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/switch-isolated", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/switch-isolated", nil, arg, &struct{}{}, defaultEPL) } // SetTakeProfitStopLossMode set partial TP/SL mode, you can set the TP/SL size smaller than position size. -func (by *Bybit) SetTakeProfitStopLossMode(ctx context.Context, arg *TPSLModeParams) (*TPSLModeResponse, error) { +func (e *Exchange) SetTakeProfitStopLossMode(ctx context.Context, arg *TPSLModeParams) (*TPSLModeResponse, error) { if arg == nil { return nil, errNilArgument } @@ -886,14 +886,14 @@ func (by *Bybit) SetTakeProfitStopLossMode(ctx context.Context, arg *TPSLModePar return nil, errTakeProfitOrStopLossModeMissing } var resp *TPSLModeResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-tpsl-mode", nil, arg, &resp, setPositionTPLSModeEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-tpsl-mode", nil, arg, &resp, setPositionTPLSModeEPL) } // SwitchPositionMode switch the position mode for USDT perpetual and Inverse futures. // If you are in one-way Mode, you can only open one position on Buy or Sell side. // If you are in hedge mode, you can open both Buy and Sell side positions simultaneously. // switches mode between MergedSingle: One-Way Mode or BothSide: Hedge Mode -func (by *Bybit) SwitchPositionMode(ctx context.Context, arg *SwitchPositionModeParams) error { +func (e *Exchange) SwitchPositionMode(ctx context.Context, arg *SwitchPositionModeParams) error { if arg == nil { return errNilArgument } @@ -907,14 +907,14 @@ func (by *Bybit) SwitchPositionMode(ctx context.Context, arg *SwitchPositionMode if arg.Symbol.IsEmpty() && arg.Coin.IsEmpty() { return errEitherSymbolOrCoinRequired } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/switch-mode", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/switch-mode", nil, arg, &struct{}{}, defaultEPL) } // SetRiskLimit risk limit will limit the maximum position value you can hold under different margin requirements. // If you want to hold a bigger position size, you need more margin. This interface can set the risk limit of a single position. // If the order exceeds the current risk limit when placing an order, it will be rejected. // '0': one-way mode '1': hedge-mode Buy side '2': hedge-mode Sell side -func (by *Bybit) SetRiskLimit(ctx context.Context, arg *SetRiskLimitParam) (*RiskLimitResponse, error) { +func (e *Exchange) SetRiskLimit(ctx context.Context, arg *SetRiskLimitParam) (*RiskLimitResponse, error) { if arg == nil { return nil, errNilArgument } @@ -932,11 +932,11 @@ func (by *Bybit) SetRiskLimit(ctx context.Context, arg *SetRiskLimitParam) (*Ris return nil, errSymbolMissing } var resp *RiskLimitResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-risk-limit", nil, arg, &resp, setPositionRiskLimitEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-risk-limit", nil, arg, &resp, setPositionRiskLimitEPL) } // SetTradingStop set the take profit, stop loss or trailing stop for the position. -func (by *Bybit) SetTradingStop(ctx context.Context, arg *TradingStopParams) error { +func (e *Exchange) SetTradingStop(ctx context.Context, arg *TradingStopParams) error { if arg == nil { return errNilArgument } @@ -950,11 +950,11 @@ func (by *Bybit) SetTradingStop(ctx context.Context, arg *TradingStopParams) err if arg.Symbol.IsEmpty() { return errSymbolMissing } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/trading-stop", nil, arg, &struct{}{}, stopTradingPositionEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/trading-stop", nil, arg, &struct{}{}, stopTradingPositionEPL) } // SetAutoAddMargin sets auto add margin -func (by *Bybit) SetAutoAddMargin(ctx context.Context, arg *AutoAddMarginParam) error { +func (e *Exchange) SetAutoAddMargin(ctx context.Context, arg *AutoAddMarginParam) error { if arg == nil { return errNilArgument } @@ -974,11 +974,11 @@ func (by *Bybit) SetAutoAddMargin(ctx context.Context, arg *AutoAddMarginParam) if arg.PositionIndex < 0 || arg.PositionIndex > 2 { return errInvalidPositionMode } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-auto-add-margin", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/set-auto-add-margin", nil, arg, &struct{}{}, defaultEPL) } // AddOrReduceMargin manually add or reduce margin for isolated margin position -func (by *Bybit) AddOrReduceMargin(ctx context.Context, arg *AddOrReduceMarginParam) (*AddOrReduceMargin, error) { +func (e *Exchange) AddOrReduceMargin(ctx context.Context, arg *AddOrReduceMarginParam) (*AddOrReduceMargin, error) { if arg == nil { return nil, errNilArgument } @@ -999,13 +999,13 @@ func (by *Bybit) AddOrReduceMargin(ctx context.Context, arg *AddOrReduceMarginPa return nil, errInvalidPositionMode } var resp *AddOrReduceMargin - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/add-margin", nil, arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/add-margin", nil, arg, &resp, defaultEPL) } // GetExecution retrieves users' execution records, sorted by execTime in descending order. However, for Normal spot, they are sorted by execId in descending order. // Execution Type possible values: 'Trade', 'AdlTrade' Auto-Deleveraging, 'Funding' Funding fee, 'BustTrade' Liquidation, 'Delivery' USDC futures delivery, 'BlockTrade' // UTA Spot: 'stopOrderType', "" for normal order, "tpslOrder" for TP/SL order, "Stop" for conditional order, "OcoOrder" for OCO order -func (by *Bybit) GetExecution(ctx context.Context, category, symbol, orderID, orderLinkID, baseCoin, executionType, stopOrderType, cursor string, startTime, endTime time.Time, limit int64) (*ExecutionResponse, error) { +func (e *Exchange) GetExecution(ctx context.Context, category, symbol, orderID, orderLinkID, baseCoin, executionType, stopOrderType, cursor string, startTime, endTime time.Time, limit int64) (*ExecutionResponse, error) { params, err := fillCategoryAndSymbol(category, symbol, true) if err != nil { return nil, err @@ -1041,17 +1041,17 @@ func (by *Bybit) GetExecution(ctx context.Context, category, symbol, orderID, or params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *ExecutionResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/execution/list", params, nil, &resp, getExecutionListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/execution/list", params, nil, &resp, getExecutionListEPL) } // GetClosedPnL retrieves user's closed profit and loss records. The results are sorted by createdTime in descending order. -func (by *Bybit) GetClosedPnL(ctx context.Context, category, symbol, cursor string, startTime, endTime time.Time, limit int64) (*ClosedProfitAndLossResponse, error) { +func (e *Exchange) GetClosedPnL(ctx context.Context, category, symbol, cursor string, startTime, endTime time.Time, limit int64) (*ClosedProfitAndLossResponse, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true, Inverse: true}, category, symbol, "", "", "", "", "", cursor, startTime, endTime, limit) if err != nil { return nil, err } var resp *ClosedProfitAndLossResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/position/closed-pnl", params, nil, &resp, getPositionClosedPNLEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/position/closed-pnl", params, nil, &resp, getPositionClosedPNLEPL) } func fillOrderAndExecutionFetchParams(ac paramsConfig, category, symbol, baseCoin, orderID, orderLinkID, orderFilter, orderStatus, cursor string, startTime, endTime time.Time, limit int64) (url.Values, error) { @@ -1110,7 +1110,7 @@ func fillOrderAndExecutionFetchParams(ac paramsConfig, category, symbol, baseCoi // After the user actively adjusts the risk level, this interface is called to try to calculate the adjusted risk level, // and if it passes (retCode=0), the system will remove the position reduceOnly mark. // You are recommended to call Get Position Info to check isReduceOnly field. -func (by *Bybit) ConfirmNewRiskLimit(ctx context.Context, category, symbol string) error { +func (e *Exchange) ConfirmNewRiskLimit(ctx context.Context, category, symbol string) error { if category == "" { return errCategoryNotSet } @@ -1124,30 +1124,30 @@ func (by *Bybit) ConfirmNewRiskLimit(ctx context.Context, category, symbol strin Category: category, Symbol: symbol, } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/confirm-pending-mmr", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/position/confirm-pending-mmr", nil, arg, &struct{}{}, defaultEPL) } // GetPreUpgradeOrderHistory the account is upgraded to a Unified account, you can get the orders which occurred before the upgrade. -func (by *Bybit) GetPreUpgradeOrderHistory(ctx context.Context, category, symbol, baseCoin, orderID, orderLinkID, orderFilter, orderStatus, cursor string, startTime, endTime time.Time, limit int64) (*TradeOrders, error) { +func (e *Exchange) GetPreUpgradeOrderHistory(ctx context.Context, category, symbol, baseCoin, orderID, orderLinkID, orderFilter, orderStatus, cursor string, startTime, endTime time.Time, limit int64) (*TradeOrders, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true, Option: true, Inverse: true}, category, symbol, baseCoin, orderID, orderLinkID, orderFilter, orderStatus, cursor, startTime, endTime, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } var resp *TradeOrders - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/order/history", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/order/history", params, nil, &resp, defaultEPL) } // GetPreUpgradeTradeHistory retrieves users' execution records which occurred before you upgraded the account to a Unified account, sorted by execTime in descending order -func (by *Bybit) GetPreUpgradeTradeHistory(ctx context.Context, category, symbol, orderID, orderLinkID, baseCoin, executionType, cursor string, startTime, endTime time.Time, limit int64) (*ExecutionResponse, error) { +func (e *Exchange) GetPreUpgradeTradeHistory(ctx context.Context, category, symbol, orderID, orderLinkID, baseCoin, executionType, cursor string, startTime, endTime time.Time, limit int64) (*ExecutionResponse, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true, Option: false, Inverse: true}, category, symbol, baseCoin, orderID, orderLinkID, "", "", cursor, startTime, endTime, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } @@ -1155,30 +1155,30 @@ func (by *Bybit) GetPreUpgradeTradeHistory(ctx context.Context, category, symbol params.Set("executionType", executionType) } var resp *ExecutionResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/execution/list", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/execution/list", params, nil, &resp, defaultEPL) } // GetPreUpgradeClosedPnL retrieves user's closed profit and loss records from before you upgraded the account to a Unified account. The results are sorted by createdTime in descending order. -func (by *Bybit) GetPreUpgradeClosedPnL(ctx context.Context, category, symbol, cursor string, startTime, endTime time.Time, limit int64) (*ClosedProfitAndLossResponse, error) { +func (e *Exchange) GetPreUpgradeClosedPnL(ctx context.Context, category, symbol, cursor string, startTime, endTime time.Time, limit int64) (*ClosedProfitAndLossResponse, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true, Inverse: true, MandatorySymbol: true}, category, symbol, "", "", "", "", "", cursor, startTime, endTime, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } var resp *ClosedProfitAndLossResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/position/closed-pnl", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/position/closed-pnl", params, nil, &resp, defaultEPL) } // GetPreUpgradeTransactionLog retrieves transaction logs which occurred in the USDC Derivatives wallet before the account was upgraded to a Unified account. -func (by *Bybit) GetPreUpgradeTransactionLog(ctx context.Context, category, baseCoin, transactionType, cursor string, startTime, endTime time.Time, limit int64) (*TransactionLog, error) { +func (e *Exchange) GetPreUpgradeTransactionLog(ctx context.Context, category, baseCoin, transactionType, cursor string, startTime, endTime time.Time, limit int64) (*TransactionLog, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true, Inverse: true}, category, "", baseCoin, "", "", "", "", cursor, startTime, endTime, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } @@ -1186,16 +1186,16 @@ func (by *Bybit) GetPreUpgradeTransactionLog(ctx context.Context, category, base params.Set("type", transactionType) } var resp *TransactionLog - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/account/transaction-log", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/account/transaction-log", params, nil, &resp, defaultEPL) } // GetPreUpgradeOptionDeliveryRecord retrieves delivery records of Option before you upgraded the account to a Unified account, sorted by deliveryTime in descending order -func (by *Bybit) GetPreUpgradeOptionDeliveryRecord(ctx context.Context, category, symbol, cursor string, expiryDate time.Time, limit int64) (*PreUpdateOptionDeliveryRecord, error) { +func (e *Exchange) GetPreUpgradeOptionDeliveryRecord(ctx context.Context, category, symbol, cursor string, expiryDate time.Time, limit int64) (*PreUpdateOptionDeliveryRecord, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{OptionalBaseCoin: true, Option: true}, category, symbol, "", "", "", "", "", cursor, time.Time{}, time.Time{}, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } @@ -1203,28 +1203,28 @@ func (by *Bybit) GetPreUpgradeOptionDeliveryRecord(ctx context.Context, category params.Set("expData", expiryDate.Format(longDatedFormat)) } var resp *PreUpdateOptionDeliveryRecord - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/asset/delivery-record", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/asset/delivery-record", params, nil, &resp, defaultEPL) } // GetPreUpgradeUSDCSessionSettlement retrieves session settlement records of USDC perpetual before you upgrade the account to Unified account. -func (by *Bybit) GetPreUpgradeUSDCSessionSettlement(ctx context.Context, category, symbol, cursor string, limit int64) (*SettlementSession, error) { +func (e *Exchange) GetPreUpgradeUSDCSessionSettlement(ctx context.Context, category, symbol, cursor string, limit int64) (*SettlementSession, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{Linear: true}, category, symbol, "", "", "", "", "", cursor, time.Time{}, time.Time{}, limit) if err != nil { return nil, err } - err = by.RequiresUnifiedAccount(ctx) + err = e.RequiresUnifiedAccount(ctx) if err != nil { return nil, err } var resp *SettlementSession - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/asset/settlement-record", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/pre-upgrade/asset/settlement-record", params, nil, &resp, defaultEPL) } // GetWalletBalance represents wallet balance, query asset information of each currency, and account risk rate information. // By default, currency information with assets or liabilities of 0 is not returned. // Unified account: UNIFIED (trade spot/linear/options), CONTRACT(trade inverse) // Normal account: CONTRACT, SPOT -func (by *Bybit) GetWalletBalance(ctx context.Context, accountType, coin string) (*WalletBalance, error) { +func (e *Exchange) GetWalletBalance(ctx context.Context, accountType, coin string) (*WalletBalance, error) { params := url.Values{} if accountType == "" { return nil, errMissingAccountType @@ -1234,17 +1234,17 @@ func (by *Bybit) GetWalletBalance(ctx context.Context, accountType, coin string) params.Set("coin", coin) } var resp *WalletBalance - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/wallet-balance", params, nil, &resp, getAccountWalletBalanceEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/wallet-balance", params, nil, &resp, getAccountWalletBalanceEPL) } // UpgradeToUnifiedAccount upgrades the account to unified account. -func (by *Bybit) UpgradeToUnifiedAccount(ctx context.Context) (*UnifiedAccountUpgradeResponse, error) { +func (e *Exchange) UpgradeToUnifiedAccount(ctx context.Context) (*UnifiedAccountUpgradeResponse, error) { var resp *UnifiedAccountUpgradeResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/upgrade-to-uta", nil, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/upgrade-to-uta", nil, nil, &resp, defaultEPL) } // GetBorrowHistory retrieves interest records, sorted in reverse order of creation time. -func (by *Bybit) GetBorrowHistory(ctx context.Context, currency, cursor string, startTime, endTime time.Time, limit int64) (*BorrowHistory, error) { +func (e *Exchange) GetBorrowHistory(ctx context.Context, currency, cursor string, startTime, endTime time.Time, limit int64) (*BorrowHistory, error) { params := url.Values{} if currency != "" { params.Set("currency", currency) @@ -1265,11 +1265,11 @@ func (by *Bybit) GetBorrowHistory(ctx context.Context, currency, cursor string, params.Set("cursor", cursor) } var resp *BorrowHistory - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/borrow-history", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/borrow-history", params, nil, &resp, defaultEPL) } // SetCollateralCoin decide whether the assets in the Unified account needs to be collateral coins. -func (by *Bybit) SetCollateralCoin(ctx context.Context, coin currency.Code, collateralSwitchON bool) error { +func (e *Exchange) SetCollateralCoin(ctx context.Context, coin currency.Code, collateralSwitchON bool) error { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) @@ -1279,33 +1279,33 @@ func (by *Bybit) SetCollateralCoin(ctx context.Context, coin currency.Code, coll } else { params.Set("collateralSwitch", "OFF") } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/set-collateral-switch", params, nil, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/set-collateral-switch", params, nil, &struct{}{}, defaultEPL) } // GetCollateralInfo retrieves the collateral information of the current unified margin account, // including loan interest rate, loanable amount, collateral conversion rate, // whether it can be mortgaged as margin, etc. -func (by *Bybit) GetCollateralInfo(ctx context.Context, currency string) (*CollateralInfo, error) { +func (e *Exchange) GetCollateralInfo(ctx context.Context, currency string) (*CollateralInfo, error) { params := url.Values{} if currency != "" { params.Set("currency", currency) } var resp *CollateralInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/collateral-info", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/collateral-info", params, nil, &resp, defaultEPL) } // GetCoinGreeks retrieves current account Greeks information -func (by *Bybit) GetCoinGreeks(ctx context.Context, baseCoin string) (*CoinGreeks, error) { +func (e *Exchange) GetCoinGreeks(ctx context.Context, baseCoin string) (*CoinGreeks, error) { params := url.Values{} if baseCoin != "" { params.Set("baseCoin", baseCoin) } var resp *CoinGreeks - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/coin-greeks", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/coin-greeks", params, nil, &resp, defaultEPL) } // GetFeeRate retrieves the trading fee rate. -func (by *Bybit) GetFeeRate(ctx context.Context, category, symbol, baseCoin string) (*AccountFee, error) { +func (e *Exchange) GetFeeRate(ctx context.Context, category, symbol, baseCoin string) (*AccountFee, error) { params := url.Values{} if !slices.Contains(validCategory, category) { return nil, fmt.Errorf("%w, valid category values are %v", errInvalidCategory, validCategory) @@ -1320,18 +1320,18 @@ func (by *Bybit) GetFeeRate(ctx context.Context, category, symbol, baseCoin stri params.Set("baseCoin", baseCoin) } var resp *AccountFee - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/fee-rate", params, nil, &resp, getAccountFeeEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/fee-rate", params, nil, &resp, getAccountFeeEPL) } // GetAccountInfo retrieves the margin mode configuration of the account. // query the margin mode and the upgraded status of account -func (by *Bybit) GetAccountInfo(ctx context.Context) (*AccountInfo, error) { +func (e *Exchange) GetAccountInfo(ctx context.Context) (*AccountInfo, error) { var resp *AccountInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/info", nil, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/info", nil, nil, &resp, defaultEPL) } // GetTransactionLog retrieves transaction logs in Unified account. -func (by *Bybit) GetTransactionLog(ctx context.Context, category, baseCoin, transactionType, cursor string, startTime, endTime time.Time, limit int64) (*TransactionLog, error) { +func (e *Exchange) GetTransactionLog(ctx context.Context, category, baseCoin, transactionType, cursor string, startTime, endTime time.Time, limit int64) (*TransactionLog, error) { params, err := fillOrderAndExecutionFetchParams(paramsConfig{OptionalBaseCoin: true, OptionalCategory: true, Linear: true, Option: true, Spot: true}, category, "", baseCoin, "", "", "", "", cursor, startTime, endTime, limit) if err != nil { return nil, err @@ -1340,11 +1340,11 @@ func (by *Bybit) GetTransactionLog(ctx context.Context, category, baseCoin, tran params.Set("type", transactionType) } var resp *TransactionLog - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/transaction-log", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/transaction-log", params, nil, &resp, defaultEPL) } // SetMarginMode set margin mode to either of ISOLATED_MARGIN, REGULAR_MARGIN(i.e. Cross margin), PORTFOLIO_MARGIN -func (by *Bybit) SetMarginMode(ctx context.Context, marginMode string) (*SetMarginModeResponse, error) { +func (e *Exchange) SetMarginMode(ctx context.Context, marginMode string) (*SetMarginModeResponse, error) { if marginMode == "" { return nil, fmt.Errorf("%w, margin mode should be either of ISOLATED_MARGIN, REGULAR_MARGIN, or PORTFOLIO_MARGIN", errInvalidMode) } @@ -1353,21 +1353,21 @@ func (by *Bybit) SetMarginMode(ctx context.Context, marginMode string) (*SetMarg }{SetMarginMode: marginMode} var resp *SetMarginModeResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/set-margin-mode", nil, arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/set-margin-mode", nil, arg, &resp, defaultEPL) } // SetSpotHedging to turn on/off Spot hedging feature in Portfolio margin for Unified account. -func (by *Bybit) SetSpotHedging(ctx context.Context, setHedgingModeOn bool) error { +func (e *Exchange) SetSpotHedging(ctx context.Context, setHedgingModeOn bool) error { resp := struct{}{} setHedgingMode := "OFF" if setHedgingModeOn { setHedgingMode = "ON" } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/set-hedging-mode", nil, &map[string]string{"setHedgingMode": setHedgingMode}, &resp, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/set-hedging-mode", nil, &map[string]string{"setHedgingMode": setHedgingMode}, &resp, defaultEPL) } // SetMMP Market Maker Protection (MMP) is an automated mechanism designed to protect market makers (MM) against liquidity risks and over-exposure in the market. -func (by *Bybit) SetMMP(ctx context.Context, arg *MMPRequestParam) error { +func (e *Exchange) SetMMP(ctx context.Context, arg *MMPRequestParam) error { if arg == nil { return errNilArgument } @@ -1386,23 +1386,23 @@ func (by *Bybit) SetMMP(ctx context.Context, arg *MMPRequestParam) error { if arg.DeltaLimit <= 0 { return fmt.Errorf("%w, delta limit is required", errQuantityLimitRequired) } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-modify", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-modify", nil, arg, &struct{}{}, defaultEPL) } // ResetMMP resets MMP. // once the mmp triggered, you can unfreeze the account by this endpoint -func (by *Bybit) ResetMMP(ctx context.Context, baseCoin string) error { +func (e *Exchange) ResetMMP(ctx context.Context, baseCoin string) error { if baseCoin == "" { return errBaseNotSet } arg := &struct { BaseCoin string `json:"baseCoin"` }{BaseCoin: baseCoin} - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-reset", nil, arg, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-reset", nil, arg, &struct{}{}, defaultEPL) } // GetMMPState retrieve Market Maker Protection (MMP) states for different coins. -func (by *Bybit) GetMMPState(ctx context.Context, baseCoin string) (*MMPStates, error) { +func (e *Exchange) GetMMPState(ctx context.Context, baseCoin string) (*MMPStates, error) { if baseCoin == "" { return nil, errBaseNotSet } @@ -1410,11 +1410,11 @@ func (by *Bybit) GetMMPState(ctx context.Context, baseCoin string) (*MMPStates, BaseCoin string `json:"baseCoin"` }{BaseCoin: baseCoin} var resp *MMPStates - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-state", nil, arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/account/mmp-state", nil, arg, &resp, defaultEPL) } // GetCoinExchangeRecords queries the coin exchange records. -func (by *Bybit) GetCoinExchangeRecords(ctx context.Context, fromCoin, toCoin, cursor string, limit int64) (*CoinExchangeRecords, error) { +func (e *Exchange) GetCoinExchangeRecords(ctx context.Context, fromCoin, toCoin, cursor string, limit int64) (*CoinExchangeRecords, error) { params := url.Values{} if fromCoin != "" { params.Set("fromCoin", fromCoin) @@ -1429,11 +1429,11 @@ func (by *Bybit) GetCoinExchangeRecords(ctx context.Context, fromCoin, toCoin, c params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *CoinExchangeRecords - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/exchange/order-record", params, nil, &resp, getExchangeOrderRecordEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/exchange/order-record", params, nil, &resp, getExchangeOrderRecordEPL) } // GetDeliveryRecord retrieves delivery records of USDC futures and Options, sorted by deliveryTime in descending order -func (by *Bybit) GetDeliveryRecord(ctx context.Context, category, symbol, cursor string, expiryDate time.Time, limit int64) (*DeliveryRecord, error) { +func (e *Exchange) GetDeliveryRecord(ctx context.Context, category, symbol, cursor string, expiryDate time.Time, limit int64) (*DeliveryRecord, error) { if !slices.Contains([]string{cLinear, cOption}, category) { return nil, fmt.Errorf("%w, valid category values are %v", errInvalidCategory, []string{cLinear, cOption}) } @@ -1452,11 +1452,11 @@ func (by *Bybit) GetDeliveryRecord(ctx context.Context, category, symbol, cursor params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *DeliveryRecord - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/delivery-record", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/delivery-record", params, nil, &resp, defaultEPL) } // GetUSDCSessionSettlement retrieves session settlement records of USDC perpetual and futures -func (by *Bybit) GetUSDCSessionSettlement(ctx context.Context, category, symbol, cursor string, limit int64) (*SettlementSession, error) { +func (e *Exchange) GetUSDCSessionSettlement(ctx context.Context, category, symbol, cursor string, limit int64) (*SettlementSession, error) { if category != cLinear { return nil, fmt.Errorf("%w, valid category value is %v", errInvalidCategory, cLinear) } @@ -1472,11 +1472,11 @@ func (by *Bybit) GetUSDCSessionSettlement(ctx context.Context, category, symbol, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *SettlementSession - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/settlement-record", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/settlement-record", params, nil, &resp, defaultEPL) } // GetAssetInfo retrieves asset information -func (by *Bybit) GetAssetInfo(ctx context.Context, accountType, coin string) (*AccountInfos, error) { +func (e *Exchange) GetAssetInfo(ctx context.Context, accountType, coin string) (*AccountInfos, error) { if accountType == "" { return nil, errMissingAccountType } @@ -1486,7 +1486,7 @@ func (by *Bybit) GetAssetInfo(ctx context.Context, accountType, coin string) (*A params.Set("coin", coin) } var resp *AccountInfos - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-asset-info", params, nil, &resp, getAssetTransferQueryInfoEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-asset-info", params, nil, &resp, getAssetTransferQueryInfoEPL) } func fillCoinBalanceFetchParams(accountType, memberID, coin string, withBonus int64, coinRequired bool) (url.Values, error) { @@ -1512,17 +1512,17 @@ func fillCoinBalanceFetchParams(accountType, memberID, coin string, withBonus in // GetAllCoinBalance retrieves all coin balance of all account types under the master account, and sub account. // It is not allowed to get master account coin balance via sub account api key. -func (by *Bybit) GetAllCoinBalance(ctx context.Context, accountType, memberID, coin string, withBonus int64) (*CoinBalances, error) { +func (e *Exchange) GetAllCoinBalance(ctx context.Context, accountType, memberID, coin string, withBonus int64) (*CoinBalances, error) { params, err := fillCoinBalanceFetchParams(accountType, memberID, coin, withBonus, false) if err != nil { return nil, err } var resp *CoinBalances - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-account-coins-balance", params, nil, &resp, getAssetAccountCoinBalanceEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-account-coins-balance", params, nil, &resp, getAssetAccountCoinBalanceEPL) } // GetSingleCoinBalance retrieves the balance of a specific coin in a specific account type. Supports querying sub UID's balance. -func (by *Bybit) GetSingleCoinBalance(ctx context.Context, accountType, coin, memberID string, withBonus, withTransferSafeAmount int64) (*CoinBalance, error) { +func (e *Exchange) GetSingleCoinBalance(ctx context.Context, accountType, coin, memberID string, withBonus, withTransferSafeAmount int64) (*CoinBalance, error) { params, err := fillCoinBalanceFetchParams(accountType, memberID, coin, withBonus, true) if err != nil { return nil, err @@ -1531,11 +1531,11 @@ func (by *Bybit) GetSingleCoinBalance(ctx context.Context, accountType, coin, me params.Set("withTransferSafeAmount", strconv.FormatInt(withTransferSafeAmount, 10)) } var resp *CoinBalance - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-account-coin-balance", params, nil, &resp, getAssetTransferQueryTransferCoinListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-account-coin-balance", params, nil, &resp, getAssetTransferQueryTransferCoinListEPL) } // GetTransferableCoin the transferable coin list between each account type -func (by *Bybit) GetTransferableCoin(ctx context.Context, fromAccountType, toAccountType string) (*TransferableCoins, error) { +func (e *Exchange) GetTransferableCoin(ctx context.Context, fromAccountType, toAccountType string) (*TransferableCoins, error) { if fromAccountType == "" { return nil, fmt.Errorf("%w, from account type not specified", errMissingAccountType) } @@ -1546,13 +1546,13 @@ func (by *Bybit) GetTransferableCoin(ctx context.Context, fromAccountType, toAcc params.Set("fromAccountType", fromAccountType) params.Set("toAccountType", toAccountType) var resp *TransferableCoins - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-transfer-coin-list", params, nil, &resp, getAssetTransferQueryTransferCoinListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-transfer-coin-list", params, nil, &resp, getAssetTransferQueryTransferCoinListEPL) } // CreateInternalTransfer create the internal transfer between different account types under the same UID. // Each account type has its own acceptable coins, e.g, you cannot transfer USDC from SPOT to CONTRACT. // Please refer to transferable coin list API to find out more. -func (by *Bybit) CreateInternalTransfer(ctx context.Context, arg *TransferParams) (string, error) { +func (e *Exchange) CreateInternalTransfer(ctx context.Context, arg *TransferParams) (string, error) { if arg == nil { return "", errNilArgument } @@ -1574,40 +1574,40 @@ func (by *Bybit) CreateInternalTransfer(ctx context.Context, arg *TransferParams resp := struct { TransferID string `json:"transferId"` }{} - return resp.TransferID, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/inter-transfer", nil, arg, &resp, interTransferEPL) + return resp.TransferID, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/inter-transfer", nil, arg, &resp, interTransferEPL) } // GetInternalTransferRecords retrieves the internal transfer records between different account types under the same UID. -func (by *Bybit) GetInternalTransferRecords(ctx context.Context, transferID, coin, status, cursor string, startTime, endTime time.Time, limit int64) (*TransferResponse, error) { +func (e *Exchange) GetInternalTransferRecords(ctx context.Context, transferID, coin, status, cursor string, startTime, endTime time.Time, limit int64) (*TransferResponse, error) { params := fillTransferQueryParams(transferID, coin, status, cursor, startTime, endTime, limit) var resp *TransferResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-inter-transfer-list", params, nil, &resp, getAssetInterTransferListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-inter-transfer-list", params, nil, &resp, getAssetInterTransferListEPL) } // GetSubUID retrieves the sub UIDs under a main UID -func (by *Bybit) GetSubUID(ctx context.Context) (*SubUID, error) { +func (e *Exchange) GetSubUID(ctx context.Context) (*SubUID, error) { var resp *SubUID - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-sub-member-list", nil, nil, &resp, getSubMemberListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-sub-member-list", nil, nil, &resp, getSubMemberListEPL) } // EnableUniversalTransferForSubUID Transfer between sub-sub or main-sub // Use this endpoint to enable a subaccount to take part in a universal transfer. It is a one-time switch which, once thrown, enables a subaccount permanently. // If not set, your subaccount cannot use universal transfers. -func (by *Bybit) EnableUniversalTransferForSubUID(ctx context.Context, subMemberIDs ...string) error { +func (e *Exchange) EnableUniversalTransferForSubUID(ctx context.Context, subMemberIDs ...string) error { if len(subMemberIDs) == 0 { return errMembersIDsNotSet } arg := map[string][]string{ "subMemberIDs": subMemberIDs, } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/save-transfer-sub-member", nil, &arg, &struct{}{}, saveTransferSubMemberEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/save-transfer-sub-member", nil, &arg, &struct{}{}, saveTransferSubMemberEPL) } // CreateUniversalTransfer transfer between sub-sub or main-sub. Please make sure you have enabled universal transfer on your sub UID in advance. // To use sub acct api key, it must have "SubMemberTransferList" permission // When use sub acct api key, it can only transfer to main account // You can not transfer between the same UID -func (by *Bybit) CreateUniversalTransfer(ctx context.Context, arg *TransferParams) (string, error) { +func (e *Exchange) CreateUniversalTransfer(ctx context.Context, arg *TransferParams) (string, error) { if arg == nil { return "", errNilArgument } @@ -1635,7 +1635,7 @@ func (by *Bybit) CreateUniversalTransfer(ctx context.Context, arg *TransferParam resp := struct { TransferID string `json:"transferId"` }{} - return resp.TransferID, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/universal-transfer", nil, arg, &resp, universalTransferEPL) + return resp.TransferID, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/transfer/universal-transfer", nil, arg, &resp, universalTransferEPL) } func fillTransferQueryParams(transferID, coin, status, cursor string, startTime, endTime time.Time, limit int64) url.Values { @@ -1668,14 +1668,14 @@ func fillTransferQueryParams(transferID, coin, status, cursor string, startTime, // Main acct api key or Sub acct api key are both supported // Main acct api key needs "SubMemberTransfer" permission // Sub acct api key needs "SubMemberTransferList" permission -func (by *Bybit) GetUniversalTransferRecords(ctx context.Context, transferID, coin, status, cursor string, startTime, endTime time.Time, limit int64) (*TransferResponse, error) { +func (e *Exchange) GetUniversalTransferRecords(ctx context.Context, transferID, coin, status, cursor string, startTime, endTime time.Time, limit int64) (*TransferResponse, error) { params := fillTransferQueryParams(transferID, coin, status, cursor, startTime, endTime, limit) var resp *TransferResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-universal-transfer-list", params, nil, &resp, getAssetUniversalTransferListEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/transfer/query-universal-transfer-list", params, nil, &resp, getAssetUniversalTransferListEPL) } // GetAllowedDepositCoinInfo retrieves allowed deposit coin information. To find out paired chain of coin, please refer coin info api. -func (by *Bybit) GetAllowedDepositCoinInfo(ctx context.Context, coin, chain, cursor string, limit int64) (*AllowedDepositCoinInfo, error) { +func (e *Exchange) GetAllowedDepositCoinInfo(ctx context.Context, coin, chain, cursor string, limit int64) (*AllowedDepositCoinInfo, error) { params := url.Values{} if coin != "" { params.Set("coin", coin) @@ -1690,13 +1690,13 @@ func (by *Bybit) GetAllowedDepositCoinInfo(ctx context.Context, coin, chain, cur params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *AllowedDepositCoinInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-allowed-list", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-allowed-list", params, nil, &resp, defaultEPL) } // SetDepositAccount sets auto transfer account after deposit. The same function as the setting for Deposit on web GUI // account types: CONTRACT Derivatives Account // 'SPOT' Spot Account 'INVESTMENT' ByFi Account (The service has been offline) 'OPTION' USDC Account 'UNIFIED' UMA or UTA 'FUND' Funding Account -func (by *Bybit) SetDepositAccount(ctx context.Context, accountType string) (*StatusResponse, error) { +func (e *Exchange) SetDepositAccount(ctx context.Context, accountType string) (*StatusResponse, error) { if accountType == "" { return nil, errMissingAccountType } @@ -1706,7 +1706,7 @@ func (by *Bybit) SetDepositAccount(ctx context.Context, accountType string) (*St AccountType: accountType, } var resp *StatusResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/deposit/deposit-to-account", nil, &arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/deposit/deposit-to-account", nil, &arg, &resp, defaultEPL) } func fillDepositRecordsParams(coin, cursor string, startTime, endTime time.Time, limit int64) url.Values { @@ -1730,32 +1730,32 @@ func fillDepositRecordsParams(coin, cursor string, startTime, endTime time.Time, } // GetDepositRecords query deposit records. -func (by *Bybit) GetDepositRecords(ctx context.Context, coin, cursor string, startTime, endTime time.Time, limit int64) (*DepositRecords, error) { +func (e *Exchange) GetDepositRecords(ctx context.Context, coin, cursor string, startTime, endTime time.Time, limit int64) (*DepositRecords, error) { params := fillDepositRecordsParams(coin, cursor, startTime, endTime, limit) var resp *DepositRecords - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-record", params, nil, &resp, getAssetDepositRecordsEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-record", params, nil, &resp, getAssetDepositRecordsEPL) } // GetSubDepositRecords query subaccount's deposit records by main UID's API key. on chain -func (by *Bybit) GetSubDepositRecords(ctx context.Context, subMemberID, coin, cursor string, startTime, endTime time.Time, limit int64) (*DepositRecords, error) { +func (e *Exchange) GetSubDepositRecords(ctx context.Context, subMemberID, coin, cursor string, startTime, endTime time.Time, limit int64) (*DepositRecords, error) { if subMemberID == "" { return nil, errMembersIDsNotSet } params := fillDepositRecordsParams(coin, cursor, startTime, endTime, limit) params.Set("subMemberId", subMemberID) var resp *DepositRecords - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-sub-member-record", params, nil, &resp, getAssetDepositSubMemberRecordsEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-sub-member-record", params, nil, &resp, getAssetDepositSubMemberRecordsEPL) } // GetInternalDepositRecordsOffChain retrieves deposit records within the Bybit platform. These transactions are not on the blockchain. -func (by *Bybit) GetInternalDepositRecordsOffChain(ctx context.Context, coin, cursor string, startTime, endTime time.Time, limit int64) (*InternalDepositRecords, error) { +func (e *Exchange) GetInternalDepositRecordsOffChain(ctx context.Context, coin, cursor string, startTime, endTime time.Time, limit int64) (*InternalDepositRecords, error) { params := fillDepositRecordsParams(coin, cursor, startTime, endTime, limit) var resp *InternalDepositRecords - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-internal-record", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-internal-record", params, nil, &resp, defaultEPL) } // GetMasterDepositAddress retrieves the deposit address information of MASTER account. -func (by *Bybit) GetMasterDepositAddress(ctx context.Context, coin currency.Code, chainType string) (*DepositAddresses, error) { +func (e *Exchange) GetMasterDepositAddress(ctx context.Context, coin currency.Code, chainType string) (*DepositAddresses, error) { if coin.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1765,11 +1765,11 @@ func (by *Bybit) GetMasterDepositAddress(ctx context.Context, coin currency.Code params.Set("chainType", chainType) } var resp *DepositAddresses - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-address", params, nil, &resp, getAssetDepositRecordsEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-address", params, nil, &resp, getAssetDepositRecordsEPL) } // GetSubDepositAddress retrieves the deposit address information of SUB account. -func (by *Bybit) GetSubDepositAddress(ctx context.Context, coin currency.Code, chainType, subMemberID string) (*DepositAddresses, error) { +func (e *Exchange) GetSubDepositAddress(ctx context.Context, coin currency.Code, chainType, subMemberID string) (*DepositAddresses, error) { if coin.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1784,23 +1784,23 @@ func (by *Bybit) GetSubDepositAddress(ctx context.Context, coin currency.Code, c params.Set("chainType", chainType) params.Set("subMemberId", subMemberID) var resp *DepositAddresses - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-sub-member-address", params, nil, &resp, getAssetDepositSubMemberAddressEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/deposit/query-sub-member-address", params, nil, &resp, getAssetDepositSubMemberAddressEPL) } // GetCoinInfo retrieves coin information, including chain information, withdraw and deposit status. -func (by *Bybit) GetCoinInfo(ctx context.Context, coin currency.Code) (*CoinInfo, error) { +func (e *Exchange) GetCoinInfo(ctx context.Context, coin currency.Code) (*CoinInfo, error) { params := url.Values{} if coin.IsEmpty() { params.Set("coin", coin.String()) } var resp *CoinInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/coin/query-info", params, nil, &resp, getAssetCoinInfoEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/coin/query-info", params, nil, &resp, getAssetCoinInfoEPL) } // GetWithdrawalRecords query withdrawal records. // endTime - startTime should be less than 30 days. Query last 30 days records by default. // Can query by the master UID's api key only -func (by *Bybit) GetWithdrawalRecords(ctx context.Context, coin currency.Code, withdrawalID, withdrawType, cursor string, startTime, endTime time.Time, limit int64) (*WithdrawalRecords, error) { +func (e *Exchange) GetWithdrawalRecords(ctx context.Context, coin currency.Code, withdrawalID, withdrawType, cursor string, startTime, endTime time.Time, limit int64) (*WithdrawalRecords, error) { params := url.Values{} if withdrawalID != "" { params.Set("withdrawID", withdrawalID) @@ -1824,22 +1824,22 @@ func (by *Bybit) GetWithdrawalRecords(ctx context.Context, coin currency.Code, w params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *WithdrawalRecords - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/withdraw/query-record", params, nil, &resp, getWithdrawRecordsEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/withdraw/query-record", params, nil, &resp, getWithdrawRecordsEPL) } // GetWithdrawableAmount retrieves withdrawable amount information using currency code -func (by *Bybit) GetWithdrawableAmount(ctx context.Context, coin currency.Code) (*WithdrawableAmount, error) { +func (e *Exchange) GetWithdrawableAmount(ctx context.Context, coin currency.Code) (*WithdrawableAmount, error) { if coin.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("coin", coin.String()) var resp *WithdrawableAmount - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/withdraw/withdrawable-amount", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/asset/withdraw/withdrawable-amount", params, nil, &resp, defaultEPL) } // WithdrawCurrency Withdraw assets from your Bybit account. You can make an off-chain transfer if the target wallet address is from Bybit. This means that no blockchain fee will be charged. -func (by *Bybit) WithdrawCurrency(ctx context.Context, arg *WithdrawalParam) (string, error) { +func (e *Exchange) WithdrawCurrency(ctx context.Context, arg *WithdrawalParam) (string, error) { if arg == nil { return "", errNilArgument } @@ -1861,11 +1861,11 @@ func (by *Bybit) WithdrawCurrency(ctx context.Context, arg *WithdrawalParam) (st resp := struct { ID string `json:"id"` }{} - return resp.ID, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/withdraw/create", nil, arg, &resp, createWithdrawalEPL) + return resp.ID, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/withdraw/create", nil, arg, &resp, createWithdrawalEPL) } // CancelWithdrawal cancel the withdrawal -func (by *Bybit) CancelWithdrawal(ctx context.Context, id string) (*StatusResponse, error) { +func (e *Exchange) CancelWithdrawal(ctx context.Context, id string) (*StatusResponse, error) { if id == "" { return nil, errMissingWithdrawalID } @@ -1875,11 +1875,11 @@ func (by *Bybit) CancelWithdrawal(ctx context.Context, id string) (*StatusRespon ID: id, } var resp *StatusResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/withdraw/cancel", nil, arg, &resp, cancelWithdrawalEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/asset/withdraw/cancel", nil, arg, &resp, cancelWithdrawalEPL) } // CreateNewSubUserID created a new sub user id. Use master user's api key only. -func (by *Bybit) CreateNewSubUserID(ctx context.Context, arg *CreateSubUserParams) (*SubUserItem, error) { +func (e *Exchange) CreateNewSubUserID(ctx context.Context, arg *CreateSubUserParams) (*SubUserItem, error) { if arg == nil { return nil, errNilArgument } @@ -1890,11 +1890,11 @@ func (by *Bybit) CreateNewSubUserID(ctx context.Context, arg *CreateSubUserParam return nil, errInvalidMemberType } var resp *SubUserItem - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/create-sub-member", nil, &arg, &resp, userCreateSubMemberEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/create-sub-member", nil, &arg, &resp, userCreateSubMemberEPL) } // CreateSubUIDAPIKey create new API key for those newly created sub UID. Use master user's api key only. -func (by *Bybit) CreateSubUIDAPIKey(ctx context.Context, arg *SubUIDAPIKeyParam) (*SubUIDAPIResponse, error) { +func (e *Exchange) CreateSubUIDAPIKey(ctx context.Context, arg *SubUIDAPIKeyParam) (*SubUIDAPIResponse, error) { if arg == nil { return nil, errNilArgument } @@ -1902,19 +1902,19 @@ func (by *Bybit) CreateSubUIDAPIKey(ctx context.Context, arg *SubUIDAPIKeyParam) return nil, fmt.Errorf("%w, subuid", errMissingUserID) } var resp *SubUIDAPIResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/create-sub-api", nil, arg, &resp, userCreateSubAPIKeyEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/create-sub-api", nil, arg, &resp, userCreateSubAPIKeyEPL) } // GetSubUIDList get all sub uid of master account. Use master user's api key only. -func (by *Bybit) GetSubUIDList(ctx context.Context) ([]SubUserItem, error) { +func (e *Exchange) GetSubUIDList(ctx context.Context) ([]SubUserItem, error) { resp := struct { SubMembers []SubUserItem `json:"subMembers"` }{} - return resp.SubMembers, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/query-sub-members", nil, nil, &resp, userQuerySubMembersEPL) + return resp.SubMembers, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/query-sub-members", nil, nil, &resp, userQuerySubMembersEPL) } // FreezeSubUID freeze Sub UID. Use master user's api key only. -func (by *Bybit) FreezeSubUID(ctx context.Context, subUID string, frozen bool) error { +func (e *Exchange) FreezeSubUID(ctx context.Context, subUID string, frozen bool) error { if subUID == "" { return fmt.Errorf("%w, subuid", errMissingUserID) } @@ -1929,19 +1929,19 @@ func (by *Bybit) FreezeSubUID(ctx context.Context, subUID string, frozen bool) e } else { arg.Frozen = 1 } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/frozen-sub-member", nil, arg, &struct{}{}, userFrozenSubMemberEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/frozen-sub-member", nil, arg, &struct{}{}, userFrozenSubMemberEPL) } // GetAPIKeyInformation retrieves the information of the api key. // Use the api key pending to be checked to call the endpoint. // Both master and sub user's api key are applicable. -func (by *Bybit) GetAPIKeyInformation(ctx context.Context) (*SubUIDAPIResponse, error) { +func (e *Exchange) GetAPIKeyInformation(ctx context.Context) (*SubUIDAPIResponse, error) { var resp *SubUIDAPIResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/query-api", nil, nil, &resp, userQueryAPIEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/query-api", nil, nil, &resp, userQueryAPIEPL) } // GetSubAccountAllAPIKeys retrieves all api keys information of a sub UID. -func (by *Bybit) GetSubAccountAllAPIKeys(ctx context.Context, subMemberID, cursor string, limit int64) (*SubAccountAPIKeys, error) { +func (e *Exchange) GetSubAccountAllAPIKeys(ctx context.Context, subMemberID, cursor string, limit int64) (*SubAccountAPIKeys, error) { if subMemberID == "" { return nil, errMembersIDsNotSet } @@ -1954,21 +1954,21 @@ func (by *Bybit) GetSubAccountAllAPIKeys(ctx context.Context, subMemberID, curso params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *SubAccountAPIKeys - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, " /v5/user/sub-apikeys", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, " /v5/user/sub-apikeys", params, nil, &resp, defaultEPL) } // GetUIDWalletType retrieves available wallet types for the master account or sub account -func (by *Bybit) GetUIDWalletType(ctx context.Context, memberIDs string) (*WalletType, error) { +func (e *Exchange) GetUIDWalletType(ctx context.Context, memberIDs string) (*WalletType, error) { if memberIDs == "" { return nil, errMembersIDsNotSet } var resp *WalletType - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/get-member-type", nil, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/get-member-type", nil, nil, &resp, defaultEPL) } // ModifyMasterAPIKey modify the settings of master api key. // Use the api key pending to be modified to call the endpoint. Use master user's api key only. -func (by *Bybit) ModifyMasterAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdateParam) (*SubUIDAPIResponse, error) { +func (e *Exchange) ModifyMasterAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdateParam) (*SubUIDAPIResponse, error) { if arg == nil || reflect.DeepEqual(*arg, SubUIDAPIKeyUpdateParam{}) { return nil, errNilArgument } @@ -1976,11 +1976,11 @@ func (by *Bybit) ModifyMasterAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdate arg.IPs = strings.Join(arg.IPAddresses, ",") } var resp *SubUIDAPIResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/update-api", nil, arg, &resp, userUpdateAPIEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/update-api", nil, arg, &resp, userUpdateAPIEPL) } // ModifySubAPIKey modifies the settings of sub api key. Use the api key pending to be modified to call the endpoint. Use sub user's api key only. -func (by *Bybit) ModifySubAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdateParam) (*SubUIDAPIResponse, error) { +func (e *Exchange) ModifySubAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdateParam) (*SubUIDAPIResponse, error) { if arg == nil || reflect.DeepEqual(*arg, SubUIDAPIKeyUpdateParam{}) { return nil, errNilArgument } @@ -1988,12 +1988,12 @@ func (by *Bybit) ModifySubAPIKey(ctx context.Context, arg *SubUIDAPIKeyUpdatePar arg.IPs = strings.Join(arg.IPAddresses, ",") } var resp *SubUIDAPIResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/update-sub-api", nil, &arg, &resp, userUpdateSubAPIEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/update-sub-api", nil, &arg, &resp, userUpdateSubAPIEPL) } // DeleteSubUID delete a sub UID. Before deleting the UID, please make sure there is no asset. // Use master user's api key**. -func (by *Bybit) DeleteSubUID(ctx context.Context, subMemberID string) error { +func (e *Exchange) DeleteSubUID(ctx context.Context, subMemberID string) error { if subMemberID == "" { return errMemberIDRequired } @@ -2001,18 +2001,18 @@ func (by *Bybit) DeleteSubUID(ctx context.Context, subMemberID string) error { SubMemberID string `json:"subMemberId"` }{SubMemberID: subMemberID} var resp any - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/del-submember", nil, arg, &resp, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/del-submember", nil, arg, &resp, defaultEPL) } // DeleteMasterAPIKey delete the api key of master account. // Use the api key pending to be delete to call the endpoint. Use master user's api key only. -func (by *Bybit) DeleteMasterAPIKey(ctx context.Context) error { - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/delete-api", nil, nil, &struct{}{}, userDeleteAPIEPL) +func (e *Exchange) DeleteMasterAPIKey(ctx context.Context) error { + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/delete-api", nil, nil, &struct{}{}, userDeleteAPIEPL) } // DeleteSubAccountAPIKey delete the api key of sub account. // Use the api key pending to be delete to call the endpoint. Use sub user's api key only. -func (by *Bybit) DeleteSubAccountAPIKey(ctx context.Context, subAccountUID string) error { +func (e *Exchange) DeleteSubAccountAPIKey(ctx context.Context, subAccountUID string) error { if subAccountUID == "" { return fmt.Errorf("%w, sub-account id missing", errMissingUserID) } @@ -2021,24 +2021,24 @@ func (by *Bybit) DeleteSubAccountAPIKey(ctx context.Context, subAccountUID strin }{ UID: subAccountUID, } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/delete-sub-api", nil, arg, &struct{}{}, userDeleteSubAPIEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/user/delete-sub-api", nil, arg, &struct{}{}, userDeleteSubAPIEPL) } // GetAffiliateUserInfo the API is used for affiliate to get their users information // The master account uid of affiliate's client -func (by *Bybit) GetAffiliateUserInfo(ctx context.Context, uid string) (*AffiliateCustomerInfo, error) { +func (e *Exchange) GetAffiliateUserInfo(ctx context.Context, uid string) (*AffiliateCustomerInfo, error) { if uid == "" { return nil, errMissingUserID } params := url.Values{} params.Set("uid", uid) var resp *AffiliateCustomerInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/aff-customer-info", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/user/aff-customer-info", params, nil, &resp, defaultEPL) } // GetLeverageTokenInfo query leverage token information // Abbreviation of the LT, such as BTC3L -func (by *Bybit) GetLeverageTokenInfo(ctx context.Context, ltCoin currency.Code) ([]LeverageTokenInfo, error) { +func (e *Exchange) GetLeverageTokenInfo(ctx context.Context, ltCoin currency.Code) ([]LeverageTokenInfo, error) { params := url.Values{} if !ltCoin.IsEmpty() { params.Set("ltCoin", ltCoin.String()) @@ -2046,22 +2046,22 @@ func (by *Bybit) GetLeverageTokenInfo(ctx context.Context, ltCoin currency.Code) resp := struct { List []LeverageTokenInfo `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/info", params, nil, &resp, defaultEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/info", params, nil, &resp, defaultEPL) } // GetLeveragedTokenMarket retrieves leverage token market information -func (by *Bybit) GetLeveragedTokenMarket(ctx context.Context, ltCoin currency.Code) (*LeveragedTokenMarket, error) { +func (e *Exchange) GetLeveragedTokenMarket(ctx context.Context, ltCoin currency.Code) (*LeveragedTokenMarket, error) { if ltCoin.IsEmpty() { return nil, fmt.Errorf("%w, 'ltCoin' is required", currency.ErrCurrencyCodeEmpty) } params := url.Values{} params.Set("ltCoin", ltCoin.String()) var resp *LeveragedTokenMarket - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/reference", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/reference", params, nil, &resp, defaultEPL) } // PurchaseLeverageToken purcases a leverage token. -func (by *Bybit) PurchaseLeverageToken(ctx context.Context, ltCoin currency.Code, amount float64, serialNumber string) (*LeverageToken, error) { +func (e *Exchange) PurchaseLeverageToken(ctx context.Context, ltCoin currency.Code, amount float64, serialNumber string) (*LeverageToken, error) { if ltCoin.IsEmpty() { return nil, fmt.Errorf("%w, 'ltCoin' is required", currency.ErrCurrencyCodeEmpty) } @@ -2078,11 +2078,11 @@ func (by *Bybit) PurchaseLeverageToken(ctx context.Context, ltCoin currency.Code SerialNumber: serialNumber, } var resp *LeverageToken - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-lever-token/purchase", nil, arg, &resp, spotLeverageTokenPurchaseEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-lever-token/purchase", nil, arg, &resp, spotLeverageTokenPurchaseEPL) } // RedeemLeverageToken redeem leverage token -func (by *Bybit) RedeemLeverageToken(ctx context.Context, ltCoin currency.Code, quantity float64, serialNumber string) (*RedeemToken, error) { +func (e *Exchange) RedeemLeverageToken(ctx context.Context, ltCoin currency.Code, quantity float64, serialNumber string) (*RedeemToken, error) { if ltCoin.IsEmpty() { return nil, fmt.Errorf("%w, 'ltCoin' is required", currency.ErrCurrencyCodeEmpty) } @@ -2099,12 +2099,12 @@ func (by *Bybit) RedeemLeverageToken(ctx context.Context, ltCoin currency.Code, SerialNumber: serialNumber, } var resp *RedeemToken - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-lever-token/redeem", nil, &arg, &resp, spotLeverTokenRedeemEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-lever-token/redeem", nil, &arg, &resp, spotLeverTokenRedeemEPL) } // GetPurchaseAndRedemptionRecords retrieves purchase or redeem history. // ltOrderType false integer LT order type. 1: purchase, 2: redemption -func (by *Bybit) GetPurchaseAndRedemptionRecords(ctx context.Context, ltCoin currency.Code, orderID, serialNo string, startTime, endTime time.Time, ltOrderType, limit int64) ([]RedeemPurchaseRecord, error) { +func (e *Exchange) GetPurchaseAndRedemptionRecords(ctx context.Context, ltCoin currency.Code, orderID, serialNo string, startTime, endTime time.Time, ltOrderType, limit int64) ([]RedeemPurchaseRecord, error) { params := url.Values{} if !ltCoin.IsEmpty() { params.Set("ltCoin", ltCoin.String()) @@ -2130,13 +2130,13 @@ func (by *Bybit) GetPurchaseAndRedemptionRecords(ctx context.Context, ltCoin cur resp := struct { List []RedeemPurchaseRecord `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/order-record", params, nil, &resp, getSpotLeverageTokenOrderRecordsEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-lever-token/order-record", params, nil, &resp, getSpotLeverageTokenOrderRecordsEPL) } // ToggleMarginTrade turn on / off spot margin trade // Your account needs to activate spot margin first; i.e., you must have finished the quiz on web / app. // spotMarginMode '1': on, '0': off -func (by *Bybit) ToggleMarginTrade(ctx context.Context, spotMarginMode bool) (*SpotMarginMode, error) { +func (e *Exchange) ToggleMarginTrade(ctx context.Context, spotMarginMode bool) (*SpotMarginMode, error) { arg := &SpotMarginMode{} if spotMarginMode { arg.SpotMarginMode = "1" @@ -2144,19 +2144,19 @@ func (by *Bybit) ToggleMarginTrade(ctx context.Context, spotMarginMode bool) (*S arg.SpotMarginMode = "0" } var resp *SpotMarginMode - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-margin-trade/switch-mode", nil, arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-margin-trade/switch-mode", nil, arg, &resp, defaultEPL) } // SetSpotMarginTradeLeverage set the user's maximum leverage in spot cross margin -func (by *Bybit) SetSpotMarginTradeLeverage(ctx context.Context, leverage float64) error { +func (e *Exchange) SetSpotMarginTradeLeverage(ctx context.Context, leverage float64) error { if leverage <= 2 { return fmt.Errorf("%w, leverage. value range from [2 to 10]", errInvalidLeverage) } - return by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-margin-trade/set-leverage", nil, &map[string]string{"leverage": strconv.FormatFloat(leverage, 'f', -1, 64)}, &struct{}{}, defaultEPL) + return e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-margin-trade/set-leverage", nil, &map[string]string{"leverage": strconv.FormatFloat(leverage, 'f', -1, 64)}, &struct{}{}, defaultEPL) } // GetVIPMarginData retrieves public VIP Margin data -func (by *Bybit) GetVIPMarginData(ctx context.Context, vipLevel, currency string) (*VIPMarginData, error) { +func (e *Exchange) GetVIPMarginData(ctx context.Context, vipLevel, currency string) (*VIPMarginData, error) { params := url.Values{} if vipLevel != "" { params.Set("vipLevel", vipLevel) @@ -2165,11 +2165,11 @@ func (by *Bybit) GetVIPMarginData(ctx context.Context, vipLevel, currency string params.Set("currency", currency) } var resp *VIPMarginData - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, "spot-cross-margin-trade/data", defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, "spot-cross-margin-trade/data", defaultEPL, &resp) } // GetMarginCoinInfo retrieves margin coin information. -func (by *Bybit) GetMarginCoinInfo(ctx context.Context, coin currency.Code) ([]MarginCoinInfo, error) { +func (e *Exchange) GetMarginCoinInfo(ctx context.Context, coin currency.Code) ([]MarginCoinInfo, error) { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) @@ -2177,11 +2177,11 @@ func (by *Bybit) GetMarginCoinInfo(ctx context.Context, coin currency.Code) ([]M resp := struct { List []MarginCoinInfo `json:"list"` }{} - return resp.List, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("spot-cross-margin-trade/pledge-token", params), defaultEPL, &resp) + return resp.List, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("spot-cross-margin-trade/pledge-token", params), defaultEPL, &resp) } // GetBorrowableCoinInfo retrieves borrowable coin info list. -func (by *Bybit) GetBorrowableCoinInfo(ctx context.Context, coin currency.Code) ([]BorrowableCoinInfo, error) { +func (e *Exchange) GetBorrowableCoinInfo(ctx context.Context, coin currency.Code) ([]BorrowableCoinInfo, error) { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) @@ -2189,28 +2189,28 @@ func (by *Bybit) GetBorrowableCoinInfo(ctx context.Context, coin currency.Code) resp := struct { List []BorrowableCoinInfo `json:"list"` }{} - return resp.List, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("spot-cross-margin-trade/borrow-token", params), defaultEPL, &resp) + return resp.List, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("spot-cross-margin-trade/borrow-token", params), defaultEPL, &resp) } // GetInterestAndQuota retrieves interest and quota information. -func (by *Bybit) GetInterestAndQuota(ctx context.Context, coin currency.Code) (*InterestAndQuota, error) { +func (e *Exchange) GetInterestAndQuota(ctx context.Context, coin currency.Code) (*InterestAndQuota, error) { if coin.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("coin", coin.String()) var resp *InterestAndQuota - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/loan-info", params, nil, &resp, getSpotCrossMarginTradeLoanInfoEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/loan-info", params, nil, &resp, getSpotCrossMarginTradeLoanInfoEPL) } // GetLoanAccountInfo retrieves loan account information. -func (by *Bybit) GetLoanAccountInfo(ctx context.Context) (*AccountLoanInfo, error) { +func (e *Exchange) GetLoanAccountInfo(ctx context.Context) (*AccountLoanInfo, error) { var resp *AccountLoanInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/account", nil, nil, &resp, getSpotCrossMarginTradeAccountEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/account", nil, nil, &resp, getSpotCrossMarginTradeAccountEPL) } // Borrow borrows a coin. -func (by *Bybit) Borrow(ctx context.Context, arg *LendArgument) (*BorrowResponse, error) { +func (e *Exchange) Borrow(ctx context.Context, arg *LendArgument) (*BorrowResponse, error) { if arg == nil { return nil, errNilArgument } @@ -2221,11 +2221,11 @@ func (by *Bybit) Borrow(ctx context.Context, arg *LendArgument) (*BorrowResponse return nil, order.ErrAmountBelowMin } var resp *BorrowResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/loan", nil, arg, &resp, spotCrossMarginTradeLoanEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/loan", nil, arg, &resp, spotCrossMarginTradeLoanEPL) } // Repay repay a debt. -func (by *Bybit) Repay(ctx context.Context, arg *LendArgument) (*RepayResponse, error) { +func (e *Exchange) Repay(ctx context.Context, arg *LendArgument) (*RepayResponse, error) { if arg == nil { return nil, errNilArgument } @@ -2236,12 +2236,12 @@ func (by *Bybit) Repay(ctx context.Context, arg *LendArgument) (*RepayResponse, return nil, order.ErrAmountBelowMin } var resp *RepayResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/repay", nil, arg, &resp, spotCrossMarginTradeRepayEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/repay", nil, arg, &resp, spotCrossMarginTradeRepayEPL) } // GetBorrowOrderDetail represents the borrow order detail. // Status '0'(default):get all kinds of status '1':uncleared '2':cleared -func (by *Bybit) GetBorrowOrderDetail(ctx context.Context, startTime, endTime time.Time, coin currency.Code, status, limit int64) ([]BorrowOrderDetail, error) { +func (e *Exchange) GetBorrowOrderDetail(ctx context.Context, startTime, endTime time.Time, coin currency.Code, status, limit int64) ([]BorrowOrderDetail, error) { params := url.Values{} if !startTime.IsZero() { params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) @@ -2261,11 +2261,11 @@ func (by *Bybit) GetBorrowOrderDetail(ctx context.Context, startTime, endTime ti resp := struct { List []BorrowOrderDetail `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/orders", params, nil, &resp, getSpotCrossMarginTradeOrdersEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/orders", params, nil, &resp, getSpotCrossMarginTradeOrdersEPL) } // GetRepaymentOrderDetail retrieves repayment order detail. -func (by *Bybit) GetRepaymentOrderDetail(ctx context.Context, startTime, endTime time.Time, coin currency.Code, limit int64) ([]CoinRepaymentResponse, error) { +func (e *Exchange) GetRepaymentOrderDetail(ctx context.Context, startTime, endTime time.Time, coin currency.Code, limit int64) ([]CoinRepaymentResponse, error) { params := url.Values{} if !startTime.IsZero() { params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) @@ -2282,13 +2282,13 @@ func (by *Bybit) GetRepaymentOrderDetail(ctx context.Context, startTime, endTime resp := struct { List []CoinRepaymentResponse `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/repay-history", params, nil, &resp, getSpotCrossMarginTradeRepayHistoryEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/spot-cross-margin-trade/repay-history", params, nil, &resp, getSpotCrossMarginTradeRepayHistoryEPL) } // ToggleMarginTradeNormal turn on / off spot margin trade // Your account needs to activate spot margin first; i.e., you must have finished the quiz on web / app. // spotMarginMode '1': on, '0': off -func (by *Bybit) ToggleMarginTradeNormal(ctx context.Context, spotMarginMode bool) (*SpotMarginMode, error) { +func (e *Exchange) ToggleMarginTradeNormal(ctx context.Context, spotMarginMode bool) (*SpotMarginMode, error) { arg := &SpotMarginMode{} if spotMarginMode { arg.SpotMarginMode = "1" @@ -2296,32 +2296,32 @@ func (by *Bybit) ToggleMarginTradeNormal(ctx context.Context, spotMarginMode boo arg.SpotMarginMode = "0" } var resp *SpotMarginMode - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/switch", nil, arg, &resp, spotCrossMarginTradeSwitchEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/spot-cross-margin-trade/switch", nil, arg, &resp, spotCrossMarginTradeSwitchEPL) } // GetProductInfo represents a product info. -func (by *Bybit) GetProductInfo(ctx context.Context, productID string) (*InstitutionalProductInfo, error) { +func (e *Exchange) GetProductInfo(ctx context.Context, productID string) (*InstitutionalProductInfo, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) } var resp *InstitutionalProductInfo - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("ins-loan/product-infos", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("ins-loan/product-infos", params), defaultEPL, &resp) } // GetInstitutionalLengingMarginCoinInfo retrieves institutional lending margin coin information. // ProductId. If not passed, then return all product margin coin. For spot, it returns coin that convertRation greater than 0. -func (by *Bybit) GetInstitutionalLengingMarginCoinInfo(ctx context.Context, productID string) (*InstitutionalMarginCoinInfo, error) { +func (e *Exchange) GetInstitutionalLengingMarginCoinInfo(ctx context.Context, productID string) (*InstitutionalMarginCoinInfo, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) } var resp *InstitutionalMarginCoinInfo - return resp, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("ins-loan/ensure-tokens-convert", params), defaultEPL, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("ins-loan/ensure-tokens-convert", params), defaultEPL, &resp) } // GetInstitutionalLoanOrders retrieves institutional loan orders. -func (by *Bybit) GetInstitutionalLoanOrders(ctx context.Context, orderID string, startTime, endTime time.Time, limit int64) ([]LoanOrderDetails, error) { +func (e *Exchange) GetInstitutionalLoanOrders(ctx context.Context, orderID string, startTime, endTime time.Time, limit int64) ([]LoanOrderDetails, error) { params := url.Values{} if orderID != "" { params.Set("orderId", orderID) @@ -2338,11 +2338,11 @@ func (by *Bybit) GetInstitutionalLoanOrders(ctx context.Context, orderID string, resp := struct { Loans []LoanOrderDetails `json:"loanInfo"` }{} - return resp.Loans, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/loan-order", params, nil, &resp, defaultEPL) + return resp.Loans, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/loan-order", params, nil, &resp, defaultEPL) } // GetInstitutionalRepayOrders retrieves list of repaid order information. -func (by *Bybit) GetInstitutionalRepayOrders(ctx context.Context, startTime, endTime time.Time, limit int64) ([]OrderRepayInfo, error) { +func (e *Exchange) GetInstitutionalRepayOrders(ctx context.Context, startTime, endTime time.Time, limit int64) ([]OrderRepayInfo, error) { params := url.Values{} if !startTime.IsZero() { params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) @@ -2356,18 +2356,18 @@ func (by *Bybit) GetInstitutionalRepayOrders(ctx context.Context, startTime, end resp := struct { RepayInfo []OrderRepayInfo `json:"repayInfo"` }{} - return resp.RepayInfo, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/repaid-history", params, nil, &resp, defaultEPL) + return resp.RepayInfo, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/repaid-history", params, nil, &resp, defaultEPL) } // GetLTV retrieves a loan-to-value(LTV) -func (by *Bybit) GetLTV(ctx context.Context) (*LTVInfo, error) { +func (e *Exchange) GetLTV(ctx context.Context) (*LTVInfo, error) { var resp *LTVInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/ltv-convert", nil, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/ins-loan/ltv-convert", nil, nil, &resp, defaultEPL) } // BindOrUnbindUID For the INS loan product, you can bind new UID to risk unit or unbind UID out from risk unit. // possible 'operate' values: 0: bind, 1: unbind -func (by *Bybit) BindOrUnbindUID(ctx context.Context, uid, operate string) (*BindOrUnbindUIDResponse, error) { +func (e *Exchange) BindOrUnbindUID(ctx context.Context, uid, operate string) (*BindOrUnbindUIDResponse, error) { if uid == "" { return nil, fmt.Errorf("%w, uid is required", errMissingUserID) } @@ -2379,11 +2379,11 @@ func (by *Bybit) BindOrUnbindUID(ctx context.Context, uid, operate string) (*Bin Operate string `json:"operate"` }{UID: uid, Operate: operate} var resp *BindOrUnbindUIDResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/ins-loan/association-uid", nil, arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/ins-loan/association-uid", nil, arg, &resp, defaultEPL) } // GetC2CLendingCoinInfo retrieves C2C basic information of lending coins -func (by *Bybit) GetC2CLendingCoinInfo(ctx context.Context, coin currency.Code) ([]C2CLendingCoinInfo, error) { +func (e *Exchange) GetC2CLendingCoinInfo(ctx context.Context, coin currency.Code) ([]C2CLendingCoinInfo, error) { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) @@ -2391,11 +2391,11 @@ func (by *Bybit) GetC2CLendingCoinInfo(ctx context.Context, coin currency.Code) resp := struct { List []C2CLendingCoinInfo `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/info", params, nil, &resp, defaultEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/info", params, nil, &resp, defaultEPL) } // C2CDepositFunds lending funds to Bybit asset pool -func (by *Bybit) C2CDepositFunds(ctx context.Context, arg *C2CLendingFundsParams) (*C2CLendingFundResponse, error) { +func (e *Exchange) C2CDepositFunds(ctx context.Context, arg *C2CLendingFundsParams) (*C2CLendingFundResponse, error) { if arg == nil { return nil, errNilArgument } @@ -2406,11 +2406,11 @@ func (by *Bybit) C2CDepositFunds(ctx context.Context, arg *C2CLendingFundsParams return nil, order.ErrAmountBelowMin } var resp *C2CLendingFundResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/lending/purchase", nil, &arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/lending/purchase", nil, &arg, &resp, defaultEPL) } // C2CRedeemFunds withdraw funds from the Bybit asset pool. -func (by *Bybit) C2CRedeemFunds(ctx context.Context, arg *C2CLendingFundsParams) (*C2CLendingFundResponse, error) { +func (e *Exchange) C2CRedeemFunds(ctx context.Context, arg *C2CLendingFundsParams) (*C2CLendingFundResponse, error) { if arg == nil { return nil, errNilArgument } @@ -2421,11 +2421,11 @@ func (by *Bybit) C2CRedeemFunds(ctx context.Context, arg *C2CLendingFundsParams) return nil, order.ErrAmountBelowMin } var resp *C2CLendingFundResponse - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/lending/redeem", nil, &arg, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodPost, "/v5/lending/redeem", nil, &arg, &resp, defaultEPL) } // GetC2CLendingOrderRecords retrieves lending or redeem history -func (by *Bybit) GetC2CLendingOrderRecords(ctx context.Context, coin currency.Code, orderID, orderType string, startTime, endTime time.Time, limit int64) ([]C2CLendingFundResponse, error) { +func (e *Exchange) GetC2CLendingOrderRecords(ctx context.Context, coin currency.Code, orderID, orderType string, startTime, endTime time.Time, limit int64) ([]C2CLendingFundResponse, error) { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) @@ -2448,24 +2448,24 @@ func (by *Bybit) GetC2CLendingOrderRecords(ctx context.Context, coin currency.Co resp := struct { List []C2CLendingFundResponse `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/history-order", params, nil, &resp, defaultEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/history-order", params, nil, &resp, defaultEPL) } // GetC2CLendingAccountInfo retrieves C2C lending account information. -func (by *Bybit) GetC2CLendingAccountInfo(ctx context.Context, coin currency.Code) (*LendingAccountInfo, error) { +func (e *Exchange) GetC2CLendingAccountInfo(ctx context.Context, coin currency.Code) (*LendingAccountInfo, error) { params := url.Values{} if !coin.IsEmpty() { params.Set("coin", coin.String()) } var resp *LendingAccountInfo - return resp, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/account", params, nil, &resp, defaultEPL) + return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/lending/account", params, nil, &resp, defaultEPL) } // GetBrokerEarning exchange broker master account to query // The data can support up to past 6 months until T-1 // startTime & endTime are either entered at the same time or not entered // Business type. 'SPOT', 'DERIVATIVES', 'OPTIONS' -func (by *Bybit) GetBrokerEarning(ctx context.Context, businessType, cursor string, startTime, endTime time.Time, limit int64) ([]BrokerEarningItem, error) { +func (e *Exchange) GetBrokerEarning(ctx context.Context, businessType, cursor string, startTime, endTime time.Time, limit int64) ([]BrokerEarningItem, error) { params := url.Values{} if businessType != "" { params.Set("bizType", businessType) @@ -2485,7 +2485,7 @@ func (by *Bybit) GetBrokerEarning(ctx context.Context, businessType, cursor stri resp := struct { List []BrokerEarningItem `json:"list"` }{} - return resp.List, by.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/broker/earning-record", params, nil, &resp, defaultEPL) + return resp.List, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/broker/earning-record", params, nil, &resp, defaultEPL) } func processOB(ob [][2]types.Number) []orderbook.Level { @@ -2498,8 +2498,8 @@ func processOB(ob [][2]types.Number) []orderbook.Level { } // SendHTTPRequest sends an unauthenticated request -func (by *Bybit) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { - endpointPath, err := by.API.Endpoints.GetURL(ePath) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error { + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } @@ -2510,14 +2510,14 @@ func (by *Bybit) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path s response := &RestResponse{ Result: result, } - err = by.SendPayload(ctx, f, func() (*request.Item, error) { + err = e.SendPayload(ctx, f, func() (*request.Item, error) { return &request.Item{ Method: http.MethodGet, Path: endpointPath + bybitAPIVersion + path, Result: response, - Verbose: by.Verbose, - HTTPDebugging: by.HTTPDebugging, - HTTPRecording: by.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.UnauthenticatedRequest) if err != nil { @@ -2530,25 +2530,25 @@ func (by *Bybit) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path s } // SendAuthHTTPRequestV5 sends an authenticated HTTP request -func (by *Bybit) SendAuthHTTPRequestV5(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, arg, result any, f request.EndpointLimit) error { +func (e *Exchange) SendAuthHTTPRequestV5(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, arg, result any, f request.EndpointLimit) error { val := reflect.ValueOf(result) if val.Kind() != reflect.Ptr { return errNonePointerArgument } else if val.IsNil() { return errNilArgument } - creds, err := by.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpointPath, err := by.API.Endpoints.GetURL(ePath) + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } response := &RestResponse{ Result: result, } - err = by.SendPayload(ctx, f, func() (*request.Item, error) { + err = e.SendPayload(ctx, f, func() (*request.Item, error) { timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10) headers := make(map[string]string) headers["X-BAPI-API-KEY"] = creds.Key @@ -2580,9 +2580,9 @@ func (by *Bybit) SendAuthHTTPRequestV5(ctx context.Context, ePath exchange.URL, Headers: headers, Body: bytes.NewBuffer(payload), Result: &response, - Verbose: by.Verbose, - HTTPDebugging: by.HTTPDebugging, - HTTPRecording: by.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if response.RetCode != 0 && response.RetMsg != "" { @@ -2657,24 +2657,24 @@ func getSign(sign, secret string) (string, error) { } // FetchAccountType if not set fetches the account type from the API, stores it and returns it. Else returns the stored account type. -func (by *Bybit) FetchAccountType(ctx context.Context) (AccountType, error) { - by.account.m.Lock() - defer by.account.m.Unlock() - if by.account.accountType == 0 { - accInfo, err := by.GetAPIKeyInformation(ctx) +func (e *Exchange) FetchAccountType(ctx context.Context) (AccountType, error) { + e.account.m.Lock() + defer e.account.m.Unlock() + if e.account.accountType == 0 { + accInfo, err := e.GetAPIKeyInformation(ctx) if err != nil { return 0, err } // From endpoint 0:regular account; 1:unified trade account // + 1 to make it 1 and 2 so that a zero value can be used to check if the account type has been set or not. - by.account.accountType = AccountType(accInfo.IsUnifiedTradeAccount + 1) + e.account.accountType = AccountType(accInfo.IsUnifiedTradeAccount + 1) } - return by.account.accountType, nil + return e.account.accountType, nil } // RequiresUnifiedAccount checks account type and returns error if not unified -func (by *Bybit) RequiresUnifiedAccount(ctx context.Context) error { - at, err := by.FetchAccountType(ctx) +func (e *Exchange) RequiresUnifiedAccount(ctx context.Context) error { + at, err := e.FetchAccountType(ctx) if err != nil { return nil //nolint:nilerr // if we can't get the account type, we can't check if it's unified or not, fail on call } @@ -2685,7 +2685,7 @@ func (by *Bybit) RequiresUnifiedAccount(ctx context.Context) error { } // GetLongShortRatio retrieves long short ratio of an instrument. -func (by *Bybit) GetLongShortRatio(ctx context.Context, category, symbol string, interval kline.Interval, limit int64) ([]InstrumentInfoItem, error) { +func (e *Exchange) GetLongShortRatio(ctx context.Context, category, symbol string, interval kline.Interval, limit int64) ([]InstrumentInfoItem, error) { if category == "" { return nil, errCategoryNotSet } else if category != cLinear && category != cInverse { @@ -2708,5 +2708,5 @@ func (by *Bybit) GetLongShortRatio(ctx context.Context, category, symbol string, resp := struct { List []InstrumentInfoItem `json:"list"` }{} - return resp.List, by.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/account-ratio", params), defaultEPL, &resp) + return resp.List, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("market/account-ratio", params), defaultEPL, &resp) } diff --git a/exchanges/bybit/bybit_inverse_websocket.go b/exchanges/bybit/bybit_inverse_websocket.go index 19068ddb46c..dca241b04be 100644 --- a/exchanges/bybit/bybit_inverse_websocket.go +++ b/exchanges/bybit/bybit_inverse_websocket.go @@ -13,33 +13,33 @@ import ( ) // WsInverseConnect connects to inverse websocket feed -func (by *Bybit) WsInverseConnect() error { +func (e *Exchange) WsInverseConnect() error { ctx := context.TODO() - if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.CoinMarginedFutures) { + if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.CoinMarginedFutures) { return websocket.ErrWebsocketNotEnabled } - by.Websocket.Conn.SetURL(inversePublic) + e.Websocket.Conn.SetURL(inversePublic) var dialer gws.Dialer - err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: []byte(`{"op": "ping"}`), Delay: bybitWebsocketTimer, }) - by.Websocket.Wg.Add(1) - go by.wsReadData(ctx, asset.CoinMarginedFutures, by.Websocket.Conn) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, asset.CoinMarginedFutures, e.Websocket.Conn) return nil } // GenerateInverseDefaultSubscriptions generates default subscription -func (by *Bybit) GenerateInverseDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateInverseDefaultSubscriptions() (subscription.List, error) { var subscriptions subscription.List channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker} - pairs, err := by.GetEnabledPairs(asset.CoinMarginedFutures) + pairs, err := e.GetEnabledPairs(asset.CoinMarginedFutures) if err != nil { return nil, err } @@ -57,26 +57,26 @@ func (by *Bybit) GenerateInverseDefaultSubscriptions() (subscription.List, error } // InverseSubscribe sends a subscription message to linear public channels. -func (by *Bybit) InverseSubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) InverseSubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleInversePayloadSubscription(ctx, "subscribe", channelSubscriptions) + return e.handleInversePayloadSubscription(ctx, "subscribe", channelSubscriptions) } // InverseUnsubscribe sends an unsubscription messages through linear public channels. -func (by *Bybit) InverseUnsubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) InverseUnsubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleInversePayloadSubscription(ctx, "unsubscribe", channelSubscriptions) + return e.handleInversePayloadSubscription(ctx, "unsubscribe", channelSubscriptions) } -func (by *Bybit) handleInversePayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { - payloads, err := by.handleSubscriptions(operation, channelSubscriptions) +func (e *Exchange) handleInversePayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { + payloads, err := e.handleSubscriptions(operation, channelSubscriptions) if err != nil { return err } for a := range payloads { // The options connection does not send the subscription request id back with the subscription notification payload // therefore the code doesn't wait for the response to check whether the subscription is successful or not. - err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) if err != nil { return err } diff --git a/exchanges/bybit/bybit_linear_websocket.go b/exchanges/bybit/bybit_linear_websocket.go index c96a58e3a47..0e9e8c9bc91 100644 --- a/exchanges/bybit/bybit_linear_websocket.go +++ b/exchanges/bybit/bybit_linear_websocket.go @@ -13,47 +13,47 @@ import ( ) // WsLinearConnect connects to linear a websocket feed -func (by *Bybit) WsLinearConnect() error { +func (e *Exchange) WsLinearConnect() error { ctx := context.TODO() - if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.LinearContract) { + if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.LinearContract) { return websocket.ErrWebsocketNotEnabled } - by.Websocket.Conn.SetURL(linearPublic) + e.Websocket.Conn.SetURL(linearPublic) var dialer gws.Dialer - err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: []byte(`{"op": "ping"}`), Delay: bybitWebsocketTimer, }) - by.Websocket.Wg.Add(1) - go by.wsReadData(ctx, asset.LinearContract, by.Websocket.Conn) - if by.IsWebsocketAuthenticationSupported() { - err = by.WsAuth(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, asset.LinearContract, e.Websocket.Conn) + if e.IsWebsocketAuthenticationSupported() { + err = e.WsAuth(ctx) if err != nil { - by.Websocket.DataHandler <- err - by.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.DataHandler <- err + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } return nil } // GenerateLinearDefaultSubscriptions generates default subscription -func (by *Bybit) GenerateLinearDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateLinearDefaultSubscriptions() (subscription.List, error) { var subscriptions subscription.List channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker} - pairs, err := by.GetEnabledPairs(asset.USDTMarginedFutures) + pairs, err := e.GetEnabledPairs(asset.USDTMarginedFutures) if err != nil { return nil, err } linearPairMap := map[asset.Item]currency.Pairs{ asset.USDTMarginedFutures: pairs, } - usdcPairs, err := by.GetEnabledPairs(asset.USDCMarginedFutures) + usdcPairs, err := e.GetEnabledPairs(asset.USDCMarginedFutures) if err != nil { return nil, err } @@ -75,26 +75,26 @@ func (by *Bybit) GenerateLinearDefaultSubscriptions() (subscription.List, error) } // LinearSubscribe sends a subscription message to linear public channels. -func (by *Bybit) LinearSubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) LinearSubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleLinearPayloadSubscription(ctx, "subscribe", channelSubscriptions) + return e.handleLinearPayloadSubscription(ctx, "subscribe", channelSubscriptions) } // LinearUnsubscribe sends an unsubscription messages through linear public channels. -func (by *Bybit) LinearUnsubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) LinearUnsubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleLinearPayloadSubscription(ctx, "unsubscribe", channelSubscriptions) + return e.handleLinearPayloadSubscription(ctx, "unsubscribe", channelSubscriptions) } -func (by *Bybit) handleLinearPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { - payloads, err := by.handleSubscriptions(operation, channelSubscriptions) +func (e *Exchange) handleLinearPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { + payloads, err := e.handleSubscriptions(operation, channelSubscriptions) if err != nil { return err } for a := range payloads { // The options connection does not send the subscription request id back with the subscription notification payload // therefore the code doesn't wait for the response to check whether the subscription is successful or not. - err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) if err != nil { return err } diff --git a/exchanges/bybit/bybit_live_test.go b/exchanges/bybit/bybit_live_test.go index 971dfe1fdd6..cf82f2d130d 100644 --- a/exchanges/bybit/bybit_live_test.go +++ b/exchanges/bybit/bybit_live_test.go @@ -18,21 +18,21 @@ import ( var mockTests = false func TestMain(m *testing.M) { - b = new(Bybit) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bybit Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - b.API.AuthenticatedSupport = true - b.API.AuthenticatedWebsocketSupport = true - b.SetCredentials(apiKey, apiSecret, "", "", "", "") - b.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) } - if b.API.AuthenticatedSupport { - if _, err := b.FetchAccountType(context.Background()); err != nil { - log.Printf("%s unable to FetchAccountType: %v", b.Name, err) + if e.API.AuthenticatedSupport { + if _, err := e.FetchAccountType(context.Background()); err != nil { + log.Printf("%s unable to FetchAccountType: %v", e.Name, err) } } @@ -48,14 +48,14 @@ func instantiateTradablePairs() { } } - err := b.UpdateTradablePairs(context.Background(), true) + err := e.UpdateTradablePairs(context.Background(), true) handleError("unable to UpdateTradablePairs", err) setTradablePair := func(assetType asset.Item, p *currency.Pair) { - tradables, err := b.GetEnabledPairs(assetType) + tradables, err := e.GetEnabledPairs(assetType) handleError("unable to GetEnabledPairs", err) - format, err := b.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) handleError("unable to GetPairFormat", err) *p = tradables[0].Format(format) diff --git a/exchanges/bybit/bybit_mock_test.go b/exchanges/bybit/bybit_mock_test.go index fe4b49042d6..1e9dae6dbe6 100644 --- a/exchanges/bybit/bybit_mock_test.go +++ b/exchanges/bybit/bybit_mock_test.go @@ -18,25 +18,25 @@ import ( var mockTests = true func TestMain(m *testing.M) { - b = new(Bybit) - if err := testexch.Setup(b); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Bybit Setup error: %s", err) } - b.SetCredentials("mock", "tester", "", "", "", "") // Hack for UpdateAccountInfo test + e.SetCredentials("mock", "tester", "", "", "", "") // Hack for UpdateAccountInfo test - if err := testexch.MockHTTPInstance(b); err != nil { + if err := testexch.MockHTTPInstance(e); err != nil { log.Fatalf("Bybit MockHTTPInstance error: %s", err) } - if err := b.UpdateTradablePairs(context.Background(), true); err != nil { + if err := e.UpdateTradablePairs(context.Background(), true); err != nil { log.Fatalf("Bybit unable to UpdateTradablePairs: %s", err) } setEnabledPair := func(assetType asset.Item, pair currency.Pair) { - okay, err := b.IsPairEnabled(pair, assetType) + okay, err := e.IsPairEnabled(pair, assetType) if !okay || err != nil { - err = b.CurrencyPairs.EnablePair(assetType, pair) + err = e.CurrencyPairs.EnablePair(assetType, pair) if err != nil { log.Fatal(err) } diff --git a/exchanges/bybit/bybit_options_websocket.go b/exchanges/bybit/bybit_options_websocket.go index 3eff209c49d..7bda9ad78a5 100644 --- a/exchanges/bybit/bybit_options_websocket.go +++ b/exchanges/bybit/bybit_options_websocket.go @@ -15,38 +15,38 @@ import ( ) // WsOptionsConnect connects to options a websocket feed -func (by *Bybit) WsOptionsConnect() error { +func (e *Exchange) WsOptionsConnect() error { ctx := context.TODO() - if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Options) { + if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.Options) { return websocket.ErrWebsocketNotEnabled } - by.Websocket.Conn.SetURL(optionPublic) + e.Websocket.Conn.SetURL(optionPublic) var dialer gws.Dialer - err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - pingMessage := PingMessage{Operation: "ping", RequestID: strconv.FormatInt(by.Websocket.Conn.GenerateMessageID(false), 10)} + pingMessage := PingMessage{Operation: "ping", RequestID: strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10)} pingData, err := json.Marshal(pingMessage) if err != nil { return err } - by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: pingData, Delay: bybitWebsocketTimer, }) - by.Websocket.Wg.Add(1) - go by.wsReadData(ctx, asset.Options, by.Websocket.Conn) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, asset.Options, e.Websocket.Conn) return nil } // GenerateOptionsDefaultSubscriptions generates default subscription -func (by *Bybit) GenerateOptionsDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateOptionsDefaultSubscriptions() (subscription.List, error) { var subscriptions subscription.List channels := []string{chanOrderbook, chanPublicTrade, chanPublicTicker} - pairs, err := by.GetEnabledPairs(asset.Options) + pairs, err := e.GetEnabledPairs(asset.Options) if err != nil { return nil, err } @@ -64,26 +64,26 @@ func (by *Bybit) GenerateOptionsDefaultSubscriptions() (subscription.List, error } // OptionSubscribe sends a subscription message to options public channels. -func (by *Bybit) OptionSubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) OptionSubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleOptionsPayloadSubscription(ctx, "subscribe", channelSubscriptions) + return e.handleOptionsPayloadSubscription(ctx, "subscribe", channelSubscriptions) } // OptionUnsubscribe sends an unsubscription messages through options public channels. -func (by *Bybit) OptionUnsubscribe(channelSubscriptions subscription.List) error { +func (e *Exchange) OptionUnsubscribe(channelSubscriptions subscription.List) error { ctx := context.TODO() - return by.handleOptionsPayloadSubscription(ctx, "unsubscribe", channelSubscriptions) + return e.handleOptionsPayloadSubscription(ctx, "unsubscribe", channelSubscriptions) } -func (by *Bybit) handleOptionsPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { - payloads, err := by.handleSubscriptions(operation, channelSubscriptions) +func (e *Exchange) handleOptionsPayloadSubscription(ctx context.Context, operation string, channelSubscriptions subscription.List) error { + payloads, err := e.handleSubscriptions(operation, channelSubscriptions) if err != nil { return err } for a := range payloads { // The options connection does not send the subscription request id back with the subscription notification payload // therefore the code doesn't wait for the response to check whether the subscription is successful or not. - err = by.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, payloads[a]) if err != nil { return err } diff --git a/exchanges/bybit/bybit_test.go b/exchanges/bybit/bybit_test.go index 761561ea45b..0047c6ab8cc 100644 --- a/exchanges/bybit/bybit_test.go +++ b/exchanges/bybit/bybit_test.go @@ -46,22 +46,22 @@ const ( ) var ( - b = &Bybit{} + e *Exchange spotTradablePair, usdcMarginedTradablePair, usdtMarginedTradablePair, inverseTradablePair, optionsTradablePair currency.Pair ) func TestGetInstrumentInfo(t *testing.T) { t.Parallel() - _, err := b.GetInstrumentInfo(t.Context(), "spot", "", "", "", "", 0) + _, err := e.GetInstrumentInfo(t.Context(), "spot", "", "", "", "", 0) require.NoError(t, err) - _, err = b.GetInstrumentInfo(t.Context(), "linear", "", "", "", "", 0) + _, err = e.GetInstrumentInfo(t.Context(), "linear", "", "", "", "", 0) require.NoError(t, err) - _, err = b.GetInstrumentInfo(t.Context(), "inverse", "", "", "", "", 0) + _, err = e.GetInstrumentInfo(t.Context(), "inverse", "", "", "", "", 0) require.NoError(t, err) - _, err = b.GetInstrumentInfo(t.Context(), "option", "", "", "", "", 0) + _, err = e.GetInstrumentInfo(t.Context(), "option", "", "", "", "", 0) require.NoError(t, err) - payload, err := b.GetInstrumentInfo(t.Context(), "linear", "10000000AIDOGEUSDT", "", "", "", 0) + payload, err := e.GetInstrumentInfo(t.Context(), "linear", "10000000AIDOGEUSDT", "", "", "", 0) require.NoError(t, err) require.NotEmpty(t, payload.List) require.NotZero(t, payload.List[0].LotSizeFilter.MinNotionalValue) @@ -69,11 +69,11 @@ func TestGetInstrumentInfo(t *testing.T) { func TestGetKlines(t *testing.T) { t.Parallel() - s := time.Now().Add(-time.Hour) - e := time.Now() + startTime := time.Now().Add(-time.Hour) + endTime := time.Now() if mockTests { - s = time.Unix(1691897100, 0).Round(kline.FiveMin.Duration()) - e = time.Unix(1691907100, 0).Round(kline.FiveMin.Duration()) + startTime = time.Unix(1691897100, 0).Round(kline.FiveMin.Duration()) + endTime = time.Unix(1691907100, 0).Round(kline.FiveMin.Duration()) } for _, tc := range []struct { category string @@ -90,7 +90,7 @@ func TestGetKlines(t *testing.T) { } { t.Run(fmt.Sprintf("%s-%s", tc.category, tc.pair), func(t *testing.T) { t.Parallel() - r, err := b.GetKlines(t.Context(), tc.category, tc.pair.String(), kline.FiveMin, s, e, tc.reqLimit) + r, err := e.GetKlines(t.Context(), tc.category, tc.pair.String(), kline.FiveMin, startTime, endTime, tc.reqLimit) if tc.expError != nil { require.ErrorIs(t, err, tc.expError) return @@ -101,15 +101,15 @@ func TestGetKlines(t *testing.T) { switch tc.category { case "spot": - assert.Equal(t, KlineItem{StartTime: types.Time(e), Open: 29393.99, High: 29399.76, Low: 29393.98, Close: 29399.76, TradeVolume: 1.168988, Turnover: 34363.5346739}, r[0]) + assert.Equal(t, KlineItem{StartTime: types.Time(endTime), Open: 29393.99, High: 29399.76, Low: 29393.98, Close: 29399.76, TradeVolume: 1.168988, Turnover: 34363.5346739}, r[0]) case "linear": if tc.pair == usdtMarginedTradablePair { - assert.Equal(t, KlineItem{StartTime: types.Time(e), Open: 0.0003, High: 0.0003, Low: 0.0002995, Close: 0.0003, TradeVolume: 55102100, Turnover: 16506.2427}, r[0]) + assert.Equal(t, KlineItem{StartTime: types.Time(endTime), Open: 0.0003, High: 0.0003, Low: 0.0002995, Close: 0.0003, TradeVolume: 55102100, Turnover: 16506.2427}, r[0]) return } - assert.Equal(t, KlineItem{StartTime: types.Time(e), Open: 239.7, High: 239.7, Low: 239.7, Close: 239.7}, r[0]) + assert.Equal(t, KlineItem{StartTime: types.Time(endTime), Open: 239.7, High: 239.7, Low: 239.7, Close: 239.7}, r[0]) case "inverse": - assert.Equal(t, KlineItem{StartTime: types.Time(e), Open: 0.2908, High: 0.2912, Low: 0.2908, Close: 0.2912, TradeVolume: 5131, Turnover: 17626.40000346}, r[0]) + assert.Equal(t, KlineItem{StartTime: types.Time(endTime), Open: 0.2908, High: 0.2912, Low: 0.2908, Close: 0.2912, TradeVolume: 5131, Turnover: 17626.40000346}, r[0]) } } else { assert.NotEmpty(t, r) @@ -120,25 +120,25 @@ func TestGetKlines(t *testing.T) { func TestGetMarkPriceKline(t *testing.T) { t.Parallel() - s := time.Now().Add(-time.Hour * 1) - e := time.Now() + startTime := time.Now().Add(-time.Hour * 1) + endTime := time.Now() if mockTests { - s = time.UnixMilli(1693077167971) - e = time.UnixMilli(1693080767971) + startTime = time.UnixMilli(1693077167971) + endTime = time.UnixMilli(1693080767971) } - _, err := b.GetMarkPriceKline(t.Context(), "linear", usdtMarginedTradablePair.String(), kline.FiveMin, s, e, 5) + _, err := e.GetMarkPriceKline(t.Context(), "linear", usdtMarginedTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } - _, err = b.GetMarkPriceKline(t.Context(), "linear", usdcMarginedTradablePair.String(), kline.FiveMin, s, e, 5) + _, err = e.GetMarkPriceKline(t.Context(), "linear", usdcMarginedTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } - _, err = b.GetMarkPriceKline(t.Context(), "inverse", inverseTradablePair.String(), kline.FiveMin, s, e, 5) + _, err = e.GetMarkPriceKline(t.Context(), "inverse", inverseTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } - _, err = b.GetMarkPriceKline(t.Context(), "option", optionsTradablePair.String(), kline.FiveMin, s, e, 5) + _, err = e.GetMarkPriceKline(t.Context(), "option", optionsTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err == nil { t.Fatalf("expected 'params error: Category is invalid', but found nil") } @@ -146,21 +146,21 @@ func TestGetMarkPriceKline(t *testing.T) { func TestGetIndexPriceKline(t *testing.T) { t.Parallel() - s := time.Now().Add(-time.Hour * 1) - e := time.Now() + startTime := time.Now().Add(-time.Hour * 1) + endTime := time.Now() if mockTests { - s = time.UnixMilli(1693077165571) - e = time.UnixMilli(1693080765571) + startTime = time.UnixMilli(1693077165571) + endTime = time.UnixMilli(1693080765571) } - _, err := b.GetIndexPriceKline(t.Context(), "linear", usdtMarginedTradablePair.String(), kline.FiveMin, s, e, 5) + _, err := e.GetIndexPriceKline(t.Context(), "linear", usdtMarginedTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } - _, err = b.GetIndexPriceKline(t.Context(), "linear", usdcMarginedTradablePair.String(), kline.FiveMin, s, e, 5) + _, err = e.GetIndexPriceKline(t.Context(), "linear", usdcMarginedTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } - _, err = b.GetIndexPriceKline(t.Context(), "inverse", inverseTradablePair.String(), kline.FiveMin, s, e, 5) + _, err = e.GetIndexPriceKline(t.Context(), "inverse", inverseTradablePair.String(), kline.FiveMin, startTime, endTime, 5) if err != nil { t.Fatal(err) } @@ -168,23 +168,23 @@ func TestGetIndexPriceKline(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook(t.Context(), "spot", spotTradablePair.String(), 100) + _, err := e.GetOrderBook(t.Context(), "spot", spotTradablePair.String(), 100) if err != nil { t.Fatal(err) } - _, err = b.GetOrderBook(t.Context(), "linear", usdtMarginedTradablePair.String(), 100) + _, err = e.GetOrderBook(t.Context(), "linear", usdtMarginedTradablePair.String(), 100) if err != nil { t.Fatal(err) } - _, err = b.GetOrderBook(t.Context(), "linear", usdcMarginedTradablePair.String(), 100) + _, err = e.GetOrderBook(t.Context(), "linear", usdcMarginedTradablePair.String(), 100) if err != nil { t.Fatal(err) } - _, err = b.GetOrderBook(t.Context(), "inverse", inverseTradablePair.String(), 100) + _, err = e.GetOrderBook(t.Context(), "inverse", inverseTradablePair.String(), 100) if err != nil { t.Fatal(err) } - _, err = b.GetOrderBook(t.Context(), "option", optionsTradablePair.String(), 0) + _, err = e.GetOrderBook(t.Context(), "option", optionsTradablePair.String(), 0) if err != nil { t.Fatal(err) } @@ -192,45 +192,45 @@ func TestGetOrderBook(t *testing.T) { func TestGetRiskLimit(t *testing.T) { t.Parallel() - _, err := b.GetRiskLimit(t.Context(), "linear", usdtMarginedTradablePair.String()) + _, err := e.GetRiskLimit(t.Context(), "linear", usdtMarginedTradablePair.String()) if err != nil { t.Error(err) } - _, err = b.GetRiskLimit(t.Context(), "linear", usdcMarginedTradablePair.String()) + _, err = e.GetRiskLimit(t.Context(), "linear", usdcMarginedTradablePair.String()) if err != nil { t.Error(err) } - _, err = b.GetRiskLimit(t.Context(), "inverse", inverseTradablePair.String()) + _, err = e.GetRiskLimit(t.Context(), "inverse", inverseTradablePair.String()) if err != nil { t.Error(err) } - _, err = b.GetRiskLimit(t.Context(), "option", optionsTradablePair.String()) + _, err = e.GetRiskLimit(t.Context(), "option", optionsTradablePair.String()) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetRiskLimit(t.Context(), "spot", spotTradablePair.String()) + _, err = e.GetRiskLimit(t.Context(), "spot", spotTradablePair.String()) assert.ErrorIs(t, err, errInvalidCategory) } // test cases for Wrapper func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := b.UpdateTicker(t.Context(), spotTradablePair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), spotTradablePair, asset.Spot) if err != nil { t.Error(err) } - _, err = b.UpdateTicker(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures) + _, err = e.UpdateTicker(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateTicker(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures) + _, err = e.UpdateTicker(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateTicker(t.Context(), inverseTradablePair, asset.CoinMarginedFutures) + _, err = e.UpdateTicker(t.Context(), inverseTradablePair, asset.CoinMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateTicker(t.Context(), optionsTradablePair, asset.Options) + _, err = e.UpdateTicker(t.Context(), optionsTradablePair, asset.Options) if err != nil { t.Error(err) } @@ -239,24 +239,24 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() var err error - _, err = b.UpdateOrderbook(t.Context(), spotTradablePair, asset.Spot) + _, err = e.UpdateOrderbook(t.Context(), spotTradablePair, asset.Spot) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), inverseTradablePair, asset.CoinMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), inverseTradablePair, asset.CoinMarginedFutures) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(t.Context(), optionsTradablePair, asset.Options) + _, err = e.UpdateOrderbook(t.Context(), optionsTradablePair, asset.Options) if err != nil { t.Error(err) } @@ -267,9 +267,9 @@ func TestSubmitOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: b.GetName(), + Exchange: e.GetName(), Pair: spotTradablePair, Side: order.Buy, Type: order.Limit, @@ -278,12 +278,12 @@ func TestSubmitOrder(t *testing.T) { ClientOrderID: "1234", AssetType: asset.Spot, } - _, err := b.SubmitOrder(t.Context(), orderSubmission) + _, err := e.SubmitOrder(t.Context(), orderSubmission) if err != nil { t.Error(err) } - _, err = b.SubmitOrder(t.Context(), &order.Submit{ - Exchange: b.GetName(), + _, err = e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.GetName(), AssetType: asset.Options, Pair: optionsTradablePair, Side: order.Sell, @@ -303,8 +303,8 @@ func TestModifyOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifyOrder(t.Context(), &order.Modify{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder(t.Context(), &order.Modify{ OrderID: "1234", Type: order.Limit, Side: order.Buy, @@ -332,23 +332,23 @@ func TestGetHistoricCandles(t *testing.T) { start = time.UnixMilli(1692748800000) end = time.UnixMilli(1693094400000) } - _, err := b.GetHistoricCandles(t.Context(), spotTradablePair, asset.Spot, kline.OneDay, start, end) + _, err := e.GetHistoricCandles(t.Context(), spotTradablePair, asset.Spot, kline.OneDay, start, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandles(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, kline.OneDay, start, end) + _, err = e.GetHistoricCandles(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, kline.OneDay, start, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandles(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures, kline.OneDay, start, end) + _, err = e.GetHistoricCandles(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures, kline.OneDay, start, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandles(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, kline.OneHour, start, end) + _, err = e.GetHistoricCandles(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, kline.OneHour, start, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandles(t.Context(), optionsTradablePair, asset.Options, kline.OneHour, start, end) + _, err = e.GetHistoricCandles(t.Context(), optionsTradablePair, asset.Options, kline.OneHour, start, end) assert.ErrorIs(t, err, asset.ErrNotSupported) } @@ -360,19 +360,19 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime = time.UnixMilli(1692889428738) end = time.UnixMilli(1693145028738) } - _, err := b.GetHistoricCandlesExtended(t.Context(), spotTradablePair, asset.Spot, kline.OneMin, startTime, end) + _, err := e.GetHistoricCandlesExtended(t.Context(), spotTradablePair, asset.Spot, kline.OneMin, startTime, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandlesExtended(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, kline.OneHour, startTime, end) + _, err = e.GetHistoricCandlesExtended(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, kline.OneHour, startTime, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandlesExtended(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, kline.OneDay, time.UnixMilli(1692889428738), time.UnixMilli(1693145028738)) + _, err = e.GetHistoricCandlesExtended(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, kline.OneDay, time.UnixMilli(1692889428738), time.UnixMilli(1693145028738)) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandlesExtended(t.Context(), optionsTradablePair, asset.Options, kline.FiveMin, startTime, end) + _, err = e.GetHistoricCandlesExtended(t.Context(), optionsTradablePair, asset.Options, kline.FiveMin, startTime, end) assert.ErrorIs(t, err, asset.ErrNotSupported) } @@ -381,9 +381,9 @@ func TestCancelOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.CancelOrder(t.Context(), &order.Cancel{ - Exchange: b.Name, + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.CancelOrder(t.Context(), &order.Cancel{ + Exchange: e.Name, AssetType: asset.Spot, Pair: spotTradablePair, OrderID: "1234", @@ -391,8 +391,8 @@ func TestCancelOrder(t *testing.T) { if err != nil { t.Error(err) } - err = b.CancelOrder(t.Context(), &order.Cancel{ - Exchange: b.Name, + err = e.CancelOrder(t.Context(), &order.Cancel{ + Exchange: e.Name, AssetType: asset.USDTMarginedFutures, Pair: usdtMarginedTradablePair, OrderID: "1234", @@ -401,8 +401,8 @@ func TestCancelOrder(t *testing.T) { t.Error(err) } - err = b.CancelOrder(t.Context(), &order.Cancel{ - Exchange: b.Name, + err = e.CancelOrder(t.Context(), &order.Cancel{ + Exchange: e.Name, AssetType: asset.CoinMarginedFutures, Pair: inverseTradablePair, OrderID: "1234", @@ -410,8 +410,8 @@ func TestCancelOrder(t *testing.T) { if err != nil { t.Error(err) } - err = b.CancelOrder(t.Context(), &order.Cancel{ - Exchange: b.Name, + err = e.CancelOrder(t.Context(), &order.Cancel{ + Exchange: e.Name, AssetType: asset.Options, Pair: optionsTradablePair, OrderID: "1234", @@ -426,24 +426,24 @@ func TestCancelAllOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot, Pair: spotTradablePair}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot, Pair: spotTradablePair}) if err != nil { t.Error(err) } - _, err = b.CancelAllOrders(t.Context(), &order.Cancel{Exchange: b.Name, AssetType: asset.USDTMarginedFutures, Pair: usdtMarginedTradablePair}) + _, err = e.CancelAllOrders(t.Context(), &order.Cancel{Exchange: e.Name, AssetType: asset.USDTMarginedFutures, Pair: usdtMarginedTradablePair}) if err != nil { t.Error(err) } - _, err = b.CancelAllOrders(t.Context(), &order.Cancel{Exchange: b.Name, AssetType: asset.CoinMarginedFutures, Pair: inverseTradablePair}) + _, err = e.CancelAllOrders(t.Context(), &order.Cancel{Exchange: e.Name, AssetType: asset.CoinMarginedFutures, Pair: inverseTradablePair}) if err != nil { t.Error(err) } - _, err = b.CancelAllOrders(t.Context(), &order.Cancel{Exchange: b.Name, AssetType: asset.Options, Pair: optionsTradablePair}) + _, err = e.CancelAllOrders(t.Context(), &order.Cancel{Exchange: e.Name, AssetType: asset.Options, Pair: optionsTradablePair}) if err != nil { t.Error(err) } - _, err = b.CancelAllOrders(t.Context(), &order.Cancel{Exchange: b.Name, AssetType: asset.Futures, Pair: spotTradablePair}) + _, err = e.CancelAllOrders(t.Context(), &order.Cancel{Exchange: e.Name, AssetType: asset.Futures, Pair: spotTradablePair}) assert.ErrorIs(t, err, asset.ErrNotSupported) } @@ -452,23 +452,23 @@ func TestGetOrderInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetOrderInfo(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrderInfo(t.Context(), "12234", spotTradablePair, asset.Spot) if err != nil { t.Error(err) } - _, err = b.GetOrderInfo(t.Context(), + _, err = e.GetOrderInfo(t.Context(), "12234", usdtMarginedTradablePair, asset.USDTMarginedFutures) if err != nil { t.Error(err) } - _, err = b.GetOrderInfo(t.Context(), + _, err = e.GetOrderInfo(t.Context(), "12234", inverseTradablePair, asset.CoinMarginedFutures) if err != nil { t.Error(err) } - _, err = b.GetOrderInfo(t.Context(), + _, err = e.GetOrderInfo(t.Context(), "12234", optionsTradablePair, asset.Options) if err != nil { t.Error(err) @@ -480,29 +480,29 @@ func TestGetActiveOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequestSpot := order.MultiOrderRequest{ Pairs: currency.Pairs{spotTradablePair}, AssetType: asset.Spot, Side: order.AnySide, Type: order.AnyType, } - _, err := b.GetActiveOrders(t.Context(), &getOrdersRequestSpot) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequestSpot) if err != nil { t.Error(err) } getOrdersRequestLinear := order.MultiOrderRequest{Pairs: currency.Pairs{usdtMarginedTradablePair}, AssetType: asset.USDTMarginedFutures, Side: order.AnySide, Type: order.AnyType} - _, err = b.GetActiveOrders(t.Context(), &getOrdersRequestLinear) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequestLinear) if err != nil { t.Error(err) } getOrdersRequestInverse := order.MultiOrderRequest{Pairs: currency.Pairs{inverseTradablePair}, AssetType: asset.CoinMarginedFutures, Side: order.AnySide, Type: order.AnyType} - _, err = b.GetActiveOrders(t.Context(), &getOrdersRequestInverse) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequestInverse) if err != nil { t.Error(err) } getOrdersRequestFutures := order.MultiOrderRequest{Pairs: currency.Pairs{optionsTradablePair}, AssetType: asset.Options, Side: order.AnySide, Type: order.AnyType} - _, err = b.GetActiveOrders(t.Context(), &getOrdersRequestFutures) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequestFutures) if err != nil { t.Error(err) } @@ -511,7 +511,7 @@ func TestGetActiveOrders(t *testing.T) { t.Fatal(err) } getOrdersRequestSpot = order.MultiOrderRequest{Pairs: pairs, AssetType: asset.Spot, Side: order.AnySide, Type: order.AnyType} - _, err = b.GetActiveOrders(t.Context(), &getOrdersRequestSpot) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequestSpot) if err != nil { t.Error(err) } @@ -522,14 +522,14 @@ func TestGetOrderHistory(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequestSpot := order.MultiOrderRequest{ Pairs: currency.Pairs{spotTradablePair}, AssetType: asset.Spot, Type: order.AnyType, Side: order.AnySide, } - _, err := b.GetOrderHistory(t.Context(), &getOrdersRequestSpot) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequestSpot) if err != nil { t.Error(err) } @@ -539,13 +539,13 @@ func TestGetOrderHistory(t *testing.T) { Type: order.AnyType, Side: order.AnySide, } - _, err = b.GetOrderHistory(t.Context(), &getOrdersRequestUMF) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequestUMF) if err != nil { t.Error(err) } getOrdersRequestUMF.Pairs = currency.Pairs{usdcMarginedTradablePair} getOrdersRequestUMF.AssetType = asset.USDCMarginedFutures - _, err = b.GetOrderHistory(t.Context(), &getOrdersRequestUMF) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequestUMF) if err != nil { t.Error(err) } @@ -555,7 +555,7 @@ func TestGetOrderHistory(t *testing.T) { Type: order.AnyType, Side: order.AnySide, } - _, err = b.GetOrderHistory(t.Context(), &getOrdersRequestCMF) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequestCMF) if err != nil { t.Error(err) } @@ -565,7 +565,7 @@ func TestGetOrderHistory(t *testing.T) { Type: order.AnyType, Side: order.AnySide, } - _, err = b.GetOrderHistory(t.Context(), &getOrdersRequestFutures) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequestFutures) if err != nil { t.Error(err) } @@ -576,8 +576,8 @@ func TestGetDepositAddress(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetDepositAddress(t.Context(), currency.USDT, "", currency.ETH.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", currency.ETH.String()) if err != nil { t.Error(err) } @@ -588,8 +588,8 @@ func TestGetAvailableTransferChains(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAvailableTransferChains(t.Context(), currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAvailableTransferChains(t.Context(), currency.USDT) if err != nil { t.Error(err) } @@ -600,8 +600,8 @@ func TestWithdrawCryptocurrencyFunds(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ Exchange: "Bybit", Amount: 10, Currency: currency.LTC, @@ -619,19 +619,19 @@ func TestWithdrawCryptocurrencyFunds(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() ctx := t.Context() - err := b.UpdateTickers(ctx, asset.Spot) + err := e.UpdateTickers(ctx, asset.Spot) if err != nil { t.Fatalf("%v %v\n", asset.Spot, err) } - err = b.UpdateTickers(ctx, asset.USDTMarginedFutures) + err = e.UpdateTickers(ctx, asset.USDTMarginedFutures) if err != nil { t.Fatalf("%v %v\n", asset.USDTMarginedFutures, err) } - err = b.UpdateTickers(ctx, asset.CoinMarginedFutures) + err = e.UpdateTickers(ctx, asset.CoinMarginedFutures) if err != nil { t.Fatalf("%v %v\n", asset.CoinMarginedFutures, err) } - err = b.UpdateTickers(ctx, asset.Options) + err = e.UpdateTickers(ctx, asset.Options) if err != nil { t.Fatalf("%v %v\n", asset.Options, err) } @@ -639,63 +639,63 @@ func TestUpdateTickers(t *testing.T) { func TestGetTickersV5(t *testing.T) { t.Parallel() - _, err := b.GetTickers(t.Context(), "bruh", "", "", time.Time{}) + _, err := e.GetTickers(t.Context(), "bruh", "", "", time.Time{}) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetTickers(t.Context(), "option", "BTC-26NOV24-92000-C", "", time.Time{}) + _, err = e.GetTickers(t.Context(), "option", "BTC-26NOV24-92000-C", "", time.Time{}) require.NoError(t, err) - _, err = b.GetTickers(t.Context(), "spot", "", "", time.Time{}) + _, err = e.GetTickers(t.Context(), "spot", "", "", time.Time{}) require.NoError(t, err) - _, err = b.GetTickers(t.Context(), "inverse", "", "", time.Time{}) + _, err = e.GetTickers(t.Context(), "inverse", "", "", time.Time{}) require.NoError(t, err) - _, err = b.GetTickers(t.Context(), "linear", "", "", time.Time{}) + _, err = e.GetTickers(t.Context(), "linear", "", "", time.Time{}) require.NoError(t, err) - _, err = b.GetTickers(t.Context(), "option", "", "BTC", time.Time{}) + _, err = e.GetTickers(t.Context(), "option", "", "BTC", time.Time{}) require.NoError(t, err) } func TestGetFundingRateHistory(t *testing.T) { t.Parallel() - _, err := b.GetFundingRateHistory(t.Context(), "bruh", "", time.Time{}, time.Time{}, 0) + _, err := e.GetFundingRateHistory(t.Context(), "bruh", "", time.Time{}, time.Time{}, 0) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetFundingRateHistory(t.Context(), "spot", spotTradablePair.String(), time.Time{}, time.Time{}, 100) + _, err = e.GetFundingRateHistory(t.Context(), "spot", spotTradablePair.String(), time.Time{}, time.Time{}, 100) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetFundingRateHistory(t.Context(), "linear", usdtMarginedTradablePair.String(), time.Time{}, time.Time{}, 100) + _, err = e.GetFundingRateHistory(t.Context(), "linear", usdtMarginedTradablePair.String(), time.Time{}, time.Time{}, 100) if err != nil { t.Error(err) } - _, err = b.GetFundingRateHistory(t.Context(), "linear", usdcMarginedTradablePair.String(), time.Time{}, time.Time{}, 100) + _, err = e.GetFundingRateHistory(t.Context(), "linear", usdcMarginedTradablePair.String(), time.Time{}, time.Time{}, 100) if err != nil { t.Error(err) } - _, err = b.GetFundingRateHistory(t.Context(), "inverse", inverseTradablePair.String(), time.Time{}, time.Time{}, 100) + _, err = e.GetFundingRateHistory(t.Context(), "inverse", inverseTradablePair.String(), time.Time{}, time.Time{}, 100) if err != nil { t.Error(err) } - _, err = b.GetFundingRateHistory(t.Context(), "option", optionsTradablePair.String(), time.Time{}, time.Time{}, 100) + _, err = e.GetFundingRateHistory(t.Context(), "option", optionsTradablePair.String(), time.Time{}, time.Time{}, 100) assert.ErrorIs(t, err, errInvalidCategory) } func TestGetPublicTradingHistory(t *testing.T) { t.Parallel() - _, err := b.GetPublicTradingHistory(t.Context(), "spot", spotTradablePair.String(), "", "", 30) + _, err := e.GetPublicTradingHistory(t.Context(), "spot", spotTradablePair.String(), "", "", 30) if err != nil { t.Error(err) } - _, err = b.GetPublicTradingHistory(t.Context(), "linear", usdtMarginedTradablePair.String(), "", "", 30) + _, err = e.GetPublicTradingHistory(t.Context(), "linear", usdtMarginedTradablePair.String(), "", "", 30) if err != nil { t.Error(err) } - _, err = b.GetPublicTradingHistory(t.Context(), "linear", usdcMarginedTradablePair.String(), "", "", 30) + _, err = e.GetPublicTradingHistory(t.Context(), "linear", usdcMarginedTradablePair.String(), "", "", 30) if err != nil { t.Error(err) } - _, err = b.GetPublicTradingHistory(t.Context(), "inverse", inverseTradablePair.String(), "", "", 30) + _, err = e.GetPublicTradingHistory(t.Context(), "inverse", inverseTradablePair.String(), "", "", 30) if err != nil { t.Error(err) } - _, err = b.GetPublicTradingHistory(t.Context(), "option", optionsTradablePair.String(), "BTC", "", 30) + _, err = e.GetPublicTradingHistory(t.Context(), "option", optionsTradablePair.String(), "BTC", "", 30) if err != nil { t.Error(err) } @@ -703,22 +703,22 @@ func TestGetPublicTradingHistory(t *testing.T) { func TestGetOpenInterestData(t *testing.T) { t.Parallel() - _, err := b.GetOpenInterestData(t.Context(), "spot", spotTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") + _, err := e.GetOpenInterestData(t.Context(), "spot", spotTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetOpenInterestData(t.Context(), "linear", usdtMarginedTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") + _, err = e.GetOpenInterestData(t.Context(), "linear", usdtMarginedTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") if err != nil { t.Error(err) } - _, err = b.GetOpenInterestData(t.Context(), "linear", usdcMarginedTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") + _, err = e.GetOpenInterestData(t.Context(), "linear", usdcMarginedTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") if err != nil { t.Error(err) } - _, err = b.GetOpenInterestData(t.Context(), "inverse", inverseTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") + _, err = e.GetOpenInterestData(t.Context(), "inverse", inverseTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") if err != nil { t.Error(err) } - _, err = b.GetOpenInterestData(t.Context(), "option", optionsTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") + _, err = e.GetOpenInterestData(t.Context(), "option", optionsTradablePair.String(), "5min", time.Time{}, time.Time{}, 0, "") assert.ErrorIs(t, err, errInvalidCategory) } @@ -730,17 +730,17 @@ func TestGetHistoricalVolatility(t *testing.T) { end = time.UnixMilli(1693080759395) start = time.UnixMilli(1690488759395) } - _, err := b.GetHistoricalVolatility(t.Context(), "option", "", 123, start, end) + _, err := e.GetHistoricalVolatility(t.Context(), "option", "", 123, start, end) if err != nil { t.Error(err) } - _, err = b.GetHistoricalVolatility(t.Context(), "spot", "", 123, start, end) + _, err = e.GetHistoricalVolatility(t.Context(), "spot", "", 123, start, end) assert.ErrorIs(t, err, errInvalidCategory) } func TestGetInsurance(t *testing.T) { t.Parallel() - _, err := b.GetInsurance(t.Context(), "") + _, err := e.GetInsurance(t.Context(), "") if err != nil { t.Error(err) } @@ -748,18 +748,18 @@ func TestGetInsurance(t *testing.T) { func TestGetDeliveryPrice(t *testing.T) { t.Parallel() - _, err := b.GetDeliveryPrice(t.Context(), "spot", spotTradablePair.String(), "", "", 200) + _, err := e.GetDeliveryPrice(t.Context(), "spot", spotTradablePair.String(), "", "", 200) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetDeliveryPrice(t.Context(), "linear", "", "", "", 200) + _, err = e.GetDeliveryPrice(t.Context(), "linear", "", "", "", 200) if err != nil { t.Error(err) } - _, err = b.GetDeliveryPrice(t.Context(), "inverse", "", "", "", 200) + _, err = e.GetDeliveryPrice(t.Context(), "inverse", "", "", "", 200) if err != nil { t.Error(err) } - _, err = b.GetDeliveryPrice(t.Context(), "option", "", "BTC", "", 200) + _, err = e.GetDeliveryPrice(t.Context(), "option", "", "BTC", "", 200) if err != nil { t.Error(err) } @@ -767,24 +767,24 @@ func TestGetDeliveryPrice(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits(t.Context(), asset.Futures) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) - err = b.UpdateOrderExecutionLimits(t.Context(), asset.Options) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Options) assert.NoError(t, err) - err = b.UpdateOrderExecutionLimits(t.Context(), asset.USDCMarginedFutures) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.USDCMarginedFutures) assert.NoError(t, err) - err = b.UpdateOrderExecutionLimits(t.Context(), asset.USDTMarginedFutures) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.USDTMarginedFutures) assert.NoError(t, err) - err = b.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) assert.NoError(t, err) - availablePairs, err := b.GetAvailablePairs(asset.Spot) + availablePairs, err := e.GetAvailablePairs(asset.Spot) if err != nil { t.Fatal("Bybit GetAvailablePairs() error", err) } for x := range availablePairs { var limits order.MinMaxLevel - limits, err = b.GetOrderExecutionLimits(asset.Spot, availablePairs[x]) + limits, err = e.GetOrderExecutionLimits(asset.Spot, availablePairs[x]) require.NoError(t, err) if limits == (order.MinMaxLevel{}) { t.Fatal("Bybit GetOrderExecutionLimits() error cannot be nil") @@ -797,38 +797,38 @@ func TestPlaceOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) ctx := t.Context() - _, err := b.PlaceOrder(ctx, nil) + _, err := e.PlaceOrder(ctx, nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{}) + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{}) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "my-category", }) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "spot", }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "spot", Symbol: currency.Pair{Delimiter: "", Base: currency.BTC, Quote: currency.USDT}, }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "spot", Symbol: spotTradablePair, Side: "buy", }) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "spot", Symbol: spotTradablePair, Side: "buy", @@ -836,7 +836,7 @@ func TestPlaceOrder(t *testing.T) { }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.PlaceOrder(ctx, &PlaceOrderParams{ + _, err = e.PlaceOrder(ctx, &PlaceOrderParams{ Category: "spot", Symbol: spotTradablePair, Side: "buy", @@ -846,7 +846,7 @@ func TestPlaceOrder(t *testing.T) { }) require.ErrorIs(t, err, errInvalidTriggerDirection) - _, err = b.PlaceOrder(t.Context(), &PlaceOrderParams{ + _, err = e.PlaceOrder(t.Context(), &PlaceOrderParams{ Category: "spot", Symbol: spotTradablePair, Side: "buy", @@ -860,7 +860,7 @@ func TestPlaceOrder(t *testing.T) { } // Spot post only normal order arg := &PlaceOrderParams{Category: "spot", Symbol: spotTradablePair, Side: "Buy", OrderType: "Limit", OrderQuantity: 0.1, Price: 15600, TimeInForce: "PostOnly", OrderLinkID: "spot-test-01", IsLeverage: 0, OrderFilter: "Order"} - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -872,7 +872,7 @@ func TestPlaceOrder(t *testing.T) { OrderQuantity: 0.1, Price: 15600, TriggerPrice: 15000, TimeInForce: "GTC", OrderLinkID: "spot-test-02", IsLeverage: 0, OrderFilter: "tpslOrder", } - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -881,7 +881,7 @@ func TestPlaceOrder(t *testing.T) { Category: "spot", Symbol: spotTradablePair, Side: "Buy", OrderType: "Limit", OrderQuantity: 0.1, Price: 15600, TimeInForce: "IOC", OrderLinkID: "spot-test-limit", IsLeverage: 1, OrderFilter: "Order", } - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -892,7 +892,7 @@ func TestPlaceOrder(t *testing.T) { TimeInForce: "IOC", OrderLinkID: "spot-test-04", IsLeverage: 0, OrderFilter: "Order", } - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -901,7 +901,7 @@ func TestPlaceOrder(t *testing.T) { Category: "linear", Symbol: usdcMarginedTradablePair, Side: "Buy", OrderType: "Limit", OrderQuantity: 1, Price: 25000, TimeInForce: "GTC", PositionIdx: 0, OrderLinkID: "usdt-test-01", ReduceOnly: false, TakeProfitPrice: 28000, StopLossPrice: 20000, TpslMode: "Partial", TpOrderType: "Limit", SlOrderType: "Limit", TpLimitPrice: 27500, SlLimitPrice: 20500, } - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -910,7 +910,7 @@ func TestPlaceOrder(t *testing.T) { Category: "linear", Symbol: usdtMarginedTradablePair, Side: "Sell", OrderType: "Limit", OrderQuantity: 1, Price: 3000, TimeInForce: "GTC", PositionIdx: 0, OrderLinkID: "usdt-test-02", ReduceOnly: true, } - _, err = b.PlaceOrder(t.Context(), arg) + _, err = e.PlaceOrder(t.Context(), arg) if err != nil { t.Error(err) } @@ -921,31 +921,31 @@ func TestAmendOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.AmendOrder(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.AmendOrder(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.AmendOrder(t.Context(), &AmendOrderParams{}) + _, err = e.AmendOrder(t.Context(), &AmendOrderParams{}) require.ErrorIs(t, err, errEitherOrderIDOROrderLinkIDRequired) - _, err = b.AmendOrder(t.Context(), &AmendOrderParams{ + _, err = e.AmendOrder(t.Context(), &AmendOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", }) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.AmendOrder(t.Context(), &AmendOrderParams{ + _, err = e.AmendOrder(t.Context(), &AmendOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: "mycat", }) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.AmendOrder(t.Context(), &AmendOrderParams{ + _, err = e.AmendOrder(t.Context(), &AmendOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: "option", }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = b.AmendOrder(t.Context(), &AmendOrderParams{ + _, err = e.AmendOrder(t.Context(), &AmendOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: cSpot, Symbol: spotTradablePair, @@ -965,31 +965,31 @@ func TestCancelTradeOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelTradeOrder(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelTradeOrder(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CancelTradeOrder(t.Context(), &CancelOrderParams{}) + _, err = e.CancelTradeOrder(t.Context(), &CancelOrderParams{}) require.ErrorIs(t, err, errEitherOrderIDOROrderLinkIDRequired) - _, err = b.CancelTradeOrder(t.Context(), &CancelOrderParams{ + _, err = e.CancelTradeOrder(t.Context(), &CancelOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", }) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.CancelTradeOrder(t.Context(), &CancelOrderParams{ + _, err = e.CancelTradeOrder(t.Context(), &CancelOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: "mycat", }) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.CancelTradeOrder(t.Context(), &CancelOrderParams{ + _, err = e.CancelTradeOrder(t.Context(), &CancelOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: "option", }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = b.CancelTradeOrder(t.Context(), &CancelOrderParams{ + _, err = e.CancelTradeOrder(t.Context(), &CancelOrderParams{ OrderID: "c6f055d9-7f21-4079-913d-e6523a9cfffa", Category: "option", Symbol: optionsTradablePair, @@ -1002,12 +1002,12 @@ func TestCancelTradeOrder(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetOpenOrders(t.Context(), "", "", "", "", "", "", "", "", 0, 100) + _, err := e.GetOpenOrders(t.Context(), "", "", "", "", "", "", "", "", 0, 100) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetOpenOrders(t.Context(), "spot", "", "", "", "", "", "", "", 0, 0) + _, err = e.GetOpenOrders(t.Context(), "spot", "", "", "", "", "", "", "", 0, 0) if err != nil { t.Error(err) } @@ -1018,14 +1018,14 @@ func TestCancelAllTradeOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelAllTradeOrders(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllTradeOrders(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CancelAllTradeOrders(t.Context(), &CancelAllOrdersParam{}) + _, err = e.CancelAllTradeOrders(t.Context(), &CancelAllOrdersParam{}) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.CancelAllTradeOrders(t.Context(), &CancelAllOrdersParam{Category: "option"}) + _, err = e.CancelAllTradeOrders(t.Context(), &CancelAllOrdersParam{Category: "option"}) if err != nil { t.Error(err) } @@ -1039,12 +1039,12 @@ func TestGetTradeOrderHistory(t *testing.T) { end = time.UnixMilli(1700058627109) start = time.UnixMilli(1699540227109) } else { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetTradeOrderHistory(t.Context(), "", "", "", "", "", "", "", "", "", start, end, 100) + _, err := e.GetTradeOrderHistory(t.Context(), "", "", "", "", "", "", "", "", "", start, end, 100) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetTradeOrderHistory(t.Context(), "spot", spotTradablePair.String(), "", "", "BTC", "", "StopOrder", "", "", start, end, 100) + _, err = e.GetTradeOrderHistory(t.Context(), "spot", spotTradablePair.String(), "", "", "BTC", "", "StopOrder", "", "", start, end, 100) if err != nil { t.Error(err) } @@ -1055,19 +1055,19 @@ func TestPlaceBatchOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.PlaceBatchOrder(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceBatchOrder(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{}) + _, err = e.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{}) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ + _, err = e.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ Category: "linear", }) require.ErrorIs(t, err, errNoOrderPassed) - _, err = b.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ + _, err = e.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ Category: "option", Request: []BatchOrderItemParam{ { @@ -1097,7 +1097,7 @@ func TestPlaceBatchOrder(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ + _, err = e.PlaceBatchOrder(t.Context(), &PlaceBatchOrderParam{ Category: "linear", Request: []BatchOrderItemParam{ { @@ -1134,11 +1134,11 @@ func TestBatchAmendOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.BatchAmendOrder(t.Context(), "linear", nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.BatchAmendOrder(t.Context(), "linear", nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.BatchAmendOrder(t.Context(), "", []BatchAmendOrderParamItem{ + _, err = e.BatchAmendOrder(t.Context(), "", []BatchAmendOrderParamItem{ { Symbol: optionsTradablePair, OrderImpliedVolatility: "6.8", @@ -1147,7 +1147,7 @@ func TestBatchAmendOrder(t *testing.T) { }) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.BatchAmendOrder(t.Context(), "option", []BatchAmendOrderParamItem{ + _, err = e.BatchAmendOrder(t.Context(), "option", []BatchAmendOrderParamItem{ { Symbol: optionsTradablePair, OrderImpliedVolatility: "6.8", @@ -1169,17 +1169,17 @@ func TestCancelBatchOrder(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelBatchOrder(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrder(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CancelBatchOrder(t.Context(), &CancelBatchOrder{}) + _, err = e.CancelBatchOrder(t.Context(), &CancelBatchOrder{}) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.CancelBatchOrder(t.Context(), &CancelBatchOrder{Category: cOption}) + _, err = e.CancelBatchOrder(t.Context(), &CancelBatchOrder{Category: cOption}) require.ErrorIs(t, err, errNoOrderPassed) - _, err = b.CancelBatchOrder(t.Context(), &CancelBatchOrder{ + _, err = e.CancelBatchOrder(t.Context(), &CancelBatchOrder{ Category: "option", Request: []CancelOrderParams{ { @@ -1200,18 +1200,18 @@ func TestCancelBatchOrder(t *testing.T) { func TestGetBorrowQuota(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetBorrowQuota(t.Context(), "", "BTCUSDT", "Buy") + _, err := e.GetBorrowQuota(t.Context(), "", "BTCUSDT", "Buy") require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetBorrowQuota(t.Context(), "spot", "", "Buy") + _, err = e.GetBorrowQuota(t.Context(), "spot", "", "Buy") require.ErrorIs(t, err, errSymbolMissing) - _, err = b.GetBorrowQuota(t.Context(), "spot", spotTradablePair.String(), "") + _, err = e.GetBorrowQuota(t.Context(), "spot", spotTradablePair.String(), "") assert.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = b.GetBorrowQuota(t.Context(), "spot", spotTradablePair.String(), "Buy") + _, err = e.GetBorrowQuota(t.Context(), "spot", spotTradablePair.String(), "Buy") if err != nil { t.Error(err) } @@ -1222,11 +1222,11 @@ func TestSetDisconnectCancelAll(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetDisconnectCancelAll(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetDisconnectCancelAll(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - err = b.SetDisconnectCancelAll(t.Context(), &SetDCPParams{TimeWindow: 300}) + err = e.SetDisconnectCancelAll(t.Context(), &SetDCPParams{TimeWindow: 300}) if err != nil { t.Fatal(err) } @@ -1235,19 +1235,19 @@ func TestSetDisconnectCancelAll(t *testing.T) { func TestGetPositionInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetPositionInfo(t.Context(), "", "", "", "", "", 20) + _, err := e.GetPositionInfo(t.Context(), "", "", "", "", "", 20) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetPositionInfo(t.Context(), "spot", "", "", "", "", 20) + _, err = e.GetPositionInfo(t.Context(), "spot", "", "", "", "", 20) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPositionInfo(t.Context(), "linear", "BTCUSDT", "", "", "", 20) + _, err = e.GetPositionInfo(t.Context(), "linear", "BTCUSDT", "", "", "", 20) if err != nil { t.Error(err) } - _, err = b.GetPositionInfo(t.Context(), "option", "BTC-26NOV24-92000-C", "BTC", "", "", 20) + _, err = e.GetPositionInfo(t.Context(), "option", "BTC-26NOV24-92000-C", "BTC", "", "", 20) if err != nil { t.Error(err) } @@ -1258,23 +1258,23 @@ func TestSetLeverageLevel(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetLeverageLevel(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetLeverageLevel(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - err = b.SetLeverageLevel(t.Context(), &SetLeverageParams{}) + err = e.SetLeverageLevel(t.Context(), &SetLeverageParams{}) require.ErrorIs(t, err, errCategoryNotSet) - err = b.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "spot"}) + err = e.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "spot"}) require.ErrorIs(t, err, errInvalidCategory) - err = b.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear"}) + err = e.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear"}) require.ErrorIs(t, err, errSymbolMissing) - err = b.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear", Symbol: "BTCUSDT"}) + err = e.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear", Symbol: "BTCUSDT"}) require.ErrorIs(t, err, errInvalidLeverage) - err = b.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear", Symbol: "BTCUSDT", SellLeverage: 3, BuyLeverage: 3}) + err = e.SetLeverageLevel(t.Context(), &SetLeverageParams{Category: "linear", Symbol: "BTCUSDT", SellLeverage: 3, BuyLeverage: 3}) if err != nil { t.Error(err) } @@ -1285,26 +1285,26 @@ func TestSwitchTradeMode(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SwitchTradeMode(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SwitchTradeMode(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{}) require.ErrorIs(t, err, errCategoryNotSet) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "spot"}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "spot"}) require.ErrorIs(t, err, errInvalidCategory) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear"}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear"}) require.ErrorIs(t, err, errSymbolMissing) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdtMarginedTradablePair.String()}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdtMarginedTradablePair.String()}) require.ErrorIs(t, err, errInvalidLeverage) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdcMarginedTradablePair.String(), SellLeverage: 3, BuyLeverage: 3, TradeMode: 2}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdcMarginedTradablePair.String(), SellLeverage: 3, BuyLeverage: 3, TradeMode: 2}) require.ErrorIs(t, err, errInvalidTradeModeValue) - err = b.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdtMarginedTradablePair.String(), SellLeverage: 3, BuyLeverage: 3, TradeMode: 1}) + err = e.SwitchTradeMode(t.Context(), &SwitchTradeModeParams{Category: "linear", Symbol: usdtMarginedTradablePair.String(), SellLeverage: 3, BuyLeverage: 3, TradeMode: 1}) if err != nil { t.Error(err) } @@ -1315,28 +1315,28 @@ func TestSetTakeProfitStopLossMode(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.SetTakeProfitStopLossMode(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.SetTakeProfitStopLossMode(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{}) + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{}) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{ + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{ Category: "spot", }) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "spot"}) + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "spot"}) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear"}) + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear"}) require.ErrorIs(t, err, errSymbolMissing) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear", Symbol: "BTCUSDT"}) + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear", Symbol: "BTCUSDT"}) require.ErrorIs(t, err, errTakeProfitOrStopLossModeMissing) - _, err = b.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear", Symbol: "BTCUSDT", TpslMode: "Partial"}) + _, err = e.SetTakeProfitStopLossMode(t.Context(), &TPSLModeParams{Category: "linear", Symbol: "BTCUSDT", TpslMode: "Partial"}) if err != nil { t.Error(err) } @@ -1347,17 +1347,17 @@ func TestSwitchPositionMode(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SwitchPositionMode(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SwitchPositionMode(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - err = b.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{}) + err = e.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{}) require.ErrorIs(t, err, errCategoryNotSet) - err = b.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{Category: "linear"}) + err = e.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{Category: "linear"}) require.ErrorIs(t, err, errEitherSymbolOrCoinRequired) - err = b.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{Category: "linear", Symbol: usdtMarginedTradablePair, PositionMode: 3}) + err = e.SwitchPositionMode(t.Context(), &SwitchPositionModeParams{Category: "linear", Symbol: usdtMarginedTradablePair, PositionMode: 3}) if err != nil { t.Error(err) } @@ -1368,20 +1368,20 @@ func TestSetRiskLimit(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.SetRiskLimit(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.SetRiskLimit(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.SetRiskLimit(t.Context(), &SetRiskLimitParam{}) + _, err = e.SetRiskLimit(t.Context(), &SetRiskLimitParam{}) assert.ErrorIs(t, err, errCategoryNotSet) - _, err = b.SetRiskLimit(t.Context(), &SetRiskLimitParam{Category: "linear", PositionMode: -2}) + _, err = e.SetRiskLimit(t.Context(), &SetRiskLimitParam{Category: "linear", PositionMode: -2}) assert.ErrorIs(t, err, errInvalidPositionMode) - _, err = b.SetRiskLimit(t.Context(), &SetRiskLimitParam{Category: "linear"}) + _, err = e.SetRiskLimit(t.Context(), &SetRiskLimitParam{Category: "linear"}) assert.ErrorIs(t, err, errSymbolMissing) - _, err = b.SetRiskLimit(t.Context(), &SetRiskLimitParam{ + _, err = e.SetRiskLimit(t.Context(), &SetRiskLimitParam{ Category: "linear", RiskID: 1234, Symbol: usdtMarginedTradablePair, @@ -1397,14 +1397,14 @@ func TestSetTradingStop(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetTradingStop(t.Context(), &TradingStopParams{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetTradingStop(t.Context(), &TradingStopParams{}) assert.ErrorIs(t, err, errCategoryNotSet) - err = b.SetTradingStop(t.Context(), &TradingStopParams{Category: "spot"}) + err = e.SetTradingStop(t.Context(), &TradingStopParams{Category: "spot"}) assert.ErrorIs(t, err, errInvalidCategory) - err = b.SetTradingStop(t.Context(), &TradingStopParams{ + err = e.SetTradingStop(t.Context(), &TradingStopParams{ Category: "linear", Symbol: usdtMarginedTradablePair, TakeProfit: "0.5", @@ -1423,7 +1423,7 @@ func TestSetTradingStop(t *testing.T) { if err != nil { t.Error(err) } - err = b.SetTradingStop(t.Context(), &TradingStopParams{ + err = e.SetTradingStop(t.Context(), &TradingStopParams{ Category: "linear", Symbol: usdcMarginedTradablePair, TakeProfit: "0.5", @@ -1449,8 +1449,8 @@ func TestSetAutoAddMargin(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetAutoAddMargin(t.Context(), &AutoAddMarginParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetAutoAddMargin(t.Context(), &AutoAddMarginParam{ Category: "inverse", Symbol: inverseTradablePair, AutoAddmargin: 0, @@ -1466,8 +1466,8 @@ func TestAddOrReduceMargin(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.AddOrReduceMargin(t.Context(), &AddOrReduceMarginParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.AddOrReduceMargin(t.Context(), &AddOrReduceMarginParam{ Category: "inverse", Symbol: inverseTradablePair, Margin: -10, @@ -1481,9 +1481,9 @@ func TestAddOrReduceMargin(t *testing.T) { func TestGetExecution(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetExecution(t.Context(), "spot", "", "", "", "", "Trade", "tpslOrder", "", time.Time{}, time.Time{}, 0) + _, err := e.GetExecution(t.Context(), "spot", "", "", "", "", "Trade", "tpslOrder", "", time.Time{}, time.Time{}, 0) if err != nil { t.Fatal(err) } @@ -1492,12 +1492,12 @@ func TestGetExecution(t *testing.T) { func TestGetClosedPnL(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetClosedPnL(t.Context(), "spot", "", "", time.Time{}, time.Time{}, 0) + _, err := e.GetClosedPnL(t.Context(), "spot", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetClosedPnL(t.Context(), "linear", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetClosedPnL(t.Context(), "linear", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Fatal(err) } @@ -1508,8 +1508,8 @@ func TestConfirmNewRiskLimit(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - err := b.ConfirmNewRiskLimit(t.Context(), "linear", "BTCUSDT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err := e.ConfirmNewRiskLimit(t.Context(), "linear", "BTCUSDT") if err != nil { t.Error(err) } @@ -1520,14 +1520,14 @@ func TestGetPreUpgradeOrderHistory(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeOrderHistory(t.Context(), "", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeOrderHistory(t.Context(), "", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 100) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetPreUpgradeOrderHistory(t.Context(), "option", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeOrderHistory(t.Context(), "option", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errBaseNotSet) - _, err = b.GetPreUpgradeOrderHistory(t.Context(), "linear", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeOrderHistory(t.Context(), "linear", "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1538,14 +1538,14 @@ func TestGetPreUpgradeTradeHistory(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeTradeHistory(t.Context(), "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeTradeHistory(t.Context(), "", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errCategoryNotSet) - _, err = b.GetPreUpgradeTradeHistory(t.Context(), "option", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeTradeHistory(t.Context(), "option", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPreUpgradeTradeHistory(t.Context(), "linear", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeTradeHistory(t.Context(), "linear", "", "", "", "", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1556,11 +1556,11 @@ func TestGetPreUpgradeClosedPnL(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeClosedPnL(t.Context(), "option", "BTCUSDT", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeClosedPnL(t.Context(), "option", "BTCUSDT", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPreUpgradeClosedPnL(t.Context(), "linear", "BTCUSDT", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeClosedPnL(t.Context(), "linear", "BTCUSDT", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1571,11 +1571,11 @@ func TestGetPreUpgradeTransactionLog(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeTransactionLog(t.Context(), "option", "", "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeTransactionLog(t.Context(), "option", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPreUpgradeTransactionLog(t.Context(), "linear", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetPreUpgradeTransactionLog(t.Context(), "linear", "", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1586,11 +1586,11 @@ func TestGetPreUpgradeOptionDeliveryRecord(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeOptionDeliveryRecord(t.Context(), "linear", "", "", time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeOptionDeliveryRecord(t.Context(), "linear", "", "", time.Time{}, 0) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPreUpgradeOptionDeliveryRecord(t.Context(), "option", "", "", time.Time{}, 0) + _, err = e.GetPreUpgradeOptionDeliveryRecord(t.Context(), "option", "", "", time.Time{}, 0) if err != nil { t.Error(err) } @@ -1601,11 +1601,11 @@ func TestGetPreUpgradeUSDCSessionSettlement(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPreUpgradeUSDCSessionSettlement(t.Context(), "option", "", "", 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPreUpgradeUSDCSessionSettlement(t.Context(), "option", "", "", 10) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetPreUpgradeUSDCSessionSettlement(t.Context(), "linear", "", "", 10) + _, err = e.GetPreUpgradeUSDCSessionSettlement(t.Context(), "linear", "", "", 10) if err != nil { t.Error(err) } @@ -1614,10 +1614,10 @@ func TestGetPreUpgradeUSDCSessionSettlement(t *testing.T) { func TestGetWalletBalance(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - r, err := b.GetWalletBalance(t.Context(), "UNIFIED", "") + r, err := e.GetWalletBalance(t.Context(), "UNIFIED", "") require.NoError(t, err, "GetWalletBalance must not error") require.NotNil(t, r, "GetWalletBalance must return a result") @@ -1705,8 +1705,8 @@ func TestUpgradeToUnifiedAccount(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.UpgradeToUnifiedAccount(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpgradeToUnifiedAccount(t.Context()) if err != nil { t.Error(err) } @@ -1715,9 +1715,9 @@ func TestUpgradeToUnifiedAccount(t *testing.T) { func TestGetBorrowHistory(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetBorrowHistory(t.Context(), "BTC", "", time.Time{}, time.Time{}, 0) + _, err := e.GetBorrowHistory(t.Context(), "BTC", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1728,8 +1728,8 @@ func TestSetCollateralCoin(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetCollateralCoin(t.Context(), currency.BTC, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetCollateralCoin(t.Context(), currency.BTC, false) if err != nil { t.Error(err) } @@ -1738,9 +1738,9 @@ func TestSetCollateralCoin(t *testing.T) { func TestGetCollateralInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetCollateralInfo(t.Context(), "BTC") + _, err := e.GetCollateralInfo(t.Context(), "BTC") if err != nil { t.Error(err) } @@ -1749,9 +1749,9 @@ func TestGetCollateralInfo(t *testing.T) { func TestGetCoinGreeks(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetCoinGreeks(t.Context(), "BTC") + _, err := e.GetCoinGreeks(t.Context(), "BTC") if err != nil { t.Error(err) } @@ -1760,12 +1760,12 @@ func TestGetCoinGreeks(t *testing.T) { func TestGetFeeRate(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetFeeRate(t.Context(), "something", "", "BTC") + _, err := e.GetFeeRate(t.Context(), "something", "", "BTC") require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetFeeRate(t.Context(), "linear", "", "BTC") + _, err = e.GetFeeRate(t.Context(), "linear", "", "BTC") if err != nil { t.Error(err) } @@ -1774,9 +1774,9 @@ func TestGetFeeRate(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetAccountInfo(t.Context()) + _, err := e.GetAccountInfo(t.Context()) if err != nil { t.Error(err) } @@ -1785,13 +1785,13 @@ func TestGetAccountInfo(t *testing.T) { func TestGetTransactionLog(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetTransactionLog(t.Context(), "option", "", "", "", time.Time{}, time.Time{}, 0) + _, err := e.GetTransactionLog(t.Context(), "option", "", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } - _, err = b.GetTransactionLog(t.Context(), "linear", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetTransactionLog(t.Context(), "linear", "", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -1802,8 +1802,8 @@ func TestSetMarginMode(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.SetMarginMode(t.Context(), "PORTFOLIO_MARGIN") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.SetMarginMode(t.Context(), "PORTFOLIO_MARGIN") if err != nil { t.Error(err) } @@ -1811,8 +1811,8 @@ func TestSetMarginMode(t *testing.T) { func TestSetSpotHedging(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetSpotHedging(t.Context(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetSpotHedging(t.Context(), true) if err != nil { t.Error(err) } @@ -1823,11 +1823,11 @@ func TestGetSubAccountALLAPIKeys(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetSubAccountAllAPIKeys(t.Context(), "", "", 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubAccountAllAPIKeys(t.Context(), "", "", 10) assert.ErrorIs(t, err, errMemberIDRequired) - _, err = b.GetSubAccountAllAPIKeys(t.Context(), "1234", "", 10) + _, err = e.GetSubAccountAllAPIKeys(t.Context(), "1234", "", 10) if err != nil { t.Error(err) } @@ -1838,11 +1838,11 @@ func TestSetMMP(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.SetMMP(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.SetMMP(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - err = b.SetMMP(t.Context(), &MMPRequestParam{ + err = e.SetMMP(t.Context(), &MMPRequestParam{ BaseCoin: "ETH", TimeWindowMS: 5000, FrozenPeriod: 100000, @@ -1859,11 +1859,11 @@ func TestResetMMP(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.ResetMMP(t.Context(), "USDT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.ResetMMP(t.Context(), "USDT") require.ErrorIs(t, err, errNilArgument) - err = b.ResetMMP(t.Context(), "BTC") + err = e.ResetMMP(t.Context(), "BTC") if err != nil { t.Error(err) } @@ -1872,9 +1872,9 @@ func TestResetMMP(t *testing.T) { func TestGetMMPState(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetMMPState(t.Context(), "BTC") + _, err := e.GetMMPState(t.Context(), "BTC") if err != nil { t.Error(err) } @@ -1883,9 +1883,9 @@ func TestGetMMPState(t *testing.T) { func TestGetCoinExchangeRecords(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetCoinExchangeRecords(t.Context(), "", "", "", 20) + _, err := e.GetCoinExchangeRecords(t.Context(), "", "", "", 20) if err != nil { t.Fatal(err) } @@ -1895,25 +1895,25 @@ func TestGetDeliveryRecord(t *testing.T) { t.Parallel() expiryTime := time.Now().Add(time.Hour * 40) if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } else { expiryTime = time.UnixMilli(1700216290093) } - _, err := b.GetDeliveryRecord(t.Context(), "spot", "", "", expiryTime, 20) + _, err := e.GetDeliveryRecord(t.Context(), "spot", "", "", expiryTime, 20) assert.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetDeliveryRecord(t.Context(), "linear", "", "", expiryTime, 20) + _, err = e.GetDeliveryRecord(t.Context(), "linear", "", "", expiryTime, 20) assert.NoError(t, err, "GetDeliveryRecord should not error for linear category") } func TestGetUSDCSessionSettlement(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetUSDCSessionSettlement(t.Context(), "option", "", "", 10) + _, err := e.GetUSDCSessionSettlement(t.Context(), "option", "", "", 10) require.ErrorIs(t, err, errInvalidCategory) - _, err = b.GetUSDCSessionSettlement(t.Context(), "linear", "", "", 10) + _, err = e.GetUSDCSessionSettlement(t.Context(), "linear", "", "", 10) if err != nil { t.Error(err) } @@ -1922,24 +1922,24 @@ func TestGetUSDCSessionSettlement(t *testing.T) { func TestGetAssetInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetAssetInfo(t.Context(), "", "BTC") + _, err := e.GetAssetInfo(t.Context(), "", "BTC") require.ErrorIs(t, err, errMissingAccountType) - _, err = b.GetAssetInfo(t.Context(), "SPOT", "BTC") + _, err = e.GetAssetInfo(t.Context(), "SPOT", "BTC") assert.NoError(t, err, "GetAssetInfo should not error for SPOT account type") } func TestGetAllCoinBalance(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetAllCoinBalance(t.Context(), "", "", "", 0) + _, err := e.GetAllCoinBalance(t.Context(), "", "", "", 0) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.GetAllCoinBalance(t.Context(), "FUND", "", "", 0) + _, err = e.GetAllCoinBalance(t.Context(), "FUND", "", "", 0) if err != nil { t.Fatal(err) } @@ -1948,12 +1948,12 @@ func TestGetAllCoinBalance(t *testing.T) { func TestGetSingleCoinBalance(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetSingleCoinBalance(t.Context(), "", "", "", 0, 0) + _, err := e.GetSingleCoinBalance(t.Context(), "", "", "", 0, 0) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.GetSingleCoinBalance(t.Context(), "SPOT", currency.BTC.String(), "", 0, 0) + _, err = e.GetSingleCoinBalance(t.Context(), "SPOT", currency.BTC.String(), "", 0, 0) if err != nil { t.Fatal(err) } @@ -1962,9 +1962,9 @@ func TestGetSingleCoinBalance(t *testing.T) { func TestGetTransferableCoin(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetTransferableCoin(t.Context(), "SPOT", "OPTION") + _, err := e.GetTransferableCoin(t.Context(), "SPOT", "OPTION") if err != nil { t.Fatal(err) } @@ -1975,46 +1975,46 @@ func TestCreateInternalTransfer(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CreateInternalTransfer(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CreateInternalTransfer(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{}) + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{}) require.ErrorIs(t, err, errMissingTransferID) transferID, err := uuid.NewV7() if err != nil { t.Fatal(err) } - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{TransferID: transferID}) + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{TransferID: transferID}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, }) require.ErrorIs(t, err, order.ErrAmountIsInvalid) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, FromAccountType: "UNIFIED", }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateInternalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateInternalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, ToAccountType: "CONTRACT", @@ -2033,11 +2033,11 @@ func TestGetInternalTransferRecords(t *testing.T) { } transferIDString := transferID.String() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } else { transferIDString = "018bd458-dba0-728b-b5b6-ecd5bd296528" } - _, err = b.GetInternalTransferRecords(t.Context(), transferIDString, currency.BTC.String(), "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetInternalTransferRecords(t.Context(), transferIDString, currency.BTC.String(), "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2046,9 +2046,9 @@ func TestGetInternalTransferRecords(t *testing.T) { func TestGetSubUID(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetSubUID(t.Context()) + _, err := e.GetSubUID(t.Context()) if err != nil { t.Error(err) } @@ -2059,8 +2059,8 @@ func TestEnableUniversalTransferForSubUID(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.EnableUniversalTransferForSubUID(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.EnableUniversalTransferForSubUID(t.Context()) require.ErrorIs(t, err, errMembersIDsNotSet) transferID1, err := uuid.NewV7() @@ -2071,7 +2071,7 @@ func TestEnableUniversalTransferForSubUID(t *testing.T) { if err != nil { t.Fatal(err) } - err = b.EnableUniversalTransferForSubUID(t.Context(), transferID1.String(), transferID2.String()) + err = e.EnableUniversalTransferForSubUID(t.Context(), transferID1.String(), transferID2.String()) if err != nil { t.Error(err) } @@ -2079,45 +2079,45 @@ func TestEnableUniversalTransferForSubUID(t *testing.T) { func TestCreateUniversalTransfer(t *testing.T) { t.Parallel() - _, err := b.CreateUniversalTransfer(t.Context(), nil) + _, err := e.CreateUniversalTransfer(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{}) + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{}) require.ErrorIs(t, err, errMissingTransferID) transferID, err := uuid.NewV7() if err != nil { t.Fatal(err) } - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{TransferID: transferID}) + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{TransferID: transferID}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, }) require.ErrorIs(t, err, order.ErrAmountIsInvalid) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, FromAccountType: "UNIFIED", }) require.ErrorIs(t, err, errMissingAccountType) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, ToAccountType: "CONTRACT", @@ -2128,8 +2128,8 @@ func TestCreateUniversalTransfer(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err = b.CreateUniversalTransfer(t.Context(), &TransferParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.CreateUniversalTransfer(t.Context(), &TransferParams{ TransferID: transferID, Coin: currency.BTC, Amount: 123.456, ToAccountType: "CONTRACT", @@ -2146,7 +2146,7 @@ func TestGetUniversalTransferRecords(t *testing.T) { t.Parallel() var transferIDString string if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) transferID, err := uuid.NewV7() if err != nil { t.Fatal(err) @@ -2155,7 +2155,7 @@ func TestGetUniversalTransferRecords(t *testing.T) { } else { transferIDString = "018bd461-cb9c-75ce-94d4-0d3f4d84c339" } - _, err := b.GetUniversalTransferRecords(t.Context(), transferIDString, currency.BTC.String(), "", "", time.Time{}, time.Time{}, 0) + _, err := e.GetUniversalTransferRecords(t.Context(), transferIDString, currency.BTC.String(), "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2164,9 +2164,9 @@ func TestGetUniversalTransferRecords(t *testing.T) { func TestGetAllowedDepositCoinInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetAllowedDepositCoinInfo(t.Context(), "BTC", "", "", 0) + _, err := e.GetAllowedDepositCoinInfo(t.Context(), "BTC", "", "", 0) if err != nil { t.Error(err) } @@ -2177,8 +2177,8 @@ func TestSetDepositAccount(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.SetDepositAccount(t.Context(), "FUND") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.SetDepositAccount(t.Context(), "FUND") if err != nil { t.Error(err) } @@ -2187,9 +2187,9 @@ func TestSetDepositAccount(t *testing.T) { func TestGetDepositRecords(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetDepositRecords(t.Context(), "", "", time.Time{}, time.Time{}, 0) + _, err := e.GetDepositRecords(t.Context(), "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2200,8 +2200,8 @@ func TestGetSubDepositRecords(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetSubDepositRecords(t.Context(), "12345", "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubDepositRecords(t.Context(), "12345", "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2210,9 +2210,9 @@ func TestGetSubDepositRecords(t *testing.T) { func TestInternalDepositRecords(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetInternalDepositRecordsOffChain(t.Context(), currency.ETH.String(), "", time.Time{}, time.Time{}, 8) + _, err := e.GetInternalDepositRecordsOffChain(t.Context(), currency.ETH.String(), "", time.Time{}, time.Time{}, 8) if err != nil { t.Error(err) } @@ -2221,9 +2221,9 @@ func TestInternalDepositRecords(t *testing.T) { func TestGetMasterDepositAddress(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetMasterDepositAddress(t.Context(), currency.LTC, "") + _, err := e.GetMasterDepositAddress(t.Context(), currency.LTC, "") if err != nil { t.Error(err) } @@ -2234,8 +2234,8 @@ func TestGetSubDepositAddress(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetSubDepositAddress(t.Context(), currency.LTC, "LTC", "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubDepositAddress(t.Context(), currency.LTC, "LTC", "12345") if err != nil { t.Error(err) } @@ -2244,9 +2244,9 @@ func TestGetSubDepositAddress(t *testing.T) { func TestGetCoinInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetCoinInfo(t.Context(), currency.BTC) + _, err := e.GetCoinInfo(t.Context(), currency.BTC) if err != nil { t.Error(err) } @@ -2255,9 +2255,9 @@ func TestGetCoinInfo(t *testing.T) { func TestGetWithdrawalRecords(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetWithdrawalRecords(t.Context(), currency.LTC, "", "", "", time.Time{}, time.Time{}, 10) + _, err := e.GetWithdrawalRecords(t.Context(), currency.LTC, "", "", "", time.Time{}, time.Time{}, 10) if err != nil { t.Error(err) } @@ -2266,9 +2266,9 @@ func TestGetWithdrawalRecords(t *testing.T) { func TestGetWithdrawableAmount(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := b.GetWithdrawableAmount(t.Context(), currency.LTC) + _, err := e.GetWithdrawableAmount(t.Context(), currency.LTC) if err != nil { t.Error(err) } @@ -2279,23 +2279,23 @@ func TestWithdrawCurrency(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.WithdrawCurrency(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.WithdrawCurrency(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.WithdrawCurrency(t.Context(), &WithdrawalParam{}) + _, err = e.WithdrawCurrency(t.Context(), &WithdrawalParam{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.BTC}) + _, err = e.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.BTC}) require.ErrorIs(t, err, errMissingChainInformation) - _, err = b.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC"}) + _, err = e.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC"}) require.ErrorIs(t, err, errMissingAddressInfo) - _, err = b.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC", Address: "234234234"}) + _, err = e.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC", Address: "234234234"}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC", Address: "234234234", Amount: 123}) + _, err = e.WithdrawCurrency(t.Context(), &WithdrawalParam{Coin: currency.LTC, Chain: "LTC", Address: "234234234", Amount: 123}) if err != nil { t.Fatal(err) } @@ -2306,11 +2306,11 @@ func TestCancelWithdrawal(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.CancelWithdrawal(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelWithdrawal(t.Context(), "") require.ErrorIs(t, err, errMissingWithdrawalID) - _, err = b.CancelWithdrawal(t.Context(), "12314") + _, err = e.CancelWithdrawal(t.Context(), "12314") if err != nil { t.Error(err) } @@ -2318,20 +2318,20 @@ func TestCancelWithdrawal(t *testing.T) { func TestCreateNewSubUserID(t *testing.T) { t.Parallel() - _, err := b.CreateNewSubUserID(t.Context(), nil) + _, err := e.CreateNewSubUserID(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CreateNewSubUserID(t.Context(), &CreateSubUserParams{MemberType: 1, Switch: 1, Note: "test"}) + _, err = e.CreateNewSubUserID(t.Context(), &CreateSubUserParams{MemberType: 1, Switch: 1, Note: "test"}) require.ErrorIs(t, err, errMissingUsername) - _, err = b.CreateNewSubUserID(t.Context(), &CreateSubUserParams{Username: "Sami", Switch: 1, Note: "test"}) + _, err = e.CreateNewSubUserID(t.Context(), &CreateSubUserParams{Username: "Sami", Switch: 1, Note: "test"}) require.ErrorIs(t, err, errInvalidMemberType) if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err = b.CreateNewSubUserID(t.Context(), &CreateSubUserParams{Username: "sami", MemberType: 1, Switch: 1, Note: "test"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.CreateNewSubUserID(t.Context(), &CreateSubUserParams{Username: "sami", MemberType: 1, Switch: 1, Note: "test"}) if err != nil { t.Error(err) } @@ -2339,17 +2339,17 @@ func TestCreateNewSubUserID(t *testing.T) { func TestCreateSubUIDAPIKey(t *testing.T) { t.Parallel() - _, err := b.CreateSubUIDAPIKey(t.Context(), nil) + _, err := e.CreateSubUIDAPIKey(t.Context(), nil) require.ErrorIs(t, err, errNilArgument) - _, err = b.CreateSubUIDAPIKey(t.Context(), &SubUIDAPIKeyParam{}) + _, err = e.CreateSubUIDAPIKey(t.Context(), &SubUIDAPIKeyParam{}) require.ErrorIs(t, err, errMissingUserID) if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err = b.CreateSubUIDAPIKey(t.Context(), &SubUIDAPIKeyParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.CreateSubUIDAPIKey(t.Context(), &SubUIDAPIKeyParam{ Subuid: 53888000, Note: "testxxx", ReadOnly: 0, @@ -2365,8 +2365,8 @@ func TestGetSubUIDList(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetSubUIDList(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubUIDList(t.Context()) if err != nil { t.Error(err) } @@ -2377,8 +2377,8 @@ func TestFreezeSubUID(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.FreezeSubUID(t.Context(), "1234", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.FreezeSubUID(t.Context(), "1234", true) if err != nil { t.Error(err) } @@ -2389,8 +2389,8 @@ func TestGetAPIKeyInformation(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAPIKeyInformation(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAPIKeyInformation(t.Context()) if err != nil { t.Error(err) } @@ -2401,8 +2401,8 @@ func TestGetUIDWalletType(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetUIDWalletType(t.Context(), "234234") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetUIDWalletType(t.Context(), "234234") if err != nil { t.Error(err) } @@ -2413,11 +2413,11 @@ func TestModifyMasterAPIKey(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifyMasterAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifyMasterAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{}) require.ErrorIs(t, err, errNilArgument) - _, err = b.ModifyMasterAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{ + _, err = e.ModifyMasterAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{ ReadOnly: 0, IPs: "*", Permissions: PermissionsList{ @@ -2439,11 +2439,11 @@ func TestModifySubAPIKey(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ModifySubAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ModifySubAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{}) require.ErrorIs(t, err, errNilArgument) - _, err = b.ModifySubAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{ + _, err = e.ModifySubAPIKey(t.Context(), &SubUIDAPIKeyUpdateParam{ APIKey: "lnqQ8ACaoMLi4168He", ReadOnly: 0, IPs: "*", @@ -2466,11 +2466,11 @@ func TestDeleteSubUID(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - err := b.DeleteSubUID(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err := e.DeleteSubUID(t.Context(), "") assert.ErrorIs(t, err, errMemberIDRequired) - err = b.DeleteSubUID(t.Context(), "1234") + err = e.DeleteSubUID(t.Context(), "1234") if err != nil { t.Error(err) } @@ -2481,8 +2481,8 @@ func TestDeleteMasterAPIKey(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.DeleteMasterAPIKey(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.DeleteMasterAPIKey(t.Context()) if err != nil { t.Error(err) } @@ -2493,8 +2493,8 @@ func TestDeleteSubAPIKey(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - err := b.DeleteSubAccountAPIKey(t.Context(), "12434") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.DeleteSubAccountAPIKey(t.Context(), "12434") if err != nil { t.Error(err) } @@ -2505,8 +2505,8 @@ func TestGetAffiliateUserInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetAffiliateUserInfo(t.Context(), "1234") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAffiliateUserInfo(t.Context(), "1234") if err != nil { t.Error(err) } @@ -2517,8 +2517,8 @@ func TestGetLeverageTokenInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetLeverageTokenInfo(t.Context(), currency.NewCode("BTC3L")) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetLeverageTokenInfo(t.Context(), currency.NewCode("BTC3L")) if err != nil { t.Error(err) } @@ -2529,11 +2529,11 @@ func TestGetLeveragedTokenMarket(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetLeveragedTokenMarket(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetLeveragedTokenMarket(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.GetLeveragedTokenMarket(t.Context(), currency.NewCode("BTC3L")) + _, err = e.GetLeveragedTokenMarket(t.Context(), currency.NewCode("BTC3L")) if err != nil { t.Error(err) } @@ -2544,8 +2544,8 @@ func TestPurchaseLeverageToken(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.PurchaseLeverageToken(t.Context(), currency.BTC3L, 100, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PurchaseLeverageToken(t.Context(), currency.BTC3L, 100, "") if err != nil { t.Error(err) } @@ -2556,8 +2556,8 @@ func TestRedeemLeverageToken(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.RedeemLeverageToken(t.Context(), currency.BTC3L, 100, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.RedeemLeverageToken(t.Context(), currency.BTC3L, 100, "") if err != nil { t.Error(err) } @@ -2568,8 +2568,8 @@ func TestGetPurchaseAndRedemptionRecords(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetPurchaseAndRedemptionRecords(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPurchaseAndRedemptionRecords(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}, 0, 0) if err != nil { t.Error(err) } @@ -2580,8 +2580,8 @@ func TestToggleMarginTrade(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.ToggleMarginTrade(t.Context(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.ToggleMarginTrade(t.Context(), true) if err != nil { t.Error(err) } @@ -2592,8 +2592,8 @@ func TestSetSpotMarginTradeLeverage(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - err := b.SetSpotMarginTradeLeverage(t.Context(), 3) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err := e.SetSpotMarginTradeLeverage(t.Context(), 3) if err != nil { t.Error(err) } @@ -2601,7 +2601,7 @@ func TestSetSpotMarginTradeLeverage(t *testing.T) { func TestGetMarginCoinInfo(t *testing.T) { t.Parallel() - _, err := b.GetMarginCoinInfo(t.Context(), currency.BTC) + _, err := e.GetMarginCoinInfo(t.Context(), currency.BTC) if err != nil { t.Error(err) } @@ -2609,7 +2609,7 @@ func TestGetMarginCoinInfo(t *testing.T) { func TestGetVIPMarginData(t *testing.T) { t.Parallel() - _, err := b.GetVIPMarginData(t.Context(), "", "") + _, err := e.GetVIPMarginData(t.Context(), "", "") if err != nil { t.Error(err) } @@ -2617,7 +2617,7 @@ func TestGetVIPMarginData(t *testing.T) { func TestGetBorrowableCoinInfo(t *testing.T) { t.Parallel() - _, err := b.GetBorrowableCoinInfo(t.Context(), currency.EMPTYCODE) + _, err := e.GetBorrowableCoinInfo(t.Context(), currency.EMPTYCODE) if err != nil { t.Error(err) } @@ -2625,15 +2625,15 @@ func TestGetBorrowableCoinInfo(t *testing.T) { func TestGetInterestAndQuota(t *testing.T) { t.Parallel() - _, err := b.GetInterestAndQuota(t.Context(), currency.EMPTYCODE) + _, err := e.GetInterestAndQuota(t.Context(), currency.EMPTYCODE) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = b.GetInterestAndQuota(t.Context(), currency.BTC) + _, err = e.GetInterestAndQuota(t.Context(), currency.BTC) assert.NoError(t, err) } @@ -2642,8 +2642,8 @@ func TestGetLoanAccountInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetLoanAccountInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetLoanAccountInfo(t.Context()) assert.NoError(t, err) } @@ -2652,17 +2652,17 @@ func TestBorrow(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.Borrow(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.Borrow(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.Borrow(t.Context(), &LendArgument{}) + _, err = e.Borrow(t.Context(), &LendArgument{}) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.Borrow(t.Context(), &LendArgument{Coin: currency.BTC}) + _, err = e.Borrow(t.Context(), &LendArgument{Coin: currency.BTC}) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.Borrow(t.Context(), &LendArgument{Coin: currency.BTC, AmountToBorrow: 0.1}) + _, err = e.Borrow(t.Context(), &LendArgument{Coin: currency.BTC, AmountToBorrow: 0.1}) if err != nil { t.Error(err) } @@ -2673,17 +2673,17 @@ func TestRepay(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.Repay(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.Repay(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.Repay(t.Context(), &LendArgument{}) + _, err = e.Repay(t.Context(), &LendArgument{}) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.Repay(t.Context(), &LendArgument{Coin: currency.BTC}) + _, err = e.Repay(t.Context(), &LendArgument{Coin: currency.BTC}) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.Repay(t.Context(), &LendArgument{Coin: currency.BTC, AmountToBorrow: 0.1}) + _, err = e.Repay(t.Context(), &LendArgument{Coin: currency.BTC, AmountToBorrow: 0.1}) if err != nil { t.Error(err) } @@ -2694,8 +2694,8 @@ func TestGetBorrowOrderDetail(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetBorrowOrderDetail(t.Context(), time.Time{}, time.Time{}, currency.BTC, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetBorrowOrderDetail(t.Context(), time.Time{}, time.Time{}, currency.BTC, 0, 0) assert.NoError(t, err) } @@ -2704,8 +2704,8 @@ func TestGetRepaymentOrderDetail(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetRepaymentOrderDetail(t.Context(), time.Time{}, time.Time{}, currency.BTC, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetRepaymentOrderDetail(t.Context(), time.Time{}, time.Time{}, currency.BTC, 0) assert.NoError(t, err) } @@ -2714,14 +2714,14 @@ func TestToggleMarginTradeNormal(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.ToggleMarginTradeNormal(t.Context(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.ToggleMarginTradeNormal(t.Context(), true) assert.NoError(t, err) } func TestGetProductInfo(t *testing.T) { t.Parallel() - _, err := b.GetProductInfo(t.Context(), "") + _, err := e.GetProductInfo(t.Context(), "") if err != nil { t.Error(err) } @@ -2729,7 +2729,7 @@ func TestGetProductInfo(t *testing.T) { func TestGetInstitutionalLengingMarginCoinInfo(t *testing.T) { t.Parallel() - _, err := b.GetInstitutionalLengingMarginCoinInfo(t.Context(), "") + _, err := e.GetInstitutionalLengingMarginCoinInfo(t.Context(), "") if err != nil { t.Error(err) } @@ -2740,8 +2740,8 @@ func TestGetInstitutionalLoanOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetInstitutionalLoanOrders(t.Context(), "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetInstitutionalLoanOrders(t.Context(), "", time.Time{}, time.Time{}, 0) assert.NoError(t, err) } @@ -2750,8 +2750,8 @@ func TestGetInstitutionalRepayOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetInstitutionalRepayOrders(t.Context(), time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetInstitutionalRepayOrders(t.Context(), time.Time{}, time.Time{}, 0) assert.NoError(t, err) } @@ -2760,8 +2760,8 @@ func TestGetLTV(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetLTV(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetLTV(t.Context()) assert.NoError(t, err) } @@ -2770,8 +2770,8 @@ func TestBindOrUnbindUID(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.BindOrUnbindUID(t.Context(), "12234", "0") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.BindOrUnbindUID(t.Context(), "12234", "0") if err != nil { t.Error(err) } @@ -2782,8 +2782,8 @@ func TestGetC2CLendingCoinInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetC2CLendingCoinInfo(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetC2CLendingCoinInfo(t.Context(), currency.BTC) if err != nil { t.Error(err) } @@ -2794,17 +2794,17 @@ func TestC2CDepositFunds(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.C2CDepositFunds(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.C2CDepositFunds(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{}) + _, err = e.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{}) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC}) + _, err = e.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC}) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC, Quantity: 1232}) + _, err = e.C2CDepositFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC, Quantity: 1232}) if err != nil { t.Error(err) } @@ -2815,17 +2815,17 @@ func TestC2CRedeemFunds(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) - _, err := b.C2CRedeemFunds(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.C2CRedeemFunds(t.Context(), nil) assert.ErrorIs(t, err, errNilArgument) - _, err = b.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{}) + _, err = e.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{}) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = b.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC}) + _, err = e.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC}) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = b.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC, Quantity: 1232}) + _, err = e.C2CRedeemFunds(t.Context(), &C2CLendingFundsParams{Coin: currency.BTC, Quantity: 1232}) if err != nil { t.Error(err) } @@ -2836,8 +2836,8 @@ func TestGetC2CLendingOrderRecords(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetC2CLendingOrderRecords(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetC2CLendingOrderRecords(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2848,8 +2848,8 @@ func TestGetC2CLendingAccountInfo(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetC2CLendingAccountInfo(t.Context(), currency.LTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetC2CLendingAccountInfo(t.Context(), currency.LTC) if err != nil { t.Error(err) } @@ -2860,8 +2860,8 @@ func TestGetBrokerEarning(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetBrokerEarning(t.Context(), "DERIVATIVES", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetBrokerEarning(t.Context(), "DERIVATIVES", "", time.Time{}, time.Time{}, 0) if err != nil { t.Error(err) } @@ -2870,10 +2870,10 @@ func TestGetBrokerEarning(t *testing.T) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - r, err := b.UpdateAccountInfo(t.Context(), asset.Spot) + r, err := e.UpdateAccountInfo(t.Context(), asset.Spot) require.NoError(t, err, "UpdateAccountInfo must not error") require.NotEmpty(t, r, "UpdateAccountInfo must return account info") @@ -2911,11 +2911,11 @@ func TestGetWithdrawalsHistory(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) - _, err := b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Futures) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + _, err = e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) if err != nil { t.Error("GetWithdrawalsHistory()", err) } @@ -2933,17 +2933,17 @@ func TestGetRecentTrades(t *testing.T) { {asset.USDTMarginedFutures, usdtMarginedTradablePair}, {asset.USDCMarginedFutures, usdcMarginedTradablePair}, } { - _, err := b.GetRecentTrades(t.Context(), tt.p, tt.a) + _, err := e.GetRecentTrades(t.Context(), tt.p, tt.a) assert.NoErrorf(t, err, "GetRecentTrades should not error for %s asset", tt.a) } - _, err := b.GetRecentTrades(t.Context(), spotTradablePair, asset.Futures) + _, err := e.GetRecentTrades(t.Context(), spotTradablePair, asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestGetBybitServerTime(t *testing.T) { t.Parallel() - _, err := b.GetBybitServerTime(t.Context()) + _, err := e.GetBybitServerTime(t.Context()) if err != nil { t.Error(err) } @@ -2951,7 +2951,7 @@ func TestGetBybitServerTime(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() - _, err := b.GetServerTime(t.Context(), asset.Empty) + _, err := e.GetServerTime(t.Context(), asset.Empty) if err != nil { t.Error(err) } @@ -2959,23 +2959,23 @@ func TestGetServerTime(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricTrades(t.Context(), spotTradablePair, asset.Spot, time.Time{}, time.Time{}) + _, err := e.GetHistoricTrades(t.Context(), spotTradablePair, asset.Spot, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetHistoricTrades(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, time.Time{}, time.Time{}) + _, err = e.GetHistoricTrades(t.Context(), usdtMarginedTradablePair, asset.USDTMarginedFutures, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetHistoricTrades(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures, time.Time{}, time.Time{}) + _, err = e.GetHistoricTrades(t.Context(), usdcMarginedTradablePair, asset.USDCMarginedFutures, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetHistoricTrades(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, time.Time{}, time.Time{}) + _, err = e.GetHistoricTrades(t.Context(), inverseTradablePair, asset.CoinMarginedFutures, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetHistoricTrades(t.Context(), optionsTradablePair, asset.Options, time.Time{}, time.Time{}) + _, err = e.GetHistoricTrades(t.Context(), optionsTradablePair, asset.Options, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -2986,7 +2986,7 @@ func TestCancelBatchOrders(t *testing.T) { if mockTests { t.Skip(skipAuthenticatedFunctionsForMockTesting) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellationParams := []order.Cancel{{ OrderID: "1", Pair: spotTradablePair, @@ -2996,7 +2996,7 @@ func TestCancelBatchOrders(t *testing.T) { Pair: usdtMarginedTradablePair, AssetType: asset.USDTMarginedFutures, }} - _, err := b.CancelBatchOrders(t.Context(), orderCancellationParams) + _, err := e.CancelBatchOrders(t.Context(), orderCancellationParams) assert.ErrorIs(t, err, asset.ErrNotSupported) orderCancellationParams = []order.Cancel{{ @@ -3009,7 +3009,7 @@ func TestCancelBatchOrders(t *testing.T) { Pair: optionsTradablePair, AssetType: asset.Options, }} - _, err = b.CancelBatchOrders(t.Context(), orderCancellationParams) + _, err = e.CancelBatchOrders(t.Context(), orderCancellationParams) if err != nil { t.Error(err) } @@ -3020,7 +3020,7 @@ func TestWsConnect(t *testing.T) { if mockTests { t.Skip(skippingWebsocketFunctionsForMockTesting) } - err := b.WsConnect() + err := e.WsConnect() if err != nil { t.Error(err) } @@ -3031,7 +3031,7 @@ func TestWsLinearConnect(t *testing.T) { if mockTests { t.Skip(skippingWebsocketFunctionsForMockTesting) } - err := b.WsLinearConnect() + err := e.WsLinearConnect() assert.Truef(t, errors.Is(err, websocket.ErrWebsocketNotEnabled) || err == nil, "WsLinerConnect should not error: %s", err) } @@ -3040,7 +3040,7 @@ func TestWsInverseConnect(t *testing.T) { if mockTests { t.Skip(skippingWebsocketFunctionsForMockTesting) } - err := b.WsInverseConnect() + err := e.WsInverseConnect() assert.Truef(t, errors.Is(err, websocket.ErrWebsocketNotEnabled) || err == nil, "WsInverseConnect should not error: %s", err) } @@ -3049,7 +3049,7 @@ func TestWsOptionsConnect(t *testing.T) { if mockTests { t.Skip(skippingWebsocketFunctionsForMockTesting) } - err := b.WsOptionsConnect() + err := e.WsOptionsConnect() assert.Truef(t, errors.Is(err, websocket.ErrWebsocketNotEnabled) || err == nil, "WsOptionsConnect should not error: %s", err) } @@ -3076,31 +3076,31 @@ func TestPushData(t *testing.T) { slices.Sort(keys) for x := range keys { - err := b.wsHandleData(t.Context(), asset.Spot, []byte(pushDataMap[keys[x]])) + err := e.wsHandleData(t.Context(), asset.Spot, []byte(pushDataMap[keys[x]])) assert.NoError(t, err, "wsHandleData should not error") } } func TestWsTicker(t *testing.T) { t.Parallel() - b := new(Bybit) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + e := new(Exchange) //nolint:govet // Intentional shadow assetRouting := []asset.Item{ asset.Spot, asset.Options, asset.USDTMarginedFutures, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures, asset.CoinMarginedFutures, } - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") testexch.FixtureToDataHandler(t, "testdata/wsTicker.json", func(_ context.Context, r []byte) error { defer slices.Delete(assetRouting, 0, 1) - return b.wsHandleData(t.Context(), assetRouting[0], r) + return e.wsHandleData(t.Context(), assetRouting[0], r) }) - close(b.Websocket.DataHandler) + close(e.Websocket.DataHandler) expected := 8 - require.Len(t, b.Websocket.DataHandler, expected, "Should see correct number of tickers") - for resp := range b.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, expected, "Should see correct number of tickers") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case *ticker.Price: - assert.Equal(t, b.Name, v.ExchangeName, "ExchangeName should be correct") - switch expected - len(b.Websocket.DataHandler) { + assert.Equal(t, e.Name, v.ExchangeName, "ExchangeName should be correct") + switch expected - len(e.Websocket.DataHandler) { case 1: // Spot assert.Equal(t, currency.BTC, v.Pair.Base, "Pair base should be correct") assert.Equal(t, currency.USDT, v.Pair.Quote, "Pair quote should be correct") @@ -3242,22 +3242,22 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { FiatCurrency: currency.USD, BankTransactionType: exchange.WireTransfer, } - _, err := b.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } feeBuilder.Pair = optionsTradablePair - _, err = b.GetFeeByType(t.Context(), feeBuilder) + _, err = e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } feeBuilder.Pair = usdtMarginedTradablePair - _, err = b.GetFeeByType(t.Context(), feeBuilder) + _, err = e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } feeBuilder.Pair = inverseTradablePair - _, err = b.GetFeeByType(t.Context(), feeBuilder) + _, err = e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } @@ -3265,82 +3265,82 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { func TestSetLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) ctx := t.Context() - err := b.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Multi, 5, order.Buy) + err := e.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Multi, 5, order.Buy) if err != nil { t.Error(err) } - err = b.SetLeverage(ctx, asset.USDCMarginedFutures, usdcMarginedTradablePair, margin.Multi, 5, order.Buy) + err = e.SetLeverage(ctx, asset.USDCMarginedFutures, usdcMarginedTradablePair, margin.Multi, 5, order.Buy) if err != nil { t.Error(err) } - err = b.SetLeverage(ctx, asset.CoinMarginedFutures, inverseTradablePair, margin.Isolated, 5, order.UnknownSide) + err = e.SetLeverage(ctx, asset.CoinMarginedFutures, inverseTradablePair, margin.Isolated, 5, order.UnknownSide) assert.ErrorIs(t, err, order.ErrSideIsInvalid) - err = b.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Isolated, 5, order.Buy) + err = e.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Isolated, 5, order.Buy) if err != nil { t.Error(err) } - err = b.SetLeverage(ctx, asset.CoinMarginedFutures, inverseTradablePair, margin.Isolated, 5, order.Sell) + err = e.SetLeverage(ctx, asset.CoinMarginedFutures, inverseTradablePair, margin.Isolated, 5, order.Sell) if err != nil { t.Error(err) } - err = b.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Isolated, 5, order.CouldNotBuy) + err = e.SetLeverage(ctx, asset.USDTMarginedFutures, usdtMarginedTradablePair, margin.Isolated, 5, order.CouldNotBuy) assert.ErrorIs(t, err, order.ErrSideIsInvalid) - err = b.SetLeverage(ctx, asset.Spot, inverseTradablePair, margin.Multi, 5, order.UnknownSide) + err = e.SetLeverage(ctx, asset.Spot, inverseTradablePair, margin.Multi, 5, order.UnknownSide) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := b.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = b.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) assert.NoError(t, err) - _, err = b.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) assert.NoError(t, err) - _, err = b.GetFuturesContractDetails(t.Context(), asset.USDCMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDCMarginedFutures) assert.NoError(t, err) } func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := b.FetchTradablePairs(t.Context(), asset.Spot) + _, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Fatal(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) + _, err = e.FetchTradablePairs(t.Context(), asset.CoinMarginedFutures) if err != nil { t.Fatal(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) + _, err = e.FetchTradablePairs(t.Context(), asset.USDTMarginedFutures) if err != nil { t.Fatal(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.USDCMarginedFutures) + _, err = e.FetchTradablePairs(t.Context(), asset.USDCMarginedFutures) if err != nil { t.Fatal(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.Options) + _, err = e.FetchTradablePairs(t.Context(), asset.Options) if err != nil { t.Fatal(err) } - _, err = b.FetchTradablePairs(t.Context(), asset.Futures) + _, err = e.FetchTradablePairs(t.Context(), asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) } func TestDeltaUpdateOrderbook(t *testing.T) { t.Parallel() data := []byte(`{"topic":"orderbook.50.WEMIXUSDT","ts":1697573183768,"type":"snapshot","data":{"s":"WEMIXUSDT","b":[["0.9511","260.703"],["0.9677","0"]],"a":[],"u":3119516,"seq":14126848493},"cts":1728966699481}`) - err := b.wsHandleData(t.Context(), asset.Spot, data) + err := e.wsHandleData(t.Context(), asset.Spot, data) if err != nil { t.Fatal(err) } @@ -3350,7 +3350,7 @@ func TestDeltaUpdateOrderbook(t *testing.T) { if err != nil { t.Fatal(err) } - err = b.wsProcessOrderbook(asset.Spot, &wsResponse) + err = e.wsProcessOrderbook(asset.Spot, &wsResponse) if err != nil { t.Fatal(err) } @@ -3358,15 +3358,15 @@ func TestDeltaUpdateOrderbook(t *testing.T) { func TestGetLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.GetLongShortRatio(t.Context(), "linear", "BTCUSDT", kline.FiveMin, 0) + _, err := e.GetLongShortRatio(t.Context(), "linear", "BTCUSDT", kline.FiveMin, 0) if err != nil { t.Fatal(err) } - _, err = b.GetLongShortRatio(t.Context(), "inverse", "BTCUSDT", kline.FiveMin, 0) + _, err = e.GetLongShortRatio(t.Context(), "inverse", "BTCUSDT", kline.FiveMin, 0) if err != nil { t.Fatal(err) } - _, err = b.GetLongShortRatio(t.Context(), "spot", "BTCUSDT", kline.FiveMin, 0) + _, err = e.GetLongShortRatio(t.Context(), "spot", "BTCUSDT", kline.FiveMin, 0) require.ErrorIs(t, err, errInvalidCategory) } @@ -3417,9 +3417,9 @@ func TestStringToOrderStatus(t *testing.T) { func TestFetchAccountType(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - val, err := b.FetchAccountType(t.Context()) + val, err := e.FetchAccountType(t.Context()) require.NoError(t, err) require.NotZero(t, val) } @@ -3435,11 +3435,11 @@ func TestAccountTypeString(t *testing.T) { func TestRequiresUnifiedAccount(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, b) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - err := b.RequiresUnifiedAccount(t.Context()) + err := e.RequiresUnifiedAccount(t.Context()) require.NoError(t, err) - b := &Bybit{} //nolint:govet // Intentional shadow to avoid future copy/paste mistakes. Also stops race below. + b := &Exchange{} b.account.accountType = accountTypeNormal err = b.RequiresUnifiedAccount(t.Context()) require.ErrorIs(t, err, errAPIKeyIsNotUnified) @@ -3447,31 +3447,31 @@ func TestRequiresUnifiedAccount(t *testing.T) { func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: usdtMarginedTradablePair, }) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Spot, Pair: spotTradablePair, }) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Options, Pair: optionsTradablePair, }) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, }) if err != nil { t.Error(err) } - _, err = b.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDCMarginedFutures, Pair: usdcMarginedTradablePair, }) @@ -3488,13 +3488,13 @@ func TestConstructOrderDetails(t *testing.T) { if err != nil { t.Fatal(err) } - orders, err := b.ConstructOrderDetails(response, asset.Spot, currency.Pair{Base: currency.BTC, Quote: currency.USDT}, currency.Pairs{}) + orders, err := e.ConstructOrderDetails(response, asset.Spot, currency.Pair{Base: currency.BTC, Quote: currency.USDT}, currency.Pairs{}) if err != nil { t.Fatal(err) } else if len(orders) > 0 { t.Errorf("expected order with length 0, got %d", len(orders)) } - orders, err = b.ConstructOrderDetails(response, asset.Spot, currency.EMPTYPAIR, currency.Pairs{}) + orders, err = e.ConstructOrderDetails(response, asset.Spot, currency.EMPTYPAIR, currency.Pairs{}) if err != nil { t.Fatal(err) } else if len(orders) != 1 { @@ -3504,14 +3504,14 @@ func TestConstructOrderDetails(t *testing.T) { func TestGetOpenInterest(t *testing.T) { t.Parallel() - _, err := b.GetOpenInterest(t.Context(), key.PairAsset{ + _, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.ETH.Item, Quote: currency.USDT.Item, Asset: asset.Spot, }) assert.ErrorIs(t, err, asset.ErrNotSupported) - resp, err := b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: usdcMarginedTradablePair.Base.Item, Quote: usdcMarginedTradablePair.Quote.Item, Asset: asset.USDCMarginedFutures, @@ -3519,7 +3519,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: usdtMarginedTradablePair.Base.Item, Quote: usdtMarginedTradablePair.Quote.Item, Asset: asset.USDTMarginedFutures, @@ -3527,7 +3527,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: inverseTradablePair.Base.Item, Quote: inverseTradablePair.Quote.Item, Asset: asset.CoinMarginedFutures, @@ -3535,7 +3535,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = b.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) } @@ -3543,31 +3543,31 @@ func TestGetOpenInterest(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := b.IsPerpetualFutureCurrency(asset.Spot, spotTradablePair) + is, err := e.IsPerpetualFutureCurrency(asset.Spot, spotTradablePair) assert.NoError(t, err) assert.False(t, is) - is, err = b.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, inverseTradablePair) + is, err = e.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, inverseTradablePair) assert.NoError(t, err) assert.Truef(t, is, "%s %s should be a perp", asset.CoinMarginedFutures, inverseTradablePair) - is, err = b.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, usdtMarginedTradablePair) + is, err = e.IsPerpetualFutureCurrency(asset.USDTMarginedFutures, usdtMarginedTradablePair) assert.NoError(t, err) assert.Truef(t, is, "%s %s should be a perp", asset.USDTMarginedFutures, usdtMarginedTradablePair) - is, err = b.IsPerpetualFutureCurrency(asset.USDCMarginedFutures, usdcMarginedTradablePair) + is, err = e.IsPerpetualFutureCurrency(asset.USDCMarginedFutures, usdcMarginedTradablePair) assert.NoError(t, err) assert.Truef(t, is, "%s %s should be a perp", asset.USDCMarginedFutures, usdcMarginedTradablePair) } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, b) - for _, a := range b.GetAssetTypes(false) { - pairs, err := b.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -3577,19 +3577,19 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - b := new(Bybit) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := b.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - for _, s := range b.Features.Subscriptions { - for _, a := range b.GetAssetTypes(true) { + for _, s := range e.Features.Subscriptions { + for _, a := range e.GetAssetTypes(true) { if s.Asset != asset.All && s.Asset != a { continue } - pairs, err := b.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) pairs = common.SortStrings(pairs).Format(currency.PairFormat{Uppercase: true, Delimiter: ""}) s := s.Clone() //nolint:govet // Intentional lexical scope shadow @@ -3625,24 +3625,24 @@ func TestGenerateSubscriptions(t *testing.T) { func TestSubscribe(t *testing.T) { t.Parallel() - b := new(Bybit) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - subs, err := b.Features.Subscriptions.ExpandTemplates(b) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + subs, err := e.Features.Subscriptions.ExpandTemplates(e) require.NoError(t, err, "ExpandTemplates must not error") - b.Features.Subscriptions = subscription.List{} - testexch.SetupWs(t, b) - err = b.Subscribe(subs) + e.Features.Subscriptions = subscription.List{} + testexch.SetupWs(t, e) + err = e.Subscribe(subs) require.NoError(t, err, "Subscribe must not error") } func TestAuthSubscribe(t *testing.T) { t.Parallel() - b := new(Bybit) - require.NoError(t, testexch.Setup(b), "Test instance Setup must not error") - b.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := b.Features.Subscriptions.ExpandTemplates(b) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.Features.Subscriptions.ExpandTemplates(e) require.NoError(t, err, "ExpandTemplates must not error") - b.Features.Subscriptions = subscription.List{} + e.Features.Subscriptions = subscription.List{} success := true mock := func(tb testing.TB, msg []byte, w *gws.Conn) error { tb.Helper() @@ -3658,12 +3658,12 @@ func TestAuthSubscribe(t *testing.T) { require.NoError(tb, err, "Marshal must not error") return w.WriteMessage(gws.TextMessage, msg) } - b = testexch.MockWsInstance[Bybit](t, testws.CurryWsMockUpgrader(t, mock)) - b.Websocket.AuthConn = b.Websocket.Conn - err = b.Subscribe(subs) + e = testexch.MockWsInstance[Exchange](t, testws.CurryWsMockUpgrader(t, mock)) + e.Websocket.AuthConn = e.Websocket.Conn + err = e.Subscribe(subs) require.NoError(t, err, "Subscribe must not error") success = false - err = b.Subscribe(subs) + err = e.Subscribe(subs) assert.ErrorContains(t, err, "Mock Resp Error", "Subscribe should error containing the returned RetMsg") } diff --git a/exchanges/bybit/bybit_websocket.go b/exchanges/bybit/bybit_websocket.go index 98a4cfac337..6a3f8cee325 100644 --- a/exchanges/bybit/bybit_websocket.go +++ b/exchanges/bybit/bybit_websocket.go @@ -79,54 +79,54 @@ var subscriptionNames = map[string]string{ } // WsConnect connects to a websocket feed -func (by *Bybit) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.Spot) { + if !e.Websocket.IsEnabled() || !e.IsEnabled() || !e.IsAssetWebsocketSupported(asset.Spot) { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := by.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - by.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: []byte(`{"op": "ping"}`), Delay: bybitWebsocketTimer, }) - by.Websocket.Wg.Add(1) - go by.wsReadData(ctx, asset.Spot, by.Websocket.Conn) - if by.Websocket.CanUseAuthenticatedEndpoints() { - err = by.WsAuth(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, asset.Spot, e.Websocket.Conn) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.WsAuth(ctx) if err != nil { - by.Websocket.DataHandler <- err - by.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.DataHandler <- err + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } return nil } // WsAuth sends an authentication message to receive auth data -func (by *Bybit) WsAuth(ctx context.Context) error { - creds, err := by.GetCredentials(ctx) +func (e *Exchange) WsAuth(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } var dialer gws.Dialer - if err := by.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil { + if err := e.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil { return err } - by.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: []byte(`{"op":"ping"}`), Delay: bybitWebsocketTimer, }) - by.Websocket.Wg.Add(1) - go by.wsReadData(ctx, asset.Spot, by.Websocket.AuthConn) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, asset.Spot, e.Websocket.AuthConn) intNonce := time.Now().Add(time.Hour * 6).UnixMilli() strNonce := strconv.FormatInt(intNonce, 10) @@ -140,11 +140,11 @@ func (by *Bybit) WsAuth(ctx context.Context) error { } sign := hex.EncodeToString(hmac) req := Authenticate{ - RequestID: strconv.FormatInt(by.Websocket.AuthConn.GenerateMessageID(false), 10), + RequestID: strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10), Operation: "auth", Args: []any{creds.Key, intNonce, sign}, } - resp, err := by.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req) if err != nil { return err } @@ -160,13 +160,13 @@ func (by *Bybit) WsAuth(ctx context.Context) error { } // Subscribe sends a websocket message to receive data from the channel -func (by *Bybit) Subscribe(channelsToSubscribe subscription.List) error { +func (e *Exchange) Subscribe(channelsToSubscribe subscription.List) error { ctx := context.TODO() - return by.handleSpotSubscription(ctx, "subscribe", channelsToSubscribe) + return e.handleSpotSubscription(ctx, "subscribe", channelsToSubscribe) } -func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) (args []SubscriptionArgument, err error) { - subs, err = subs.ExpandTemplates(by) +func (e *Exchange) handleSubscriptions(operation string, subs subscription.List) (args []SubscriptionArgument, err error) { + subs, err = subs.ExpandTemplates(e) if err != nil { return } @@ -176,7 +176,7 @@ func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) ( args = append(args, SubscriptionArgument{ auth: b[0].Authenticated, Operation: operation, - RequestID: strconv.FormatInt(by.Websocket.Conn.GenerateMessageID(false), 10), + RequestID: strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10), Arguments: b.QualifiedChannels(), associatedSubs: b, }) @@ -187,25 +187,25 @@ func (by *Bybit) handleSubscriptions(operation string, subs subscription.List) ( } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (by *Bybit) Unsubscribe(channelsToUnsubscribe subscription.List) error { +func (e *Exchange) Unsubscribe(channelsToUnsubscribe subscription.List) error { ctx := context.TODO() - return by.handleSpotSubscription(ctx, "unsubscribe", channelsToUnsubscribe) + return e.handleSpotSubscription(ctx, "unsubscribe", channelsToUnsubscribe) } -func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, channelsToSubscribe subscription.List) error { - payloads, err := by.handleSubscriptions(operation, channelsToSubscribe) +func (e *Exchange) handleSpotSubscription(ctx context.Context, operation string, channelsToSubscribe subscription.List) error { + payloads, err := e.handleSubscriptions(operation, channelsToSubscribe) if err != nil { return err } for a := range payloads { var response []byte if payloads[a].auth { - response, err = by.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a]) + response, err = e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a]) if err != nil { return err } } else { - response, err = by.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a]) + response, err = e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, payloads[a].RequestID, payloads[a]) if err != nil { return err } @@ -221,15 +221,15 @@ func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, c var conn websocket.Connection if payloads[a].auth { - conn = by.Websocket.AuthConn + conn = e.Websocket.AuthConn } else { - conn = by.Websocket.Conn + conn = e.Websocket.Conn } if operation == "unsubscribe" { - err = by.Websocket.RemoveSubscriptions(conn, payloads[a].associatedSubs...) + err = e.Websocket.RemoveSubscriptions(conn, payloads[a].associatedSubs...) } else { - err = by.Websocket.AddSubscriptions(conn, payloads[a].associatedSubs...) + err = e.Websocket.AddSubscriptions(conn, payloads[a].associatedSubs...) } if err != nil { return err @@ -239,12 +239,12 @@ func (by *Bybit) handleSpotSubscription(ctx context.Context, operation string, c } // generateSubscriptions generates default subscription -func (by *Bybit) generateSubscriptions() (subscription.List, error) { - return by.Features.Subscriptions.ExpandTemplates(by) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (by *Bybit) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "isSymbolChannel": isSymbolChannel, @@ -255,26 +255,26 @@ func (by *Bybit) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat } // wsReadData receives and passes on websocket messages for processing -func (by *Bybit) wsReadData(ctx context.Context, assetType asset.Item, ws websocket.Connection) { - defer by.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context, assetType asset.Item, ws websocket.Connection) { + defer e.Websocket.Wg.Done() for { select { - case <-by.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: return default: resp := ws.ReadMessage() if resp.Raw == nil { return } - err := by.wsHandleData(ctx, assetType, resp.Raw) + err := e.wsHandleData(ctx, assetType, resp.Raw) if err != nil { - by.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, assetType asset.Item, respRaw []byte) error { var result WebsocketResponse err := json.Unmarshal(respRaw, &result) if err != nil { @@ -284,13 +284,13 @@ func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw switch result.Operation { case "subscribe", "unsubscribe", "auth": if result.RequestID != "" { - if !by.Websocket.Match.IncomingWithData(result.RequestID, respRaw) { + if !e.Websocket.Match.IncomingWithData(result.RequestID, respRaw) { return fmt.Errorf("could not match subscription with id %s data %s", result.RequestID, respRaw) } } case "ping", "pong": default: - by.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ Message: string(respRaw), } return nil @@ -303,54 +303,54 @@ func (by *Bybit) wsHandleData(ctx context.Context, assetType asset.Item, respRaw } switch topicSplit[0] { case chanOrderbook: - return by.wsProcessOrderbook(assetType, &result) + return e.wsProcessOrderbook(assetType, &result) case chanPublicTrade: - return by.wsProcessPublicTrade(assetType, &result) + return e.wsProcessPublicTrade(assetType, &result) case chanPublicTicker: - return by.wsProcessPublicTicker(assetType, &result) + return e.wsProcessPublicTicker(assetType, &result) case chanKline: - return by.wsProcessKline(assetType, &result, topicSplit) + return e.wsProcessKline(assetType, &result, topicSplit) case chanLiquidation: - return by.wsProcessLiquidation(&result) + return e.wsProcessLiquidation(&result) case chanLeverageTokenKline: - return by.wsProcessLeverageTokenKline(assetType, &result, topicSplit) + return e.wsProcessLeverageTokenKline(assetType, &result, topicSplit) case chanLeverageTokenTicker: - return by.wsProcessLeverageTokenTicker(assetType, &result) + return e.wsProcessLeverageTokenTicker(assetType, &result) case chanLeverageTokenNav: - return by.wsLeverageTokenNav(&result) + return e.wsLeverageTokenNav(&result) case chanPositions: - return by.wsProcessPosition(&result) + return e.wsProcessPosition(&result) case chanExecution: - return by.wsProcessExecution(asset.Spot, &result) + return e.wsProcessExecution(asset.Spot, &result) case chanOrder: - return by.wsProcessOrder(asset.Spot, &result) + return e.wsProcessOrder(asset.Spot, &result) case chanWallet: - return by.wsProcessWalletPushData(ctx, asset.Spot, respRaw) + return e.wsProcessWalletPushData(ctx, asset.Spot, respRaw) case chanGreeks: - return by.wsProcessGreeks(respRaw) + return e.wsProcessGreeks(respRaw) case chanDCP: return nil } return fmt.Errorf("unhandled stream data %s", string(respRaw)) } -func (by *Bybit) wsProcessGreeks(resp []byte) error { +func (e *Exchange) wsProcessGreeks(resp []byte) error { var result GreeksResponse err := json.Unmarshal(resp, &result) if err != nil { return err } - by.Websocket.DataHandler <- &result + e.Websocket.DataHandler <- &result return nil } -func (by *Bybit) wsProcessWalletPushData(ctx context.Context, assetType asset.Item, resp []byte) error { +func (e *Exchange) wsProcessWalletPushData(ctx context.Context, assetType asset.Item, resp []byte) error { var result WebsocketWallet err := json.Unmarshal(resp, &result) if err != nil { return err } - creds, err := by.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -368,12 +368,12 @@ func (by *Bybit) wsProcessWalletPushData(ctx context.Context, assetType asset.It }) } } - by.Websocket.DataHandler <- changes - return account.ProcessChange(by.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } // wsProcessOrder the order stream to see changes to your orders in real-time. -func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) error { var result WsOrders err := json.Unmarshal(resp.Data, &result) if err != nil { @@ -381,7 +381,7 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e } execution := make([]order.Detail, len(result)) for x := range result { - cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -395,7 +395,7 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e } execution[x] = order.Detail{ Amount: result[x].Qty.Float64(), - Exchange: by.Name, + Exchange: e.Name, OrderID: result[x].OrderID, ClientOrderID: result[x].OrderLinkID, Side: side, @@ -410,11 +410,11 @@ func (by *Bybit) wsProcessOrder(assetType asset.Item, resp *WebsocketResponse) e LastUpdated: result[x].UpdatedTime.Time(), } } - by.Websocket.DataHandler <- execution + e.Websocket.DataHandler <- execution return nil } -func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessExecution(assetType asset.Item, resp *WebsocketResponse) error { var result WsExecutions err := json.Unmarshal(resp.Data, &result) if err != nil { @@ -422,7 +422,7 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons } executions := make([]fill.Data, len(result)) for x := range result { - cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -433,7 +433,7 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons executions[x] = fill.Data{ ID: result[x].ExecID, Timestamp: result[x].ExecTime.Time(), - Exchange: by.Name, + Exchange: e.Name, AssetType: assetType, CurrencyPair: cp, Side: side, @@ -443,59 +443,59 @@ func (by *Bybit) wsProcessExecution(assetType asset.Item, resp *WebsocketRespons Amount: result[x].ExecQty.Float64(), } } - by.Websocket.DataHandler <- executions + e.Websocket.DataHandler <- executions return nil } -func (by *Bybit) wsProcessPosition(resp *WebsocketResponse) error { +func (e *Exchange) wsProcessPosition(resp *WebsocketResponse) error { var result WsPositions err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - by.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result return nil } -func (by *Bybit) wsLeverageTokenNav(resp *WebsocketResponse) error { +func (e *Exchange) wsLeverageTokenNav(resp *WebsocketResponse) error { var result LTNav err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - by.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result return nil } -func (by *Bybit) wsProcessLeverageTokenTicker(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessLeverageTokenTicker(assetType asset.Item, resp *WebsocketResponse) error { var result TickerItem err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - cp, err := by.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } - by.Websocket.DataHandler <- &ticker.Price{ + e.Websocket.DataHandler <- &ticker.Price{ Last: result.LastPrice.Float64(), High: result.HighPrice24H.Float64(), Low: result.LowPrice24H.Float64(), Pair: cp, - ExchangeName: by.Name, + ExchangeName: e.Name, AssetType: assetType, LastUpdated: resp.PushTimestamp.Time(), } return nil } -func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error { +func (e *Exchange) wsProcessLeverageTokenKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error { var result LTKlines err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - cp, err := by.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -509,7 +509,7 @@ func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *Websock Timestamp: result[x].Timestamp.Time(), Pair: cp, AssetType: assetType, - Exchange: by.Name, + Exchange: e.Name, StartTime: result[x].Start.Time(), CloseTime: result[x].End.Time(), Interval: interval.String(), @@ -519,27 +519,27 @@ func (by *Bybit) wsProcessLeverageTokenKline(assetType asset.Item, resp *Websock LowPrice: result[x].Low.Float64(), } } - by.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result return nil } -func (by *Bybit) wsProcessLiquidation(resp *WebsocketResponse) error { +func (e *Exchange) wsProcessLiquidation(resp *WebsocketResponse) error { var result WebsocketLiquidation err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - by.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result return nil } -func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error { +func (e *Exchange) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, topicSplit []string) error { var result WsKlines err := json.Unmarshal(resp.Data, &result) if err != nil { return err } - cp, err := by.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(topicSplit[2], assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -553,7 +553,7 @@ func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, t Timestamp: result[x].Timestamp.Time(), Pair: cp, AssetType: assetType, - Exchange: by.Name, + Exchange: e.Name, StartTime: result[x].Start.Time(), CloseTime: result[x].End.Time(), Interval: interval.String(), @@ -564,21 +564,21 @@ func (by *Bybit) wsProcessKline(assetType asset.Item, resp *WebsocketResponse, t Volume: result[x].Volume.Float64(), } } - by.Websocket.DataHandler <- spotCandlesticks + e.Websocket.DataHandler <- spotCandlesticks return nil } -func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResponse) error { tickResp := new(TickerItem) if err := json.Unmarshal(resp.Data, tickResp); err != nil { return err } - p, err := by.MatchSymbolWithAvailablePairs(tickResp.Symbol, assetType, hasPotentialDelimiter(assetType)) + p, err := e.MatchSymbolWithAvailablePairs(tickResp.Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } - pFmt, err := by.GetPairFormat(assetType, false) + pFmt, err := e.GetPairFormat(assetType, false) if err != nil { return err } @@ -588,12 +588,12 @@ func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResp if resp.Type == "snapshot" { tick = &ticker.Price{ Pair: p, - ExchangeName: by.Name, + ExchangeName: e.Name, AssetType: assetType, } } else { // ticker updates may be partial, so we need to update the current ticker - tick, err = ticker.GetTicker(by.Name, p, assetType) + tick, err = ticker.GetTicker(e.Name, p, assetType) if err != nil { return err } @@ -603,7 +603,7 @@ func (by *Bybit) wsProcessPublicTicker(assetType asset.Item, resp *WebsocketResp tick.LastUpdated = resp.PushTimestamp.Time() if err = ticker.ProcessTicker(tick); err == nil { - by.Websocket.DataHandler <- tick + e.Websocket.DataHandler <- tick } return err @@ -667,7 +667,7 @@ func updateTicker(tick *ticker.Price, resp *TickerItem) { } } -func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketResponse) error { var result WebsocketPublicTrades err := json.Unmarshal(resp.Data, &result) if err != nil { @@ -675,7 +675,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo } tradeDatas := make([]trade.Data, len(result)) for x := range result { - cp, err := by.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(result[x].Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -687,7 +687,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo Timestamp: result[x].OrderFillTimestamp.Time(), CurrencyPair: cp, AssetType: assetType, - Exchange: by.Name, + Exchange: e.Name, Price: result[x].Price.Float64(), Amount: result[x].Size.Float64(), Side: side, @@ -697,7 +697,7 @@ func (by *Bybit) wsProcessPublicTrade(assetType asset.Item, resp *WebsocketRespo return trade.AddTradesToBuffer(tradeDatas...) } -func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketResponse) error { +func (e *Exchange) wsProcessOrderbook(assetType asset.Item, resp *WebsocketResponse) error { var result WsOrderbookDetail if err := json.Unmarshal(resp.Data, &result); err != nil { return err @@ -706,7 +706,7 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons return nil } - cp, err := by.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType)) + cp, err := e.MatchSymbolWithAvailablePairs(result.Symbol, assetType, hasPotentialDelimiter(assetType)) if err != nil { return err } @@ -722,9 +722,9 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons } if resp.Type == "snapshot" { - return by.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Pair: cp, - Exchange: by.Name, + Exchange: e.Name, Asset: assetType, LastUpdated: resp.OrderbookLastUpdated.Time(), LastUpdateID: result.UpdateID, @@ -733,7 +733,7 @@ func (by *Bybit) wsProcessOrderbook(assetType asset.Item, resp *WebsocketRespons Bids: bids, }) } - return by.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Pair: cp, Asks: asks, Bids: bids, diff --git a/exchanges/bybit/bybit_wrapper.go b/exchanges/bybit/bybit_wrapper.go index aa35ea2293f..3a373646718 100644 --- a/exchanges/bybit/bybit_wrapper.go +++ b/exchanges/bybit/bybit_wrapper.go @@ -53,27 +53,27 @@ var ( ) // SetDefaults sets the basic defaults for Bybit -func (by *Bybit) SetDefaults() { - by.Name = "Bybit" - by.Enabled = true - by.Verbose = true - by.API.CredentialsValidator.RequiresKey = true - by.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Bybit" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for _, n := range assetPairFmts { ps := currency.PairStore{AssetEnabled: true, RequestFormat: n.reqFmt, ConfigFormat: n.cfgFmt} - if err := by.SetAssetPairStore(n.asset, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", by.Name, n.asset, err) + if err := e.SetAssetPairStore(n.asset, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, n.asset, err) } } for _, a := range []asset.Item{asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.Options} { - if err := by.DisableAssetWebsocketSupport(a); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", by.Name, a, err) + if err := e.DisableAssetWebsocketSupport(a); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, a, err) } } - by.Features = exchange.Features{ + e.Features = exchange.Features{ CurrencyTranslations: currency.NewTranslations( map[currency.Code]currency.Code{ currency.NewCode("10000000AIDOGE"): currency.AIDOGE, @@ -186,8 +186,8 @@ func (by *Bybit) SetDefaults() { Subscriptions: defaultSubscriptions.Clone(), } - by.API.Endpoints = by.NewEndpoints() - err := by.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err := e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: bybitAPIURL, exchange.RestCoinMargined: bybitAPIURL, exchange.RestUSDTMargined: bybitAPIURL, @@ -199,62 +199,62 @@ func (by *Bybit) SetDefaults() { log.Errorln(log.ExchangeSys, err) } - if by.Requester, err = request.New(by.Name, + if e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit()), ); err != nil { log.Errorln(log.ExchangeSys, err) } - by.Websocket = websocket.NewManager() - by.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - by.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - by.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (by *Bybit) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - by.SetEnabled(false) + e.SetEnabled(false) return nil } - err = by.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningEndpoint, err := by.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = by.Websocket.Setup( + err = e.Websocket.Setup( &websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: spotPublic, RunningURL: wsRunningEndpoint, RunningURLAuth: websocketPrivate, - Connector: by.WsConnect, - Subscriber: by.Subscribe, - Unsubscriber: by.Unsubscribe, - GenerateSubscriptions: by.generateSubscriptions, - Features: &by.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, }, - TradeFeed: by.Features.Enabled.TradeFeed, + TradeFeed: e.Features.Enabled.TradeFeed, }) if err != nil { return err } - err = by.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ - URL: by.Websocket.GetWebsocketURL(), + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + URL: e.Websocket.GetWebsocketURL(), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: bybitWebsocketTimer, }) @@ -262,7 +262,7 @@ func (by *Bybit) Setup(exch *config.Exchange) error { return err } - return by.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: websocketPrivate, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -271,18 +271,18 @@ func (by *Bybit) Setup(exch *config.Exchange) error { } // AuthenticateWebsocket sends an authentication message to the websocket -func (by *Bybit) AuthenticateWebsocket(ctx context.Context) error { - return by.WsAuth(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.WsAuth(ctx) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (by *Bybit) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !by.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%s %w", a, asset.ErrNotSupported) } var pair currency.Pair var category string - format, err := by.GetPairFormat(a, false) + format, err := e.GetPairFormat(a, false) if err != nil { return nil, err } @@ -296,7 +296,7 @@ func (by *Bybit) FetchTradablePairs(ctx context.Context, a asset.Item) (currency case asset.Spot, asset.CoinMarginedFutures, asset.USDCMarginedFutures, asset.USDTMarginedFutures: category = getCategoryName(a) for { - response, err = by.GetInstrumentInfo(ctx, category, "", "Trading", "", nextPageCursor, 1000) + response, err = e.GetInstrumentInfo(ctx, category, "", "Trading", "", nextPageCursor, 1000) if err != nil { return nil, err } @@ -311,7 +311,7 @@ func (by *Bybit) FetchTradablePairs(ctx context.Context, a asset.Item) (currency for x := range supportedOptionsTypes { nextPageCursor = "" for { - response, err = by.GetInstrumentInfo(ctx, category, "", "Trading", supportedOptionsTypes[x], nextPageCursor, 1000) + response, err = e.GetInstrumentInfo(ctx, category, "", "Trading", supportedOptionsTypes[x], nextPageCursor, 1000) if err != nil { return nil, err } @@ -369,28 +369,28 @@ func getCategoryName(a asset.Item) string { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (by *Bybit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assetTypes := by.GetAssetTypes(true) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assetTypes := e.GetAssetTypes(true) for i := range assetTypes { - pairs, err := by.FetchTradablePairs(ctx, assetTypes[i]) + pairs, err := e.FetchTradablePairs(ctx, assetTypes[i]) if err != nil { return err } - err = by.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) + err = e.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) if err != nil { return err } } - return by.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error { - enabled, err := by.GetEnabledPairs(assetType) +func (e *Exchange) UpdateTickers(ctx context.Context, assetType asset.Item) error { + enabled, err := e.GetEnabledPairs(assetType) if err != nil { return err } - format, err := by.GetPairFormat(assetType, false) + format, err := e.GetPairFormat(assetType, false) if err != nil { return err } @@ -399,13 +399,13 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error case asset.Spot, asset.USDCMarginedFutures, asset.USDTMarginedFutures, asset.CoinMarginedFutures: - ticks, err = by.GetTickers(ctx, getCategoryName(assetType), "", "", time.Time{}) + ticks, err = e.GetTickers(ctx, getCategoryName(assetType), "", "", time.Time{}) if err != nil { return err } for x := range ticks.List { var pair currency.Pair - pair, err = by.MatchSymbolWithAvailablePairs(ticks.List[x].Symbol, assetType, true) + pair, err = e.MatchSymbolWithAvailablePairs(ticks.List[x].Symbol, assetType, true) if err != nil { continue } @@ -422,7 +422,7 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error AskSize: ticks.List[x].Ask1Size.Float64(), Volume: ticks.List[x].Volume24H.Float64(), Pair: pair.Format(format), - ExchangeName: by.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { @@ -431,13 +431,13 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error } case asset.Options: for x := range supportedOptionsTypes { - ticks, err = by.GetTickers(ctx, getCategoryName(assetType), "", supportedOptionsTypes[x], time.Time{}) + ticks, err = e.GetTickers(ctx, getCategoryName(assetType), "", supportedOptionsTypes[x], time.Time{}) if err != nil { return err } for x := range ticks.List { var pair currency.Pair - pair, err = by.MatchSymbolWithAvailablePairs(ticks.List[x].Symbol, assetType, true) + pair, err = e.MatchSymbolWithAvailablePairs(ticks.List[x].Symbol, assetType, true) if err != nil { continue } @@ -454,7 +454,7 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error AskSize: ticks.List[x].Ask1Size.Float64(), Volume: ticks.List[x].Volume24H.Float64(), Pair: pair.Format(format), - ExchangeName: by.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { @@ -469,24 +469,24 @@ func (by *Bybit) UpdateTickers(ctx context.Context, assetType asset.Item) error } // UpdateTicker updates and returns the ticker for a currency pair -func (by *Bybit) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { - if err := by.UpdateTickers(ctx, assetType); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, assetType); err != nil { return nil, err } - return ticker.GetTicker(by.Name, p, assetType) + return ticker.GetTicker(e.Name, p, assetType) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := by.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } var orderbookNew *Orderbook var err error - p, err = by.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -499,7 +499,7 @@ func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if assetType == asset.USDCMarginedFutures && !p.Quote.Equal(currency.PERP) { p.Delimiter = currency.DashDelimiter } - orderbookNew, err = by.GetOrderBook(ctx, getCategoryName(assetType), p.String(), 0) + orderbookNew, err = e.GetOrderBook(ctx, getCategoryName(assetType), p.String(), 0) default: return nil, fmt.Errorf("%s %w", assetType, asset.ErrNotSupported) } @@ -507,10 +507,10 @@ func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return nil, err } book := &orderbook.Book{ - Exchange: by.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: by.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make([]orderbook.Level, len(orderbookNew.Bids)), Asks: make([]orderbook.Level, len(orderbookNew.Asks)), } @@ -530,16 +530,16 @@ func (by *Bybit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(by.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies -func (by *Bybit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount var accountType string - info.Exchange = by.Name - at, err := by.FetchAccountType(ctx) + info.Exchange = e.Name + at, err := e.FetchAccountType(ctx) if err != nil { return info, err } @@ -562,7 +562,7 @@ func (by *Bybit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a default: return info, fmt.Errorf("%s %w", assetType, asset.ErrNotSupported) } - balances, err := by.GetWalletBalance(ctx, accountType, "") + balances, err := e.GetWalletBalance(ctx, accountType, "") if err != nil { return info, err } @@ -585,7 +585,7 @@ func (by *Bybit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a acc.Currencies = currencyBalance acc.AssetType = assetType info.Accounts = append(info.Accounts, acc) - creds, err := by.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -598,15 +598,15 @@ func (by *Bybit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (by *Bybit) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (by *Bybit) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { switch a { case asset.Spot, asset.Options, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures: - withdrawals, err := by.GetWithdrawalRecords(ctx, c, "", "2", "", time.Time{}, time.Time{}, 0) + withdrawals, err := e.GetWithdrawalRecords(ctx, c, "", "2", "", time.Time{}, time.Time{}, 0) if err != nil { return nil, err } @@ -632,8 +632,8 @@ func (by *Bybit) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a a } // GetRecentTrades returns the most recent trades for a currency and asset -func (by *Bybit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - formattedPair, err := by.FormatExchangeCurrency(p, assetType) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + formattedPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -647,9 +647,9 @@ func (by *Bybit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType if assetType == asset.USDCMarginedFutures && !p.Quote.Equal(currency.PERP) { formattedPair.Delimiter = currency.DashDelimiter } - tradeData, err = by.GetPublicTradingHistory(ctx, getCategoryName(assetType), formattedPair.String(), "", "", limit) + tradeData, err = e.GetPublicTradingHistory(ctx, getCategoryName(assetType), formattedPair.String(), "", "", limit) case asset.Options: - tradeData, err = by.GetPublicTradingHistory(ctx, getCategoryName(assetType), formattedPair.String(), formattedPair.Base.String(), "", limit) + tradeData, err = e.GetPublicTradingHistory(ctx, getCategoryName(assetType), formattedPair.String(), formattedPair.Base.String(), "", limit) default: return nil, fmt.Errorf("%s %w", assetType, asset.ErrNotSupported) } @@ -663,7 +663,7 @@ func (by *Bybit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType return nil, err } resp[i] = trade.Data{ - Exchange: by.Name, + Exchange: e.Name, CurrencyPair: formattedPair, AssetType: assetType, Price: tradeData.List[i].Price.Float64(), @@ -674,7 +674,7 @@ func (by *Bybit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } } - if by.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err := trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -686,9 +686,9 @@ func (by *Bybit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } // GetHistoricTrades returns historic trade data within the timeframe provided -func (by *Bybit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, _, _ time.Time) ([]trade.Data, error) { var err error - p, err = by.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -702,12 +702,12 @@ func (by *Bybit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTy if assetType == asset.USDCMarginedFutures && !p.Quote.Equal(currency.PERP) { p.Delimiter = currency.DashDelimiter } - tradeHistoryResponse, err = by.GetPublicTradingHistory(ctx, getCategoryName(assetType), p.String(), "", "", limit) + tradeHistoryResponse, err = e.GetPublicTradingHistory(ctx, getCategoryName(assetType), p.String(), "", "", limit) if err != nil { return nil, err } case asset.Options: - tradeHistoryResponse, err = by.GetPublicTradingHistory(ctx, getCategoryName(assetType), p.String(), p.Base.String(), "", limit) + tradeHistoryResponse, err = e.GetPublicTradingHistory(ctx, getCategoryName(assetType), p.String(), p.Base.String(), "", limit) if err != nil { return nil, err } @@ -722,7 +722,7 @@ func (by *Bybit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTy } resp[x] = trade.Data{ TID: tradeHistoryResponse.List[x].ExecutionID, - Exchange: by.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -746,12 +746,12 @@ func orderTypeToString(oType order.Type) string { } // SubmitOrder submits a new order -func (by *Bybit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - err := s.Validate(by.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } - formattedPair, err := by.FormatExchangeCurrency(s.Pair, s.AssetType) + formattedPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -807,7 +807,7 @@ func (by *Bybit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi arg.SlOrderType = getOrderTypeString(s.RiskManagementModes.StopLoss.OrderType) arg.SlLimitPrice = s.RiskManagementModes.StopLoss.LimitPrice } - response, err = by.PlaceOrder(ctx, arg) + response, err = e.PlaceOrder(ctx, arg) if err != nil { return nil, err } @@ -833,7 +833,7 @@ func getOrderTypeString(oType order.Type) string { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (by *Bybit) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } @@ -841,7 +841,7 @@ func (by *Bybit) ModifyOrder(ctx context.Context, action *order.Modify) (*order. result *OrderResponse err error ) - action.Pair, err = by.FormatExchangeCurrency(action.Pair, action.AssetType) + action.Pair, err = e.FormatExchangeCurrency(action.Pair, action.AssetType) if err != nil { return nil, err } @@ -866,7 +866,7 @@ func (by *Bybit) ModifyOrder(ctx context.Context, action *order.Modify) (*order. StopLossTriggerBy: action.RiskManagementModes.StopLoss.TriggerPriceType.String(), StopLossLimitPrice: action.RiskManagementModes.StopLoss.LimitPrice, } - result, err = by.AmendOrder(ctx, arg) + result, err = e.AmendOrder(ctx, arg) if err != nil { return nil, err } @@ -885,11 +885,11 @@ func (by *Bybit) ModifyOrder(ctx context.Context, action *order.Modify) (*order. } // CancelOrder cancels an order by its corresponding ID number -func (by *Bybit) CancelOrder(ctx context.Context, ord *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, ord *order.Cancel) error { if err := ord.Validate(ord.StandardCancel()); err != nil { return err } - format, err := by.GetPairFormat(ord.AssetType, true) + format, err := e.GetPairFormat(ord.AssetType, true) if err != nil { return err } @@ -898,7 +898,7 @@ func (by *Bybit) CancelOrder(ctx context.Context, ord *order.Cancel) error { if ord.AssetType == asset.USDCMarginedFutures && !ord.Pair.Quote.Equal(currency.PERP) { ord.Pair.Delimiter = currency.DashDelimiter } - _, err = by.CancelTradeOrder(ctx, &CancelOrderParams{ + _, err = e.CancelTradeOrder(ctx, &CancelOrderParams{ Category: getCategoryName(ord.AssetType), Symbol: ord.Pair.Format(format), OrderID: ord.OrderID, @@ -911,7 +911,7 @@ func (by *Bybit) CancelOrder(ctx context.Context, ord *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func (by *Bybit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -930,7 +930,7 @@ func (by *Bybit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde case o[i].ClientOrderID == "" && o[i].OrderID == "": return nil, order.ErrOrderIDNotSet default: - o[i].Pair, err = by.FormatExchangeCurrency(o[i].Pair, category) + o[i].Pair, err = e.FormatExchangeCurrency(o[i].Pair, category) if err != nil { return nil, err } @@ -941,7 +941,7 @@ func (by *Bybit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } } } - cancelledOrders, err := by.CancelBatchOrder(ctx, &CancelBatchOrder{ + cancelledOrders, err := e.CancelBatchOrder(ctx, &CancelBatchOrder{ Category: getCategoryName(category), Request: requests, }) @@ -958,12 +958,12 @@ func (by *Bybit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } // CancelAllOrders cancels all orders associated with a currency pair -func (by *Bybit) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { err := orderCancellation.Validate() if err != nil { return order.CancelAllResponse{}, err } - orderCancellation.Pair, err = by.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) + orderCancellation.Pair, err = e.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) if err != nil { return order.CancelAllResponse{}, err } @@ -975,7 +975,7 @@ func (by *Bybit) CancelAllOrders(ctx context.Context, orderCancellation *order.C if orderCancellation.AssetType == asset.USDCMarginedFutures && !orderCancellation.Pair.Quote.Equal(currency.PERP) { orderCancellation.Pair.Delimiter = currency.DashDelimiter } - activeOrder, err := by.CancelAllTradeOrders(ctx, &CancelAllOrdersParam{ + activeOrder, err := e.CancelAllTradeOrders(ctx, &CancelAllOrdersParam{ Category: getCategoryName(orderCancellation.AssetType), Symbol: orderCancellation.Pair, BaseCoin: orderCancellation.Pair.Base.String(), @@ -993,14 +993,14 @@ func (by *Bybit) CancelAllOrders(ctx context.Context, orderCancellation *order.C } // GetOrderInfo returns order information based on order ID -func (by *Bybit) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty - } else if err := by.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + } else if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - pair, err := by.FormatExchangeCurrency(pair, assetType) + pair, err := e.FormatExchangeCurrency(pair, assetType) if err != nil { return nil, err } @@ -1010,7 +1010,7 @@ func (by *Bybit) GetOrderInfo(ctx context.Context, orderID string, pair currency if assetType == asset.USDCMarginedFutures && !pair.Quote.Equal(currency.PERP) { pair.Delimiter = currency.DashDelimiter } - resp, err := by.GetOpenOrders(ctx, getCategoryName(assetType), pair.String(), "", "", orderID, "", "", "", 0, 1) + resp, err := e.GetOpenOrders(ctx, getCategoryName(assetType), pair.String(), "", "", orderID, "", "", "", 0, 1) if err != nil { return nil, err } @@ -1027,7 +1027,7 @@ func (by *Bybit) GetOrderInfo(ctx context.Context, orderID string, pair currency } return &order.Detail{ Amount: resp.List[0].OrderQuantity.Float64(), - Exchange: by.Name, + Exchange: e.Name, OrderID: resp.List[0].OrderID, ClientOrderID: resp.List[0].OrderLinkID, Side: getSide(resp.List[0].Side), @@ -1048,8 +1048,8 @@ func (by *Bybit) GetOrderInfo(ctx context.Context, orderID string, pair currency } // GetDepositAddress returns a deposit address for a specified currency -func (by *Bybit) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { - dAddressInfo, err := by.GetMasterDepositAddress(ctx, cryptocurrency, chain) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { + dAddressInfo, err := e.GetMasterDepositAddress(ctx, cryptocurrency, chain) if err != nil { return nil, err } @@ -1066,10 +1066,9 @@ func (by *Bybit) GetDepositAddress(ctx context.Context, cryptocurrency currency. return nil, fmt.Errorf("%w for currency: %s chain: %s", deposit.ErrAddressNotFound, cryptocurrency, chain) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (by *Bybit) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - info, err := by.GetCoinInfo(ctx, cryptocurrency) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + info, err := e.GetCoinInfo(ctx, cryptocurrency) if err != nil { return nil, err } @@ -1086,11 +1085,11 @@ func (by *Bybit) GetAvailableTransferChains(ctx context.Context, cryptocurrency // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (by *Bybit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - wID, err := by.WithdrawCurrency(ctx, + wID, err := e.WithdrawCurrency(ctx, &WithdrawalParam{ Coin: withdrawRequest.Currency, Chain: withdrawRequest.Crypto.Chain, @@ -1109,18 +1108,18 @@ func (by *Bybit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (by *Bybit) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (by *Bybit) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1128,7 +1127,7 @@ func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque if len(req.Pairs) == 0 { return nil, currency.ErrCurrencyPairsEmpty } - format, err := by.GetPairFormat(req.AssetType, true) + format, err := e.GetPairFormat(req.AssetType, true) if err != nil { return nil, err } @@ -1145,11 +1144,11 @@ func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque switch req.AssetType { case asset.Spot, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures, asset.Options: if baseCoin != currency.EMPTYCODE { - openOrders, err := by.GetOpenOrders(ctx, getCategoryName(req.AssetType), "", baseCoin.String(), "", req.FromOrderID, "", "", "", 0, 50) + openOrders, err := e.GetOpenOrders(ctx, getCategoryName(req.AssetType), "", baseCoin.String(), "", req.FromOrderID, "", "", "", 0, 50) if err != nil { return nil, err } - newOpenOrders, err := by.ConstructOrderDetails(openOrders.List, req.AssetType, currency.EMPTYPAIR, req.Pairs) + newOpenOrders, err := e.ConstructOrderDetails(openOrders.List, req.AssetType, currency.EMPTYPAIR, req.Pairs) if err != nil { return nil, err } @@ -1159,11 +1158,11 @@ func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque if req.AssetType == asset.USDCMarginedFutures && !req.Pairs[y].Quote.Equal(currency.PERP) { req.Pairs[y].Delimiter = currency.DashDelimiter } - openOrders, err := by.GetOpenOrders(ctx, getCategoryName(req.AssetType), req.Pairs[y].String(), "", "", req.FromOrderID, "", "", "", 0, 50) + openOrders, err := e.GetOpenOrders(ctx, getCategoryName(req.AssetType), req.Pairs[y].String(), "", "", req.FromOrderID, "", "", "", 0, 50) if err != nil { return nil, err } - newOpenOrders, err := by.ConstructOrderDetails(openOrders.List, req.AssetType, req.Pairs[y], currency.Pairs{}) + newOpenOrders, err := e.ConstructOrderDetails(openOrders.List, req.AssetType, req.Pairs[y], currency.Pairs{}) if err != nil { return nil, err } @@ -1173,16 +1172,16 @@ func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque default: return orders, fmt.Errorf("%s %w", req.AssetType, asset.ErrNotSupported) } - return req.Filter(by.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ConstructOrderDetails constructs list of order.Detail instances given list of TradeOrder and other filtering information -func (by *Bybit) ConstructOrderDetails(tradeOrders []TradeOrder, assetType asset.Item, pair currency.Pair, filterPairs currency.Pairs) (order.FilteredOrders, error) { +func (e *Exchange) ConstructOrderDetails(tradeOrders []TradeOrder, assetType asset.Item, pair currency.Pair, filterPairs currency.Pairs) (order.FilteredOrders, error) { orders := make([]order.Detail, 0, len(tradeOrders)) var err error var ePair currency.Pair for x := range tradeOrders { - ePair, err = by.MatchSymbolWithAvailablePairs(tradeOrders[x].Symbol, assetType, true) + ePair, err = e.MatchSymbolWithAvailablePairs(tradeOrders[x].Symbol, assetType, true) if err != nil { return nil, err } @@ -1197,7 +1196,7 @@ func (by *Bybit) ConstructOrderDetails(tradeOrders []TradeOrder, assetType asset orders = append(orders, order.Detail{ Amount: tradeOrders[x].OrderQuantity.Float64(), Date: tradeOrders[x].CreatedTime.Time(), - Exchange: by.Name, + Exchange: e.Name, OrderID: tradeOrders[x].OrderID, ClientOrderID: tradeOrders[x].OrderLinkID, Side: getSide(tradeOrders[x].Side), @@ -1221,7 +1220,7 @@ func (by *Bybit) ConstructOrderDetails(tradeOrders []TradeOrder, assetType asset // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1230,14 +1229,14 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque if req.AssetType == asset.Options { limit = 25 } - format, err := by.GetPairFormat(req.AssetType, false) + format, err := e.GetPairFormat(req.AssetType, false) if err != nil { return nil, err } var orders []order.Detail switch req.AssetType { case asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures, asset.Options: - resp, err := by.GetTradeOrderHistory(ctx, getCategoryName(req.AssetType), "", req.FromOrderID, "", "", "", "", "", "", req.StartTime, req.EndTime, limit) + resp, err := e.GetTradeOrderHistory(ctx, getCategoryName(req.AssetType), "", req.FromOrderID, "", "", "", "", "", "", req.StartTime, req.EndTime, limit) if err != nil { return nil, err } @@ -1247,11 +1246,11 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var side order.Side side, err = order.StringToOrderSide(resp.List[i].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", by.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var pair currency.Pair - pair, err = by.MatchSymbolWithAvailablePairs(resp.List[i].Symbol, req.AssetType, true) + pair, err = e.MatchSymbolWithAvailablePairs(resp.List[i].Symbol, req.AssetType, true) if err != nil { return nil, err } @@ -1265,7 +1264,7 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque RemainingAmount: resp.List[i].LeavesQuantity.Float64(), Date: resp.List[i].CreatedTime.Time(), LastUpdated: resp.List[i].UpdatedTime.Time(), - Exchange: by.Name, + Exchange: e.Name, OrderID: resp.List[i].OrderID, Side: side, Type: orderType, @@ -1284,7 +1283,7 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque orders = append(orders, detail) } case asset.Spot: - resp, err := by.GetTradeOrderHistory(ctx, getCategoryName(req.AssetType), "", req.FromOrderID, "", "", "", "", "", "", req.StartTime, req.EndTime, limit) + resp, err := e.GetTradeOrderHistory(ctx, getCategoryName(req.AssetType), "", req.FromOrderID, "", "", "", "", "", "", req.StartTime, req.EndTime, limit) if err != nil { return nil, err } @@ -1294,10 +1293,10 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var side order.Side side, err = order.StringToOrderSide(resp.List[i].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", by.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var pair currency.Pair - pair, err = by.MatchSymbolWithAvailablePairs(resp.List[i].Symbol, req.AssetType, true) + pair, err = e.MatchSymbolWithAvailablePairs(resp.List[i].Symbol, req.AssetType, true) if err != nil { return nil, err } @@ -1312,7 +1311,7 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque Cost: resp.List[i].AveragePrice.Float64() * resp.List[i].CumulativeExecQuantity.Float64(), Date: resp.List[i].CreatedTime.Time(), LastUpdated: resp.List[i].UpdatedTime.Time(), - Exchange: by.Name, + Exchange: e.Name, OrderID: resp.List[i].OrderID, Side: side, Type: orderType, @@ -1332,15 +1331,15 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque return orders, fmt.Errorf("%s %w", req.AssetType, asset.ErrNotSupported) } order.FilterOrdersByPairs(&orders, req.Pairs) - return req.Filter(by.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetFeeByType returns an estimate of fee based on the type of transaction -func (by *Bybit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder.Pair.IsEmpty() { return 0, currency.ErrCurrencyPairEmpty } - if (!by.AreCredentialsValid(ctx) || by.SkipAuthCheck) && + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } @@ -1348,18 +1347,18 @@ func (by *Bybit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild case exchange.OfflineTradeFee: return getOfflineTradeFee(feeBuilder.PurchasePrice, feeBuilder.Amount), nil default: - assets := by.getCategoryFromPair(feeBuilder.Pair) + assets := e.getCategoryFromPair(feeBuilder.Pair) var err error var baseCoin, pairString string if assets[0] == asset.Options { baseCoin = feeBuilder.Pair.Base.String() } else { - pairString, err = by.FormatSymbol(feeBuilder.Pair, assets[0]) + pairString, err = e.FormatSymbol(feeBuilder.Pair, assets[0]) if err != nil { return 0, err } } - accountFee, err := by.GetFeeRate(ctx, getCategoryName(assets[0]), pairString, baseCoin) + accountFee, err := e.GetFeeRate(ctx, getCategoryName(assets[0]), pairString, baseCoin) if err != nil { return 0, err } @@ -1378,11 +1377,11 @@ func getOfflineTradeFee(price, amount float64) float64 { return 0.01 * price * amount } -func (by *Bybit) getCategoryFromPair(pair currency.Pair) []asset.Item { - assets := by.GetAssetTypes(true) +func (e *Exchange) getCategoryFromPair(pair currency.Pair) []asset.Item { + assets := e.GetAssetTypes(true) containingAssets := make([]asset.Item, 0, len(assets)) for a := range assets { - pairs, err := by.GetAvailablePairs(assets[a]) + pairs, err := e.GetAvailablePairs(assets[a]) if err != nil { continue } @@ -1394,16 +1393,16 @@ func (by *Bybit) getCategoryFromPair(pair currency.Pair) []asset.Item { } // ValidateAPICredentials validates current credentials used for wrapper -func (by *Bybit) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := by.UpdateAccountInfo(ctx, assetType) - return by.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (by *Bybit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { switch a { case asset.Spot, asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.USDCMarginedFutures: - req, err := by.GetKlineRequest(pair, a, interval, start, end, false) + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } @@ -1412,7 +1411,7 @@ func (by *Bybit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a req.RequestFormatted.Delimiter = currency.DashDelimiter } var candles []KlineItem - candles, err = by.GetKlines(ctx, getCategoryName(req.Asset), req.RequestFormatted.String(), req.ExchangeInterval, req.Start, req.End, req.RequestLimit) + candles, err = e.GetKlines(ctx, getCategoryName(req.Asset), req.RequestFormatted.String(), req.ExchangeInterval, req.Start, req.End, req.RequestLimit) if err != nil { return nil, err } @@ -1435,10 +1434,10 @@ func (by *Bybit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (by *Bybit) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { switch a { case asset.Spot, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures: - req, err := by.GetKlineExtendedRequest(pair, a, interval, start, end) + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1448,7 +1447,7 @@ func (by *Bybit) GetHistoricCandlesExtended(ctx context.Context, pair currency.P req.RequestFormatted.Delimiter = currency.DashDelimiter } var klineItems []KlineItem - klineItems, err = by.GetKlines(ctx, + klineItems, err = e.GetKlines(ctx, getCategoryName(req.Asset), req.RequestFormatted.String(), req.ExchangeInterval, @@ -1477,8 +1476,8 @@ func (by *Bybit) GetHistoricCandlesExtended(ctx context.Context, pair currency.P } // GetServerTime returns the current exchange server time. -func (by *Bybit) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - info, err := by.GetBybitServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + info, err := e.GetBybitServerTime(ctx) if err != nil { return time.Time{}, err } @@ -1512,7 +1511,7 @@ func (i *InstrumentInfo) transformSymbol(a asset.Item) string { } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { var ( allInstrumentsInfo InstrumentsInfo nextPageCursor string @@ -1520,7 +1519,7 @@ func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e switch a { case asset.Spot, asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures: for { - instrumentInfo, err := by.GetInstrumentInfo(ctx, getCategoryName(a), "", "", "", nextPageCursor, 1000) + instrumentInfo, err := e.GetInstrumentInfo(ctx, getCategoryName(a), "", "", "", nextPageCursor, 1000) if err != nil { return err } @@ -1551,7 +1550,7 @@ func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e for i := range supportedOptionsTypes { nextPageCursor = "" for { - instrumentInfo, err := by.GetInstrumentInfo(ctx, getCategoryName(a), "", "", supportedOptionsTypes[i], nextPageCursor, 1000) + instrumentInfo, err := e.GetInstrumentInfo(ctx, getCategoryName(a), "", "", supportedOptionsTypes[i], nextPageCursor, 1000) if err != nil { return fmt.Errorf("%w - %v", err, supportedOptionsTypes[i]) } @@ -1571,9 +1570,9 @@ func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e continue } symbol := allInstrumentsInfo.List[x].transformSymbol(a) - pair, err := by.MatchSymbolWithAvailablePairs(symbol, a, true) + pair, err := e.MatchSymbolWithAvailablePairs(symbol, a, true) if err != nil { - log.Warnf(log.ExchangeSys, "%s unable to load limits for %s %v, pair data missing", by.Name, a, symbol) + log.Warnf(log.ExchangeSys, "%s unable to load limits for %s %v, pair data missing", e.Name, a, symbol) continue } limits = append(limits, order.MinMaxLevel{ @@ -1590,15 +1589,15 @@ func (by *Bybit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e MaximumQuoteAmount: allInstrumentsInfo.List[x].LotSizeFilter.MaxOrderQty.Float64() * allInstrumentsInfo.List[x].PriceFilter.MaxPrice.Float64(), }) } - return by.LoadLimits(limits) + return e.LoadLimits(limits) } // SetLeverage sets the account's initial leverage for the asset type and pair -func (by *Bybit) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, amount float64, orderSide order.Side) error { +func (e *Exchange) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, _ margin.Type, amount float64, orderSide order.Side) error { switch item { case asset.USDTMarginedFutures, asset.USDCMarginedFutures, asset.CoinMarginedFutures: var err error - pair, err = by.FormatExchangeCurrency(pair, item) + pair, err = e.FormatExchangeCurrency(pair, item) if err != nil { return err } @@ -1619,14 +1618,14 @@ func (by *Bybit) SetLeverage(ctx context.Context, item asset.Item, pair currency default: return order.ErrSideIsInvalid } - return by.SetLeverageLevel(ctx, params) + return e.SetLeverageLevel(ctx, params) default: return fmt.Errorf("%w %v", asset.ErrNotSupported, item) } } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (by *Bybit) IsPerpetualFutureCurrency(a asset.Item, p currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, p currency.Pair) (bool, error) { if !a.IsFutures() { return false, nil } @@ -1637,18 +1636,18 @@ func (by *Bybit) IsPerpetualFutureCurrency(a asset.Item, p currency.Pair) (bool, } // GetFuturesContractDetails returns details about futures contracts -func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !by.SupportsAsset(item) { + if !e.SupportsAsset(item) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } - inverseContracts, err := by.GetInstrumentInfo(ctx, getCategoryName(item), "", "", "", "", 1000) + inverseContracts, err := e.GetInstrumentInfo(ctx, getCategoryName(item), "", "", "", "", 1000) if err != nil { return nil, err } - format, err := by.GetPairFormat(item, false) + format, err := e.GetPairFormat(item, false) if err != nil { return nil, err } @@ -1670,12 +1669,12 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) return nil, err } contractType := strings.ToLower(inverseContracts.List[i].ContractType) - var s, e time.Time + var start, end time.Time if inverseContracts.List[i].LaunchTime.Time().UnixMilli() > 0 { - s = inverseContracts.List[i].LaunchTime.Time() + start = inverseContracts.List[i].LaunchTime.Time() } if inverseContracts.List[i].DeliveryTime.Time().UnixMilli() > 0 { - e = inverseContracts.List[i].DeliveryTime.Time() + end = inverseContracts.List[i].DeliveryTime.Time() } var ct futures.ContractType @@ -1683,24 +1682,24 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) case "inverseperpetual": ct = futures.Perpetual case "inversefutures": - ct, err = getContractLength(e.Sub(s)) + ct, err = getContractLength(end.Sub(start)) if err != nil { - return nil, fmt.Errorf("%w %v %v %v %v-%v", err, by.Name, item, cp, inverseContracts.List[i].LaunchTime.Time(), inverseContracts.List[i].DeliveryTime) + return nil, fmt.Errorf("%w %v %v %v %v-%v", err, e.Name, item, cp, inverseContracts.List[i].LaunchTime.Time(), inverseContracts.List[i].DeliveryTime) } default: - if by.Verbose { - log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", by.Name, item, cp, s, e) + if e.Verbose { + log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", e.Name, item, cp, start, end) } ct = futures.Unknown } resp = append(resp, futures.Contract{ - Exchange: by.Name, + Exchange: e.Name, Name: cp.Format(format), Underlying: underlying, Asset: item, - StartDate: s, - EndDate: e, + StartDate: start, + EndDate: end, SettlementType: futures.Inverse, IsActive: strings.EqualFold(inverseContracts.List[i].Status, "trading"), Status: inverseContracts.List[i].Status, @@ -1711,7 +1710,7 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) } return resp, nil case asset.USDCMarginedFutures: - linearContracts, err := by.GetInstrumentInfo(ctx, "linear", "", "", "", "", 1000) + linearContracts, err := e.GetInstrumentInfo(ctx, "linear", "", "", "", "", 1000) if err != nil { return nil, err } @@ -1749,9 +1748,9 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) case "linearfutures": ct, err = getContractLength(instruments[i].DeliveryTime.Time().Sub(instruments[i].LaunchTime.Time())) if err != nil { - return nil, fmt.Errorf("%w %v %v %v %v-%v", err, by.Name, item, cp, instruments[i].LaunchTime.Time(), instruments[i].DeliveryTime.Time()) + return nil, fmt.Errorf("%w %v %v %v %v-%v", err, e.Name, item, cp, instruments[i].LaunchTime.Time(), instruments[i].DeliveryTime.Time()) } - cp, err = by.MatchSymbolWithAvailablePairs(instruments[i].Symbol, item, true) + cp, err = e.MatchSymbolWithAvailablePairs(instruments[i].Symbol, item, true) if err != nil { if errors.Is(err, currency.ErrPairNotFound) { continue @@ -1759,11 +1758,11 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) return nil, err } default: - if by.Verbose { - log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", by.Name, item, cp, instruments[i].LaunchTime.Time(), instruments[i].DeliveryTime.Time()) + if e.Verbose { + log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", e.Name, item, cp, instruments[i].LaunchTime.Time(), instruments[i].DeliveryTime.Time()) } ct = futures.Unknown - cp, err = by.MatchSymbolWithAvailablePairs(instruments[i].Symbol, item, true) + cp, err = e.MatchSymbolWithAvailablePairs(instruments[i].Symbol, item, true) if err != nil { if errors.Is(err, currency.ErrPairNotFound) { continue @@ -1773,7 +1772,7 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) } resp = append(resp, futures.Contract{ - Exchange: by.Name, + Exchange: e.Name, Name: cp.Format(format), Underlying: underlying, Asset: item, @@ -1790,7 +1789,7 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) } return resp, nil case asset.USDTMarginedFutures: - linearContracts, err := by.GetInstrumentInfo(ctx, "linear", "", "", "", "", 1000) + linearContracts, err := e.GetInstrumentInfo(ctx, "linear", "", "", "", "", 1000) if err != nil { return nil, err } @@ -1821,12 +1820,12 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) return nil, err } contractType := strings.ToLower(instruments[i].ContractType) - var s, e time.Time + var start, end time.Time if !instruments[i].LaunchTime.Time().IsZero() { - s = instruments[i].LaunchTime.Time() + start = instruments[i].LaunchTime.Time() } if !instruments[i].DeliveryTime.Time().IsZero() { - e = instruments[i].DeliveryTime.Time() + end = instruments[i].DeliveryTime.Time() } var ct futures.ContractType @@ -1834,24 +1833,24 @@ func (by *Bybit) GetFuturesContractDetails(ctx context.Context, item asset.Item) case "linearperpetual": ct = futures.Perpetual case "linearfutures": - ct, err = getContractLength(e.Sub(s)) + ct, err = getContractLength(end.Sub(start)) if err != nil { - return nil, fmt.Errorf("%w %v %v %v %v-%v", err, by.Name, item, cp, s, e) + return nil, fmt.Errorf("%w %v %v %v %v-%v", err, e.Name, item, cp, start, end) } default: - if by.Verbose { - log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", by.Name, item, cp, s, e) + if e.Verbose { + log.Warnf(log.ExchangeSys, "%v unhandled contract type for %v %v %v-%v", e.Name, item, cp, start, end) } ct = futures.Unknown } resp = append(resp, futures.Contract{ - Exchange: by.Name, + Exchange: e.Name, Name: cp.Format(format), Underlying: underlying, Asset: item, - StartDate: s, - EndDate: e, + StartDate: start, + EndDate: end, SettlementType: futures.Linear, IsActive: strings.EqualFold(instruments[i].Status, "trading"), Status: instruments[i].Status, @@ -1894,7 +1893,7 @@ func getContractLength(contractLength time.Duration) (futures.ContractType, erro } // GetLatestFundingRates returns the latest funding rates data -func (by *Bybit) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1908,18 +1907,18 @@ func (by *Bybit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates symbol := "" if !r.Pair.IsEmpty() { - format, err := by.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } symbol = r.Pair.Format(format).String() } - ticks, err := by.GetTickers(ctx, getCategoryName(r.Asset), symbol, "", time.Time{}) + ticks, err := e.GetTickers(ctx, getCategoryName(r.Asset), symbol, "", time.Time{}) if err != nil { return nil, err } - instrumentInfo, err := by.GetInstrumentInfo(ctx, getCategoryName(r.Asset), symbol, "", "", "", 1000) + instrumentInfo, err := e.GetInstrumentInfo(ctx, getCategoryName(r.Asset), symbol, "", "", "", 1000) if err != nil { return nil, err } @@ -1928,7 +1927,7 @@ func (by *Bybit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates for i := range ticks.List { var cp currency.Pair var isEnabled bool - cp, isEnabled, err = by.MatchSymbolCheckEnabled(ticks.List[i].Symbol, r.Asset, false) + cp, isEnabled, err = e.MatchSymbolCheckEnabled(ticks.List[i].Symbol, r.Asset, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } else if !isEnabled { @@ -1947,7 +1946,7 @@ func (by *Bybit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates lrt = ticks.List[i].NextFundingTime.Time().Add(-fundingInterval) } resp = append(resp, fundingrate.LatestRateResponse{ - Exchange: by.Name, + Exchange: e.Name, TimeChecked: time.Now(), Asset: r.Asset, Pair: cp, @@ -1967,7 +1966,7 @@ func (by *Bybit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } // GetOpenInterest returns the open interest rate for a given asset pair -func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { if k[i].Asset != asset.USDCMarginedFutures && k[i].Asset != asset.USDTMarginedFutures && @@ -1976,7 +1975,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } } if len(k) == 1 { - formattedPair, err := by.FormatExchangeCurrency(k[0].Pair(), k[0].Asset) + formattedPair, err := e.FormatExchangeCurrency(k[0].Pair(), k[0].Asset) if err != nil { return nil, err } @@ -1986,7 +1985,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } pFmt := formattedPair.String() var ticks *TickerData - ticks, err = by.GetTickers(ctx, getCategoryName(k[0].Asset), pFmt, "", time.Time{}) + ticks, err = e.GetTickers(ctx, getCategoryName(k[0].Asset), pFmt, "", time.Time{}) if err != nil { return nil, err } @@ -1996,7 +1995,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } return []futures.OpenInterest{{ Key: key.ExchangePairAsset{ - Exchange: by.Name, + Exchange: e.Name, Asset: k[0].Asset, Base: k[0].Base, Quote: k[0].Quote, @@ -2008,7 +2007,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut assets := []asset.Item{asset.USDCMarginedFutures, asset.USDTMarginedFutures, asset.CoinMarginedFutures} var resp []futures.OpenInterest for i := range assets { - ticks, err := by.GetTickers(ctx, getCategoryName(assets[i]), "", "", time.Time{}) + ticks, err := e.GetTickers(ctx, getCategoryName(assets[i]), "", "", time.Time{}) if err != nil { return nil, err } @@ -2016,7 +2015,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut var pair currency.Pair var isEnabled bool // only long-dated contracts have a delimiter - pair, isEnabled, err = by.MatchSymbolCheckEnabled(ticks.List[x].Symbol, assets[i], strings.Contains(ticks.List[x].Symbol, currency.DashDelimiter)) + pair, isEnabled, err = e.MatchSymbolCheckEnabled(ticks.List[x].Symbol, assets[i], strings.Contains(ticks.List[x].Symbol, currency.DashDelimiter)) if err != nil || !isEnabled { continue } @@ -2032,7 +2031,7 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: by.Name, + Exchange: e.Name, Base: pair.Base.Item, Quote: pair.Quote.Item, Asset: assets[i], @@ -2045,8 +2044,8 @@ func (by *Bybit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fut } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (by *Bybit) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := by.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } @@ -2060,13 +2059,13 @@ func (by *Bybit) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp curre return tradeBaseURL + "trade/inverse/" + cp.Upper().String(), nil } var symbol string - symbol, err = by.FormatSymbol(cp, a) + symbol, err = e.FormatSymbol(cp, a) if err != nil { return "", err } // convert long-dated to static contracts var io *InstrumentsInfo - io, err = by.GetInstrumentInfo(ctx, getCategoryName(a), symbol, "", "", "", 1000) + io, err = e.GetInstrumentInfo(ctx, getCategoryName(a), symbol, "", "", "", 1000) if err != nil { return "", err } diff --git a/exchanges/coinbasepro/coinbasepro.go b/exchanges/coinbasepro/coinbasepro.go index 98066612b2c..c34252fd5a9 100644 --- a/exchanges/coinbasepro/coinbasepro.go +++ b/exchanges/coinbasepro/coinbasepro.go @@ -55,21 +55,21 @@ const ( coinbaseproTrailingVolume = "users/self/trailing-volume" ) -// CoinbasePro is the overarching type across the coinbasepro package -type CoinbasePro struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with CoinbasePro +type Exchange struct { exchange.Base } // GetProducts returns supported currency pairs on the exchange with specific // information about the pair -func (c *CoinbasePro) GetProducts(ctx context.Context) ([]Product, error) { +func (e *Exchange) GetProducts(ctx context.Context) ([]Product, error) { var products []Product - return products, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproProducts, &products) + return products, e.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproProducts, &products) } // GetOrderbook returns orderbook by currency pair and level -func (c *CoinbasePro) GetOrderbook(ctx context.Context, symbol string, level int) (any, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, symbol string, level int) (any, error) { orderbook := OrderbookResponse{} path := fmt.Sprintf("%s/%s/%s", coinbaseproProducts, symbol, coinbaseproOrderbook) @@ -78,7 +78,7 @@ func (c *CoinbasePro) GetOrderbook(ctx context.Context, symbol string, level int path = fmt.Sprintf("%s/%s/%s?level=%s", coinbaseproProducts, symbol, coinbaseproOrderbook, levelStr) } - if err := c.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook); err != nil { return nil, err } @@ -121,25 +121,25 @@ func (c *CoinbasePro) GetOrderbook(ctx context.Context, symbol string, level int // GetTicker returns ticker by currency pair // currencyPair - example "BTC-USD" -func (c *CoinbasePro) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { tick := Ticker{} path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproTicker) - return tick, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &tick) + return tick, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &tick) } // GetTrades listd the latest trades for a product // currencyPair - example "BTC-USD" -func (c *CoinbasePro) GetTrades(ctx context.Context, currencyPair string) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, currencyPair string) ([]Trade, error) { var trades []Trade path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproTrades) - return trades, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) + return trades, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) } // GetHistoricRates returns historic rates for a product. Rates are returned in // grouped buckets based on requested granularity. -func (c *CoinbasePro) GetHistoricRates(ctx context.Context, currencyPair, start, end string, granularity int64) ([]History, error) { +func (e *Exchange) GetHistoricRates(ctx context.Context, currencyPair, start, end string, granularity int64) ([]History, error) { values := url.Values{} if start != "" { @@ -166,69 +166,69 @@ func (c *CoinbasePro) GetHistoricRates(ctx context.Context, currencyPair, start, path := common.EncodeURLValues( fmt.Sprintf("%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproHistory), values) - return resp, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetStats returns a 24 hr stat for the product. Volume is in base currency // units. open, high, low are in quote currency units. -func (c *CoinbasePro) GetStats(ctx context.Context, currencyPair string) (Stats, error) { +func (e *Exchange) GetStats(ctx context.Context, currencyPair string) (Stats, error) { stats := Stats{} path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproStats) - return stats, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &stats) + return stats, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &stats) } // GetCurrencies returns a list of supported currency on the exchange // Warning: Not all currencies may be currently in use for tradinc. -func (c *CoinbasePro) GetCurrencies(ctx context.Context) ([]Currency, error) { +func (e *Exchange) GetCurrencies(ctx context.Context) ([]Currency, error) { var currencies []Currency - return currencies, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproCurrencies, ¤cies) + return currencies, e.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproCurrencies, ¤cies) } // GetCurrentServerTime returns the API server time -func (c *CoinbasePro) GetCurrentServerTime(ctx context.Context) (ServerTime, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (ServerTime, error) { serverTime := ServerTime{} - return serverTime, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproTime, &serverTime) + return serverTime, e.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproTime, &serverTime) } // GetAccounts returns a list of trading accounts associated with the APIKEYS -func (c *CoinbasePro) GetAccounts(ctx context.Context) ([]AccountResponse, error) { +func (e *Exchange) GetAccounts(ctx context.Context) ([]AccountResponse, error) { var resp []AccountResponse return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproAccounts, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproAccounts, nil, &resp) } // GetAccount returns information for a single account. Use this endpoint when // account_id is known -func (c *CoinbasePro) GetAccount(ctx context.Context, accountID string) (AccountResponse, error) { +func (e *Exchange) GetAccount(ctx context.Context, accountID string) (AccountResponse, error) { resp := AccountResponse{} path := fmt.Sprintf("%s/%s", coinbaseproAccounts, accountID) - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetAccountHistory returns a list of account activity. Account activity either // increases or decreases your account balance. Items are paginated and sorted // latest first. -func (c *CoinbasePro) GetAccountHistory(ctx context.Context, accountID string) ([]AccountLedgerResponse, error) { +func (e *Exchange) GetAccountHistory(ctx context.Context, accountID string) ([]AccountLedgerResponse, error) { var resp []AccountLedgerResponse path := fmt.Sprintf("%s/%s/%s", coinbaseproAccounts, accountID, coinbaseproLedger) - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetHolds returns the holds that are placed on an account for any active // orders or pending withdraw requests. As an order is filled, the hold amount // is updated. If an order is canceled, any remaining hold is removed. For a // withdraw, once it is completed, the hold is removed. -func (c *CoinbasePro) GetHolds(ctx context.Context, accountID string) ([]AccountHolds, error) { +func (e *Exchange) GetHolds(ctx context.Context, accountID string) ([]AccountHolds, error) { var resp []AccountHolds path := fmt.Sprintf("%s/%s/%s", coinbaseproAccounts, accountID, coinbaseproHolds) - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // PlaceLimitOrder places a new limit order. Orders can only be placed if the @@ -248,7 +248,7 @@ func (c *CoinbasePro) GetHolds(ctx context.Context, accountID string) ([]Account // timeInforce - [optional] GTC, GTT, IOC, or FOK (default is GTC) // cancelAfter - [optional] min, hour, day * Requires time_in_force to be GTT // postOnly - [optional] Post only flag Invalid when time_in_force is IOC or FOK -func (c *CoinbasePro) PlaceLimitOrder(ctx context.Context, clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) { +func (e *Exchange) PlaceLimitOrder(ctx context.Context, clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) { req := make(map[string]any) req["type"] = order.Limit.Lower() req["price"] = strconv.FormatFloat(price, 'f', -1, 64) @@ -271,7 +271,7 @@ func (c *CoinbasePro) PlaceLimitOrder(ctx context.Context, clientRef string, pri req["post_only"] = postOnly } resp := GeneralizedOrderResponse{} - return resp.ID, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + return resp.ID, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) } // PlaceMarketOrder places a new market order. @@ -290,7 +290,7 @@ func (c *CoinbasePro) PlaceLimitOrder(ctx context.Context, clientRef string, pri // size - [optional]* Desired amount in BTC // funds [optional]* Desired amount of quote currency to use // * One of size or funds is required. -func (c *CoinbasePro) PlaceMarketOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { +func (e *Exchange) PlaceMarketOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} req := make(map[string]any) req["side"] = side @@ -310,7 +310,7 @@ func (c *CoinbasePro) PlaceMarketOrder(ctx context.Context, clientRef string, si req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -333,7 +333,7 @@ func (c *CoinbasePro) PlaceMarketOrder(ctx context.Context, clientRef string, si // MARGIN ORDER PARAMS // size - [optional]* Desired amount in BTC // funds - [optional]* Desired amount of quote currency to use -func (c *CoinbasePro) PlaceMarginOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { +func (e *Exchange) PlaceMarginOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} req := make(map[string]any) req["side"] = side @@ -353,7 +353,7 @@ func (c *CoinbasePro) PlaceMarginOrder(ctx context.Context, clientRef string, si req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -362,24 +362,24 @@ func (c *CoinbasePro) PlaceMarginOrder(ctx context.Context, clientRef string, si } // CancelExistingOrder cancels order by orderID -func (c *CoinbasePro) CancelExistingOrder(ctx context.Context, orderID string) error { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID string) error { path := fmt.Sprintf("%s/%s", coinbaseproOrders, orderID) - return c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, nil) } // CancelAllExistingOrders cancels all open orders on the exchange and returns // and array of order IDs // currencyPair - [optional] all orders for a currencyPair string will be // canceled -func (c *CoinbasePro) CancelAllExistingOrders(ctx context.Context, currencyPair string) ([]string, error) { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context, currencyPair string) ([]string, error) { var resp []string req := make(map[string]any) if currencyPair != "" { req["product_id"] = currencyPair } - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, coinbaseproOrders, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, coinbaseproOrders, req, &resp) } // GetOrders lists current open orders. Only open or un-settled orders are @@ -387,7 +387,7 @@ func (c *CoinbasePro) CancelAllExistingOrders(ctx context.Context, currencyPair // longer appear in the default request. // status - can be a range of "open", "pending", "done" or "active" // currencyPair - [optional] for example "BTC-USD" -func (c *CoinbasePro) GetOrders(ctx context.Context, status []string, currencyPair string) ([]GeneralizedOrderResponse, error) { +func (e *Exchange) GetOrders(ctx context.Context, status []string, currencyPair string) ([]GeneralizedOrderResponse, error) { var resp []GeneralizedOrderResponse params := url.Values{} @@ -400,19 +400,19 @@ func (c *CoinbasePro) GetOrders(ctx context.Context, status []string, currencyPa path := common.EncodeURLValues(coinbaseproOrders, params) return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetOrder returns a single order by order id. -func (c *CoinbasePro) GetOrder(ctx context.Context, orderID string) (GeneralizedOrderResponse, error) { +func (e *Exchange) GetOrder(ctx context.Context, orderID string) (GeneralizedOrderResponse, error) { resp := GeneralizedOrderResponse{} path := fmt.Sprintf("%s/%s", coinbaseproOrders, orderID) - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetFills returns a list of recent fills -func (c *CoinbasePro) GetFills(ctx context.Context, orderID, currencyPair string) ([]FillResponse, error) { +func (e *Exchange) GetFills(ctx context.Context, orderID, currencyPair string) ([]FillResponse, error) { var resp []FillResponse params := url.Values{} @@ -428,7 +428,7 @@ func (c *CoinbasePro) GetFills(ctx context.Context, orderID, currencyPair string path := common.EncodeURLValues(coinbaseproFills, params) return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // MarginTransfer sends funds between a standard/default profile and a margin @@ -442,7 +442,7 @@ func (c *CoinbasePro) GetFills(ctx context.Context, orderID, currencyPair string // transferType - either "deposit" or "withdraw" // profileID - The id of the margin profile to deposit or withdraw from // currency - currency to transfer, currently on "BTC" or "USD" -func (c *CoinbasePro) MarginTransfer(ctx context.Context, amount float64, transferType, profileID, currency string) (MarginTransfer, error) { +func (e *Exchange) MarginTransfer(ctx context.Context, amount float64, transferType, profileID, currency string) (MarginTransfer, error) { resp := MarginTransfer{} req := make(map[string]any) req["type"] = transferType @@ -451,34 +451,34 @@ func (c *CoinbasePro) MarginTransfer(ctx context.Context, amount float64, transf req["margin_profile_id"] = profileID return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproMarginTransfer, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproMarginTransfer, req, &resp) } // GetPosition returns an overview of account profile. -func (c *CoinbasePro) GetPosition(ctx context.Context) (AccountOverview, error) { +func (e *Exchange) GetPosition(ctx context.Context) (AccountOverview, error) { resp := AccountOverview{} return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPosition, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPosition, nil, &resp) } // ClosePosition closes a position and allowing you to repay position as well // repayOnly - allows the position to be repaid -func (c *CoinbasePro) ClosePosition(ctx context.Context, repayOnly bool) (AccountOverview, error) { +func (e *Exchange) ClosePosition(ctx context.Context, repayOnly bool) (AccountOverview, error) { resp := AccountOverview{} req := make(map[string]any) req["repay_only"] = repayOnly return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPositionClose, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPositionClose, req, &resp) } // GetPayMethods returns a full list of payment methods -func (c *CoinbasePro) GetPayMethods(ctx context.Context) ([]PaymentMethod, error) { +func (e *Exchange) GetPayMethods(ctx context.Context) ([]PaymentMethod, error) { var resp []PaymentMethod return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPaymentMethod, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPaymentMethod, nil, &resp) } // DepositViaPaymentMethod deposits funds from a payment method. See the Payment @@ -487,7 +487,7 @@ func (c *CoinbasePro) GetPayMethods(ctx context.Context) ([]PaymentMethod, error // amount - The amount to deposit // currency - The type of currency // paymentID - ID of the payment method -func (c *CoinbasePro) DepositViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) DepositViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount @@ -495,7 +495,7 @@ func (c *CoinbasePro) DepositViaPaymentMethod(ctx context.Context, amount float6 req["payment_method_id"] = paymentID return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPaymentMethodDeposit, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPaymentMethodDeposit, req, &resp) } // DepositViaCoinbase deposits funds from a coinbase account. Move funds between @@ -506,7 +506,7 @@ func (c *CoinbasePro) DepositViaPaymentMethod(ctx context.Context, amount float6 // amount - The amount to deposit // currency - The type of currency // accountID - ID of the coinbase account -func (c *CoinbasePro) DepositViaCoinbase(ctx context.Context, amount float64, currency, accountID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) DepositViaCoinbase(ctx context.Context, amount float64, currency, accountID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount @@ -514,7 +514,7 @@ func (c *CoinbasePro) DepositViaCoinbase(ctx context.Context, amount float64, cu req["coinbase_account_id"] = accountID return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproDepositCoinbase, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproDepositCoinbase, req, &resp) } // WithdrawViaPaymentMethod withdraws funds to a payment method @@ -522,7 +522,7 @@ func (c *CoinbasePro) DepositViaCoinbase(ctx context.Context, amount float64, cu // amount - The amount to withdraw // currency - The type of currency // paymentID - ID of the payment method -func (c *CoinbasePro) WithdrawViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) WithdrawViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount @@ -530,7 +530,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(ctx context.Context, amount float req["payment_method_id"] = paymentID return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalPaymentMethod, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalPaymentMethod, req, &resp) } // /////////////////////// NO ROUTE FOUND ERROR //////////////////////////////// @@ -555,7 +555,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(ctx context.Context, amount float // amount - The amount to withdraw // currency - The type of currency // cryptoAddress - A crypto address of the recipient -func (c *CoinbasePro) WithdrawCrypto(ctx context.Context, amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount @@ -563,15 +563,15 @@ func (c *CoinbasePro) WithdrawCrypto(ctx context.Context, amount float64, curren req["crypto_address"] = cryptoAddress return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalCrypto, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalCrypto, req, &resp) } // GetCoinbaseAccounts returns a list of coinbase accounts -func (c *CoinbasePro) GetCoinbaseAccounts(ctx context.Context) ([]CoinbaseAccounts, error) { +func (e *Exchange) GetCoinbaseAccounts(ctx context.Context) ([]CoinbaseAccounts, error) { var resp []CoinbaseAccounts return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproCoinbaseAccounts, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproCoinbaseAccounts, nil, &resp) } // GetReport returns batches of historic information about your account in @@ -586,7 +586,7 @@ func (c *CoinbasePro) GetCoinbaseAccounts(ctx context.Context) ([]CoinbaseAccoun // if type is account // format - pdf or csv (default is pdf) // email - [optional] Email address to send the report to -func (c *CoinbasePro) GetReport(ctx context.Context, reportType, startDate, endDate, currencyPair, accountID, format, email string) (Report, error) { +func (e *Exchange) GetReport(ctx context.Context, reportType, startDate, endDate, currencyPair, accountID, format, email string) (Report, error) { resp := Report{} req := make(map[string]any) req["type"] = reportType @@ -608,29 +608,29 @@ func (c *CoinbasePro) GetReport(ctx context.Context, reportType, startDate, endD } return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproReports, req, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproReports, req, &resp) } // GetReportStatus once a report request has been accepted for processing, the // status is available by polling the report resource endpoint. -func (c *CoinbasePro) GetReportStatus(ctx context.Context, reportID string) (Report, error) { +func (e *Exchange) GetReportStatus(ctx context.Context, reportID string) (Report, error) { resp := Report{} path := fmt.Sprintf("%s/%s", coinbaseproReports, reportID) - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetTrailingVolume this request will return your 30-day trailing volume for // all products. -func (c *CoinbasePro) GetTrailingVolume(ctx context.Context) ([]Volume, error) { +func (e *Exchange) GetTrailingVolume(ctx context.Context) ([]Volume, error) { var resp []Volume return resp, - c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproTrailingVolume, nil, &resp) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproTrailingVolume, nil, &resp) } // GetTransfers returns a history of withdrawal and or deposit transactions -func (c *CoinbasePro) GetTransfers(ctx context.Context, profileID, transferType string, limit int64, start, end time.Time) ([]TransferHistory, error) { +func (e *Exchange) GetTransfers(ctx context.Context, profileID, transferType string, limit int64, start, end time.Time) ([]TransferHistory, error) { if !start.IsZero() && !end.IsZero() { err := common.StartEndTimeCheck(start, end) if err != nil { @@ -654,12 +654,12 @@ func (c *CoinbasePro) GetTransfers(ctx context.Context, profileID, transferType req["type"] = transferType } var resp []TransferHistory - return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproTransfers, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproTransfers, req, &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (c *CoinbasePro) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := c.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -668,23 +668,23 @@ func (c *CoinbasePro) SendHTTPRequest(ctx context.Context, ep exchange.URL, path Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: c.Verbose, - HTTPDebugging: c.HTTPDebugging, - HTTPRecording: c.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return c.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any) (err error) { - creds, err := c.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any) (err error) { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := c.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -719,24 +719,24 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ctx context.Context, ep excha Headers: headers, Body: bytes.NewBuffer(payload), Result: result, - Verbose: c.Verbose, - HTTPDebugging: c.HTTPDebugging, - HTTPRecording: c.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - return c.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) + return e.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (c *CoinbasePro) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - trailingVolume, err := c.GetTrailingVolume(ctx) + trailingVolume, err := e.GetTrailingVolume(ctx) if err != nil { return 0, err } - fee = c.calculateTradingFee(trailingVolume, + fee = e.calculateTradingFee(trailingVolume, feeBuilder.Pair.Base, feeBuilder.Pair.Quote, feeBuilder.Pair.Delimiter, @@ -763,7 +763,7 @@ func getOfflineTradeFee(price, amount float64) float64 { return 0.0025 * price * amount } -func (c *CoinbasePro) calculateTradingFee(trailingVolume []Volume, base, quote currency.Code, delimiter string, purchasePrice, amount float64, isMaker bool) float64 { +func (e *Exchange) calculateTradingFee(trailingVolume []Volume, base, quote currency.Code, delimiter string, purchasePrice, amount float64, isMaker bool) float64 { var fee float64 for _, i := range trailingVolume { if strings.EqualFold(i.ProductID, base.String()+delimiter+quote.String()) { diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index 7730b7e6cff..d1cc31cb66b 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -27,7 +27,7 @@ import ( ) var ( - c *CoinbasePro + e *Exchange testPair = currency.NewPairWithDelimiter(currency.BTC.String(), currency.USD.String(), "-") ) @@ -44,32 +44,32 @@ func TestMain(_ *testing.M) { } func TestGetProducts(t *testing.T) { - _, err := c.GetProducts(t.Context()) + _, err := e.GetProducts(t.Context()) if err != nil { t.Errorf("Coinbase, GetProducts() Error: %s", err) } } func TestGetOrderbook(t *testing.T) { - _, err := c.GetOrderbook(t.Context(), testPair.String(), 2) + _, err := e.GetOrderbook(t.Context(), testPair.String(), 2) if err != nil { t.Error(err) } - _, err = c.GetOrderbook(t.Context(), testPair.String(), 3) + _, err = e.GetOrderbook(t.Context(), testPair.String(), 3) if err != nil { t.Error(err) } } func TestGetTicker(t *testing.T) { - _, err := c.GetTicker(t.Context(), testPair.String()) + _, err := e.GetTicker(t.Context(), testPair.String()) if err != nil { t.Error("GetTicker() error", err) } } func TestGetTrades(t *testing.T) { - _, err := c.GetTrades(t.Context(), testPair.String()) + _, err := e.GetTrades(t.Context(), testPair.String()) if err != nil { t.Error("GetTrades() error", err) } @@ -94,7 +94,7 @@ func TestHistoryUnmarshalJSON(t *testing.T) { func TestGetHistoricRates(t *testing.T) { t.Parallel() - result, err := c.GetHistoricRates(t.Context(), "BTC-USD", "", "", 0) + result, err := e.GetHistoricRates(t.Context(), "BTC-USD", "", "", 0) require.NoError(t, err) assert.NotNil(t, result) } @@ -102,7 +102,7 @@ func TestGetHistoricRates(t *testing.T) { func TestGetHistoricRatesGranularityCheck(t *testing.T) { end := time.Now() start := end.Add(-time.Hour * 2) - _, err := c.GetHistoricCandles(t.Context(), + _, err := e.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneHour, start, end) if err != nil { t.Fatal(err) @@ -111,26 +111,26 @@ func TestGetHistoricRatesGranularityCheck(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - _, err := c.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) + _, err := e.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, time.Unix(1546300800, 0), time.Unix(1577836799, 0)) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") } func TestGetStats(t *testing.T) { - _, err := c.GetStats(t.Context(), testPair.String()) + _, err := e.GetStats(t.Context(), testPair.String()) if err != nil { t.Error("GetStats() error", err) } } func TestGetCurrencies(t *testing.T) { - _, err := c.GetCurrencies(t.Context()) + _, err := e.GetCurrencies(t.Context()) if err != nil { t.Error("GetCurrencies() error", err) } } func TestGetCurrentServerTime(t *testing.T) { - _, err := c.GetCurrentServerTime(t.Context()) + _, err := e.GetCurrentServerTime(t.Context()) if err != nil { t.Error("GetServerTime() error", err) } @@ -138,7 +138,7 @@ func TestGetCurrentServerTime(t *testing.T) { func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := c.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) if st.IsZero() { @@ -148,13 +148,13 @@ func TestWrapperGetServerTime(t *testing.T) { func TestAuthRequests(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, c) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := c.GetAccounts(t.Context()) + _, err := e.GetAccounts(t.Context()) if err != nil { t.Error("GetAccounts() error", err) } - accountResponse, err := c.GetAccount(t.Context(), + accountResponse, err := e.GetAccount(t.Context(), "13371337-1337-1337-1337-133713371337") if accountResponse.ID != "" { t.Error("Expecting no data returned") @@ -162,7 +162,7 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - accountHistoryResponse, err := c.GetAccountHistory(t.Context(), + accountHistoryResponse, err := e.GetAccountHistory(t.Context(), "13371337-1337-1337-1337-133713371337") if len(accountHistoryResponse) > 0 { t.Error("Expecting no data returned") @@ -170,7 +170,7 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - getHoldsResponse, err := c.GetHolds(t.Context(), + getHoldsResponse, err := e.GetHolds(t.Context(), "13371337-1337-1337-1337-133713371337") if len(getHoldsResponse) > 0 { t.Error("Expecting no data returned") @@ -178,7 +178,7 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - orderResponse, err := c.PlaceLimitOrder(t.Context(), + orderResponse, err := e.PlaceLimitOrder(t.Context(), "", 0.001, 0.001, order.Buy.Lower(), "", "", testPair.String(), "", false) if orderResponse != "" { @@ -187,7 +187,7 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - marketOrderResponse, err := c.PlaceMarketOrder(t.Context(), + marketOrderResponse, err := e.PlaceMarketOrder(t.Context(), "", 1, 0, order.Buy.Lower(), testPair.String(), "") if marketOrderResponse != "" { @@ -196,7 +196,7 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - fillsResponse, err := c.GetFills(t.Context(), + fillsResponse, err := e.GetFills(t.Context(), "1337", testPair.String()) if len(fillsResponse) > 0 { t.Error("Expecting no data returned") @@ -204,11 +204,11 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - _, err = c.GetFills(t.Context(), "", "") + _, err = e.GetFills(t.Context(), "", "") if err == nil { t.Error("Expecting error") } - marginTransferResponse, err := c.MarginTransfer(t.Context(), + marginTransferResponse, err := e.MarginTransfer(t.Context(), 1, "withdraw", "13371337-1337-1337-1337-133713371337", "BTC") if marginTransferResponse.ID != "" { t.Error("Expecting no data returned") @@ -216,19 +216,19 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - _, err = c.GetPosition(t.Context()) + _, err = e.GetPosition(t.Context()) if err == nil { t.Error("Expecting error") } - _, err = c.ClosePosition(t.Context(), false) + _, err = e.ClosePosition(t.Context(), false) if err == nil { t.Error("Expecting error") } - _, err = c.GetPayMethods(t.Context()) + _, err = e.GetPayMethods(t.Context()) if err != nil { t.Error("GetPayMethods() error", err) } - _, err = c.GetCoinbaseAccounts(t.Context()) + _, err = e.GetCoinbaseAccounts(t.Context()) if err != nil { t.Error("GetCoinbaseAccounts() error", err) } @@ -246,11 +246,11 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := c.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(c) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -264,9 +264,9 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { func TestGetFee(t *testing.T) { feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(c) { + if sharedtestvalues.AreAPICredentialsSet(e) { // CryptocurrencyTradeFee Basic - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -274,21 +274,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -296,14 +296,14 @@ func TestGetFee(t *testing.T) { // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -311,7 +311,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.EUR - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -319,7 +319,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := c.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -334,7 +334,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp) } @@ -346,7 +346,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp) } @@ -358,7 +358,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp) } @@ -370,7 +370,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.002) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.002) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.002), resp) } @@ -382,7 +382,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.001) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.001) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.001), resp) } @@ -394,7 +394,7 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp) } @@ -406,14 +406,14 @@ func TestCalculateTradingFee(t *testing.T) { }, } - if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, true); resp != float64(0) { + if resp := e.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, true); resp != float64(0) { t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp) } } func TestFormatWithdrawPermissions(t *testing.T) { expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText - withdrawPermissions := c.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -427,10 +427,10 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := c.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -443,26 +443,26 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := c.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } getOrdersRequest.Pairs = []currency.Pair{} - _, err = c.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } getOrdersRequest.Pairs = nil - _, err = c.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -472,11 +472,11 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) // limit order orderSubmission := &order.Submit{ - Exchange: c.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "-", Base: currency.BTC, @@ -489,16 +489,16 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := c.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(c) && (err != nil || response.Status != order.New) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } // market order from amount orderSubmission = &order.Submit{ - Exchange: c.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "-", Base: currency.BTC, @@ -510,16 +510,16 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err = c.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(c) && (err != nil || response.Status != order.New) { + response, err = e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } // market order from quote amount orderSubmission = &order.Submit{ - Exchange: c.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "-", Base: currency.BTC, @@ -531,17 +531,17 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err = c.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(c) && (err != nil || response.Status != order.New) { + response, err = e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", @@ -550,18 +550,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := c.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", @@ -570,12 +570,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := c.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } @@ -586,9 +586,9 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - _, err := c.ModifyOrder(t.Context(), + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") @@ -597,10 +597,10 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: c.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -609,19 +609,19 @@ func TestWithdraw(t *testing.T) { }, } - _, err := c.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: 100, @@ -633,18 +633,18 @@ func TestWithdrawFiat(t *testing.T) { }, } - _, err := c.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: 100, @@ -656,18 +656,18 @@ func TestWithdrawInternationalBank(t *testing.T) { }, } - _, err := c.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestGetDepositAddress(t *testing.T) { - _, err := c.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress() error", err) } @@ -675,19 +675,19 @@ func TestGetDepositAddress(t *testing.T) { // TestWsAuth dials websocket, sends login request. func TestWsAuth(t *testing.T) { - if !c.Websocket.IsEnabled() && !c.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(c) { + if !e.Websocket.IsEnabled() && !e.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } var dialer gws.Dialer - err := c.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) require.NoError(t, err, "Dial must not error") - go c.wsReadData(t.Context()) + go e.wsReadData(t.Context()) - err = c.Subscribe(subscription.List{{Channel: "user", Pairs: currency.Pairs{testPair}}}) + err = e.Subscribe(subscription.List{{Channel: "user", Pairs: currency.Pairs{testPair}}}) require.NoError(t, err, "Subscribe must not error") timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout) select { - case badResponse := <-c.Websocket.DataHandler: + case badResponse := <-e.Websocket.DataHandler: t.Error(badResponse) case <-timer.C: } @@ -722,7 +722,7 @@ func TestWsSubscribe(t *testing.T) { } ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -736,7 +736,7 @@ func TestWsHeartbeat(t *testing.T) { "product_id": "BTC-USD", "time": "2014-11-07T08:19:28.464459Z" }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -794,7 +794,7 @@ func TestWsStatus(t *testing.T) { } ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -813,7 +813,7 @@ func TestWsTicker(t *testing.T) { "best_bid": "4388", "best_ask": "4388.01" }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -827,7 +827,7 @@ func TestWsOrderbook(t *testing.T) { "asks": [["10102.55", "0.57753524"]], "time":"2023-08-15T06:46:55.376250Z" }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -844,7 +844,7 @@ func TestWsOrderbook(t *testing.T) { ] ] }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -862,7 +862,7 @@ func TestWsOrders(t *testing.T) { "side": "buy", "order_type": "limit" }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -877,7 +877,7 @@ func TestWsOrders(t *testing.T) { "side": "buy", "order_type": "market" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -892,7 +892,7 @@ func TestWsOrders(t *testing.T) { "remaining_size": "1.00", "side": "sell" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -908,7 +908,7 @@ func TestWsOrders(t *testing.T) { "side": "sell", "remaining_size": "0" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -925,7 +925,7 @@ func TestWsOrders(t *testing.T) { "price": "400.23", "side": "sell" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -941,7 +941,7 @@ func TestWsOrders(t *testing.T) { "price": "400.23", "side": "sell" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -956,7 +956,7 @@ func TestWsOrders(t *testing.T) { "price": "400.23", "side": "sell" }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -975,7 +975,7 @@ func TestWsOrders(t *testing.T) { "taker_fee_rate": "0.0025", "private": true }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -1005,7 +1005,7 @@ func TestStatusToStandardStatus(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := c.GetRecentTrades(t.Context(), testPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), testPair, asset.Spot) if err != nil { t.Error(err) } @@ -1013,7 +1013,7 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := c.GetHistoricTrades(t.Context(), + _, err := e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) @@ -1022,8 +1022,8 @@ func TestGetHistoricTrades(t *testing.T) { func TestGetTransfers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, c) - _, err := c.GetTransfers(t.Context(), "", "", 100, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTransfers(t.Context(), "", "", 100, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -1031,12 +1031,12 @@ func TestGetTransfers(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, c) - for _, a := range c.GetAssetTypes(false) { - pairs, err := c.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := c.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/coinbasepro/coinbasepro_websocket.go b/exchanges/coinbasepro/coinbasepro_websocket.go index 247dcd29c7e..c77c264e711 100644 --- a/exchanges/coinbasepro/coinbasepro_websocket.go +++ b/exchanges/coinbasepro/coinbasepro_websocket.go @@ -28,39 +28,39 @@ const ( ) // WsConnect initiates a websocket connection -func (c *CoinbasePro) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !c.Websocket.IsEnabled() || !c.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := c.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - c.Websocket.Wg.Add(1) - go c.wsReadData(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) return nil } // wsReadData receives and passes on websocket messages for processing -func (c *CoinbasePro) wsReadData(ctx context.Context) { - defer c.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := c.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := c.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, respRaw []byte) error { msgType := wsMsgType{} err := json.Unmarshal(respRaw, &msgType) if err != nil { @@ -78,9 +78,9 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { if err != nil { return err } - c.Websocket.DataHandler <- status + e.Websocket.DataHandler <- status case "error": - c.Websocket.DataHandler <- errors.New(string(respRaw)) + e.Websocket.DataHandler <- errors.New(string(respRaw)) case "ticker": wsTicker := WebsocketTicker{} err := json.Unmarshal(respRaw, &wsTicker) @@ -88,11 +88,11 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { return err } - c.Websocket.DataHandler <- &ticker.Price{ + e.Websocket.DataHandler <- &ticker.Price{ LastUpdated: wsTicker.Time, Pair: wsTicker.ProductID, AssetType: asset.Spot, - ExchangeName: c.Name, + ExchangeName: e.Name, Open: wsTicker.Open24H, High: wsTicker.High24H, Low: wsTicker.Low24H, @@ -109,7 +109,7 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { return err } - err = c.ProcessSnapshot(&snapshot) + err = e.ProcessSnapshot(&snapshot) if err != nil { return err } @@ -120,7 +120,7 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { return err } - err = c.ProcessOrderbookUpdate(&update) + err = e.ProcessOrderbookUpdate(&update) if err != nil { return err } @@ -135,24 +135,24 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { var oStatus order.Status oType, err = order.StringToOrderType(wsOrder.OrderType) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: wsOrder.OrderID, Err: err, } } oSide, err = order.StringToOrderSide(wsOrder.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: wsOrder.OrderID, Err: err, } } oStatus, err = statusToStandardStatus(wsOrder.Type) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: wsOrder.OrderID, Err: err, } @@ -165,10 +165,10 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { ts = wsOrder.Timestamp.Time() } - creds, err := c.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: wsOrder.OrderID, Err: err, } @@ -182,11 +182,11 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { if wsOrder.UserID != "" { var p currency.Pair var a asset.Item - p, a, err = c.GetRequestFormattedPairAndAssetType(wsOrder.ProductID) + p, a, err = e.GetRequestFormattedPairAndAssetType(wsOrder.ProductID) if err != nil { return err } - c.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ HiddenOrder: wsOrder.Private, Price: wsOrder.Price, Amount: wsOrder.Size, @@ -194,7 +194,7 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { ExecutedAmount: wsOrder.Size - wsOrder.RemainingSize, RemainingAmount: wsOrder.RemainingSize, Fee: wsOrder.TakerFeeRate, - Exchange: c.Name, + Exchange: e.Name, OrderID: wsOrder.OrderID, AccountID: wsOrder.ProfileID, ClientID: clientID, @@ -214,20 +214,20 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { } oSide, err := order.StringToOrderSide(wsOrder.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, Err: err, } } var p currency.Pair var a asset.Item - p, a, err = c.GetRequestFormattedPairAndAssetType(wsOrder.ProductID) + p, a, err = e.GetRequestFormattedPairAndAssetType(wsOrder.ProductID) if err != nil { return err } if wsOrder.UserID != "" { - c.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ OrderID: wsOrder.OrderID, Pair: p, AssetType: a, @@ -235,7 +235,7 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { { Price: wsOrder.Price, Amount: wsOrder.Size, - Exchange: c.Name, + Exchange: e.Name, TID: strconv.FormatInt(wsOrder.TradeID, 10), Side: oSide, Timestamp: wsOrder.Time, @@ -244,12 +244,12 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { }, } } else { - if !c.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } return trade.AddTradesToBuffer(trade.Data{ Timestamp: wsOrder.Time, - Exchange: c.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: wsOrder.Price, @@ -259,7 +259,7 @@ func (c *CoinbasePro) wsHandleData(ctx context.Context, respRaw []byte) error { }) } default: - c.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: c.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } return nil @@ -283,7 +283,7 @@ func statusToStandardStatus(stat string) (order.Status, error) { } // ProcessSnapshot processes the initial orderbook snap shot -func (c *CoinbasePro) ProcessSnapshot(snapshot *WebsocketOrderbookSnapshot) error { +func (e *Exchange) ProcessSnapshot(snapshot *WebsocketOrderbookSnapshot) error { pair, err := currency.NewPairFromString(snapshot.ProductID) if err != nil { return err @@ -294,8 +294,8 @@ func (c *CoinbasePro) ProcessSnapshot(snapshot *WebsocketOrderbookSnapshot) erro Bids: make(orderbook.Levels, len(snapshot.Bids)), Asks: make(orderbook.Levels, len(snapshot.Asks)), Asset: asset.Spot, - Exchange: c.Name, - ValidateOrderbook: c.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, LastUpdated: snapshot.Time, } @@ -307,11 +307,11 @@ func (c *CoinbasePro) ProcessSnapshot(snapshot *WebsocketOrderbookSnapshot) erro ob.Asks[i].Price = snapshot.Asks[i][0].Float64() ob.Asks[i].Amount = snapshot.Asks[i][1].Float64() } - return c.Websocket.Orderbook.LoadSnapshot(ob) + return e.Websocket.Orderbook.LoadSnapshot(ob) } // ProcessOrderbookUpdate updates the orderbook local cache -func (c *CoinbasePro) ProcessOrderbookUpdate(update *WebsocketL2Update) error { +func (e *Exchange) ProcessOrderbookUpdate(update *WebsocketL2Update) error { if len(update.Changes) == 0 { return errors.New("no data in websocket update") } @@ -340,7 +340,7 @@ func (c *CoinbasePro) ProcessOrderbookUpdate(update *WebsocketL2Update) error { } } - return c.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Bids: bids, Asks: asks, Pair: p, @@ -350,19 +350,19 @@ func (c *CoinbasePro) ProcessOrderbookUpdate(update *WebsocketL2Update) error { } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (c *CoinbasePro) generateSubscriptions() (subscription.List, error) { - pairs, err := c.GetEnabledPairs(asset.Spot) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } - pairFmt, err := c.GetPairFormat(asset.Spot, true) + pairFmt, err := e.GetPairFormat(asset.Spot, true) if err != nil { return nil, err } pairs = pairs.Format(pairFmt) - authed := c.IsWebsocketAuthenticationSupported() - subs := make(subscription.List, 0, len(c.Features.Subscriptions)) - for _, baseSub := range c.Features.Subscriptions { + authed := e.IsWebsocketAuthenticationSupported() + subs := make(subscription.List, 0, len(e.Features.Subscriptions)) + for _, baseSub := range e.Features.Subscriptions { if !authed && baseSub.Authenticated { continue } @@ -376,7 +376,7 @@ func (c *CoinbasePro) generateSubscriptions() (subscription.List, error) { } // Subscribe sends a websocket message to receive data from the channel -func (c *CoinbasePro) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() r := &WebsocketSubscribe{ Type: "subscribe", @@ -394,8 +394,8 @@ func (c *CoinbasePro) Subscribe(subs subscription.List) error { } } for _, s := range subs { - if s.Authenticated && r.Key == "" && c.IsWebsocketAuthenticationSupported() { - if err := c.authWsSubscibeReq(ctx, r); err != nil { + if s.Authenticated && r.Key == "" && e.IsWebsocketAuthenticationSupported() { + if err := e.authWsSubscibeReq(ctx, r); err != nil { return err } } @@ -410,15 +410,15 @@ func (c *CoinbasePro) Subscribe(subs subscription.List) error { r.Channels = append(r.Channels, s.Channel) } } - err := c.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) if err == nil { - err = c.Websocket.AddSuccessfulSubscriptions(c.Websocket.Conn, subs...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, subs...) } return err } -func (c *CoinbasePro) authWsSubscibeReq(ctx context.Context, r *WebsocketSubscribe) error { - creds, err := c.GetCredentials(ctx) +func (e *Exchange) authWsSubscibeReq(ctx context.Context, r *WebsocketSubscribe) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -435,7 +435,7 @@ func (c *CoinbasePro) authWsSubscibeReq(ctx context.Context, r *WebsocketSubscri } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (c *CoinbasePro) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() r := &WebsocketSubscribe{ Type: "unsubscribe", @@ -447,9 +447,9 @@ func (c *CoinbasePro) Unsubscribe(subs subscription.List) error { ProductIDs: s.Pairs.Strings(), }) } - err := c.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) if err == nil { - err = c.Websocket.RemoveSubscriptions(c.Websocket.Conn, subs...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, subs...) } return err } diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index d05a3b3bc35..28fc73481bf 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -31,23 +31,23 @@ import ( ) // SetDefaults sets default values for the exchange -func (c *CoinbasePro) SetDefaults() { - c.Name = "CoinbasePro" - c.Enabled = true - c.Verbose = true - c.API.CredentialsValidator.RequiresKey = true - c.API.CredentialsValidator.RequiresSecret = true - c.API.CredentialsValidator.RequiresClientID = true - c.API.CredentialsValidator.RequiresBase64DecodeSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "CoinbasePro" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresClientID = true + e.API.CredentialsValidator.RequiresBase64DecodeSecret = true requestFmt := ¤cy.PairFormat{Delimiter: currency.DashDelimiter, Uppercase: true} configFmt := ¤cy.PairFormat{Delimiter: currency.DashDelimiter, Uppercase: true} - err := c.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - c.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -115,14 +115,14 @@ func (c *CoinbasePro) SetDefaults() { }, } - c.Requester, err = request.New(c.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - c.API.Endpoints = c.NewEndpoints() - err = c.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: coinbaseproAPIURL, exchange.RestSandbox: coinbaseproSandboxAPIURL, exchange.WebsocketSpot: coinbaseproWebsocketURL, @@ -130,41 +130,41 @@ func (c *CoinbasePro) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - c.Websocket = websocket.NewManager() - c.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - c.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - c.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup initialises the exchange parameters with the current configuration -func (c *CoinbasePro) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - c.SetEnabled(false) + e.SetEnabled(false) return nil } - err = c.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := c.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = c.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: coinbaseproWebsocketURL, RunningURL: wsRunningURL, - Connector: c.WsConnect, - Subscriber: c.Subscribe, - Unsubscriber: c.Unsubscribe, - GenerateSubscriptions: c.generateSubscriptions, - Features: &c.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, }, @@ -173,15 +173,15 @@ func (c *CoinbasePro) Setup(exch *config.Exchange) error { return err } - return c.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (c *CoinbasePro) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - products, err := c.GetProducts(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + products, err := e.GetProducts(ctx) if err != nil { return nil, err } @@ -203,24 +203,24 @@ func (c *CoinbasePro) FetchTradablePairs(ctx context.Context, _ asset.Item) (cur // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (c *CoinbasePro) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := c.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = c.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return c.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateAccountInfo retrieves balances for all enabled currencies for the // coinbasepro exchange -func (c *CoinbasePro) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = c.Name - accountBalance, err := c.GetAccounts(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetAccounts(ctx) if err != nil { return response, err } @@ -243,7 +243,7 @@ func (c *CoinbasePro) UpdateAccountInfo(ctx context.Context, assetType asset.Ite return account.Holdings{}, err } - creds, err := c.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -256,22 +256,22 @@ func (c *CoinbasePro) UpdateAccountInfo(ctx context.Context, assetType asset.Ite } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (c *CoinbasePro) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (c *CoinbasePro) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - fPair, err := c.FormatExchangeCurrency(p, a) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := c.GetTicker(ctx, fPair.String()) + tick, err := e.GetTicker(ctx, fPair.String()) if err != nil { return nil, err } - stats, err := c.GetStats(ctx, fPair.String()) + stats, err := e.GetStats(ctx, fPair.String()) if err != nil { return nil, err } @@ -286,7 +286,7 @@ func (c *CoinbasePro) UpdateTicker(ctx context.Context, p currency.Pair, a asset Open: stats.Open, Pair: p, LastUpdated: tick.Time, - ExchangeName: c.Name, + ExchangeName: e.Name, AssetType: a, } @@ -295,29 +295,29 @@ func (c *CoinbasePro) UpdateTicker(ctx context.Context, p currency.Pair, a asset return tickerPrice, err } - return ticker.GetTicker(c.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := c.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: c.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: c.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := c.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := c.GetOrderbook(ctx, fPair.String(), 2) + orderbookNew, err := e.GetOrderbook(ctx, fPair.String(), 2) if err != nil { return book, err } @@ -346,31 +346,31 @@ func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, asse if err != nil { return book, err } - return orderbook.Get(c.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (c *CoinbasePro) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (c *CoinbasePro) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { // while fetching withdrawal history is possible, the API response lacks any useful information // like the currency withdrawn and thus is unsupported. If that position changes, use GetTransfers(...) return nil, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (c *CoinbasePro) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = c.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData []Trade - tradeData, err = c.GetTrades(ctx, p.String()) + tradeData, err = e.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -382,7 +382,7 @@ func (c *CoinbasePro) GetRecentTrades(ctx context.Context, p currency.Pair, asse return nil, err } resp[i] = trade.Data{ - Exchange: c.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].TradeID, 10), CurrencyPair: p, AssetType: assetType, @@ -393,7 +393,7 @@ func (c *CoinbasePro) GetRecentTrades(ctx context.Context, p currency.Pair, asse } } - err = c.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -403,17 +403,17 @@ func (c *CoinbasePro) GetRecentTrades(ctx context.Context, p currency.Pair, asse } // GetHistoricTrades returns historic trade data within the timeframe provided -func (c *CoinbasePro) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (c *CoinbasePro) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(c.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := c.FormatExchangeCurrency(s.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pair, asset.Spot) if err != nil { return nil, err } @@ -421,7 +421,7 @@ func (c *CoinbasePro) SubmitOrder(ctx context.Context, s *order.Submit) (*order. var orderID string switch s.Type { case order.Market: - orderID, err = c.PlaceMarketOrder(ctx, + orderID, err = e.PlaceMarketOrder(ctx, "", s.Amount, s.QuoteAmount, @@ -433,7 +433,7 @@ func (c *CoinbasePro) SubmitOrder(ctx context.Context, s *order.Submit) (*order. if s.TimeInForce == order.ImmediateOrCancel { timeInForce = order.ImmediateOrCancel.String() } - orderID, err = c.PlaceLimitOrder(ctx, + orderID, err = e.PlaceLimitOrder(ctx, "", s.Price, s.Amount, @@ -454,33 +454,33 @@ func (c *CoinbasePro) SubmitOrder(ctx context.Context, s *order.Submit) (*order. // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *CoinbasePro) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (c *CoinbasePro) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - return c.CancelExistingOrder(ctx, o.OrderID) + return e.CancelExistingOrder(ctx, o.OrderID) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (c *CoinbasePro) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (c *CoinbasePro) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { // CancellAllExisting orders returns a list of successful cancellations, we're only interested in failures - _, err := c.CancelAllExistingOrders(ctx, "") + _, err := e.CancelAllExistingOrders(ctx, "") return order.CancelAllResponse{}, err } // GetOrderInfo returns order information based on order ID -func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { - genOrderDetail, err := c.GetOrder(ctx, orderID) +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { + genOrderDetail, err := e.GetOrder(ctx, orderID) if err != nil { return nil, fmt.Errorf("error retrieving order %s : %w", orderID, err) } @@ -502,7 +502,7 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, _ curren } response := order.Detail{ - Exchange: c.GetName(), + Exchange: e.GetName(), OrderID: genOrderDetail.ID, Pair: pair, Side: orderSide, @@ -515,7 +515,7 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, _ curren RemainingAmount: genOrderDetail.Size - genOrderDetail.FilledSize, Fee: genOrderDetail.FillFees, } - fillResponse, err := c.GetFills(ctx, orderID, genOrderDetail.ProductID) + fillResponse, err := e.GetFills(ctx, orderID, genOrderDetail.ProductID) if err != nil { return nil, fmt.Errorf("error retrieving the order fills: %w", err) } @@ -530,7 +530,7 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, _ curren TID: strconv.FormatInt(fillResponse[i].TradeID, 10), Price: fillResponse[i].Price, Amount: fillResponse[i].Size, - Exchange: c.GetName(), + Exchange: e.GetName(), Type: orderType, Side: fillSide, Fee: fillResponse[i].Fee, @@ -540,17 +540,17 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, _ curren } // GetDepositAddress returns a deposit address for a specified currency -func (c *CoinbasePro) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { return nil, common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *CoinbasePro) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := c.WithdrawCrypto(ctx, + resp, err := e.WithdrawCrypto(ctx, withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address) @@ -564,11 +564,11 @@ func (c *CoinbasePro) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawR // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *CoinbasePro) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - paymentMethods, err := c.GetPayMethods(ctx) + paymentMethods, err := e.GetPayMethods(ctx) if err != nil { return nil, err } @@ -584,7 +584,7 @@ func (c *CoinbasePro) WithdrawFiatFunds(ctx context.Context, withdrawRequest *wi return nil, fmt.Errorf("could not find payment method '%v'. Check the name via the website and try again", withdrawRequest.Fiat.Bank.BankName) } - resp, err := c.WithdrawViaPaymentMethod(ctx, + resp, err := e.WithdrawViaPaymentMethod(ctx, withdrawRequest.Amount, withdrawRequest.Currency.String(), selectedWithdrawalMethod.ID) @@ -599,11 +599,11 @@ func (c *CoinbasePro) WithdrawFiatFunds(ctx context.Context, withdrawRequest *wi // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (c *CoinbasePro) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := c.WithdrawFiatFunds(ctx, withdrawRequest) + v, err := e.WithdrawFiatFunds(ctx, withdrawRequest) if err != nil { return nil, err } @@ -614,19 +614,19 @@ func (c *CoinbasePro) WithdrawFiatFundsToInternationalBank(ctx context.Context, } // GetFeeByType returns an estimate of fee based on type of transaction -func (c *CoinbasePro) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !c.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return c.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -634,13 +634,13 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.MultiOrder var respOrders []GeneralizedOrderResponse var fPair currency.Pair for i := range req.Pairs { - fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[i], asset.Spot) if err != nil { return nil, err } var resp []GeneralizedOrderResponse - resp, err = c.GetOrders(ctx, + resp, err = e.GetOrders(ctx, []string{"open", "pending", "active"}, fPair.String()) if err != nil { @@ -649,7 +649,7 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.MultiOrder respOrders = append(respOrders, resp...) } - format, err := c.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -670,7 +670,7 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.MultiOrder var orderType order.Type orderType, err = order.StringToOrderType(respOrders[i].Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", c.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders[i] = order.Detail{ OrderID: respOrders[i].ID, @@ -680,15 +680,15 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.MultiOrder Date: respOrders[i].CreatedAt, Side: side, Pair: curr, - Exchange: c.Name, + Exchange: e.Name, } } - return req.Filter(c.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -698,24 +698,24 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.MultiOrder var fPair currency.Pair var resp []GeneralizedOrderResponse for i := range req.Pairs { - fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[i], asset.Spot) if err != nil { return nil, err } - resp, err = c.GetOrders(ctx, []string{"done"}, fPair.String()) + resp, err = e.GetOrders(ctx, []string{"done"}, fPair.String()) if err != nil { return nil, err } respOrders = append(respOrders, resp...) } } else { - respOrders, err = c.GetOrders(ctx, []string{"done"}, "") + respOrders, err = e.GetOrders(ctx, []string{"done"}, "") if err != nil { return nil, err } } - format, err := c.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -736,12 +736,12 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.MultiOrder var orderStatus order.Status orderStatus, err = order.StringToOrderStatus(respOrders[i].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", c.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var orderType order.Type orderType, err = order.StringToOrderType(respOrders[i].Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", c.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } detail := order.Detail{ OrderID: respOrders[i].ID, @@ -759,23 +759,23 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.MultiOrder Status: orderStatus, Pair: curr, Price: respOrders[i].Price, - Exchange: c.Name, + Exchange: e.Name, } detail.InferCostsAndTimes() orders[i] = detail } - return req.Filter(c.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetHistoricCandles returns a set of candle between two time periods for a // designated time period -func (c *CoinbasePro) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := c.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - history, err := c.GetHistoricRates(ctx, + history, err := e.GetHistoricRates(ctx, req.RequestFormatted.String(), start.Format(time.RFC3339), end.Format(time.RFC3339), @@ -799,8 +799,8 @@ func (c *CoinbasePro) GetHistoricCandles(ctx context.Context, pair currency.Pair } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (c *CoinbasePro) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := c.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -808,7 +808,7 @@ func (c *CoinbasePro) GetHistoricCandlesExtended(ctx context.Context, pair curre timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var history []History - history, err = c.GetHistoricRates(ctx, + history, err = e.GetHistoricRates(ctx, req.RequestFormatted.String(), req.RangeHolder.Ranges[x].Start.Time.Format(time.RFC3339), req.RangeHolder.Ranges[x].End.Time.Format(time.RFC3339), @@ -833,14 +833,14 @@ func (c *CoinbasePro) GetHistoricCandlesExtended(ctx context.Context, pair curre // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (c *CoinbasePro) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := c.UpdateAccountInfo(ctx, assetType) - return c.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetServerTime returns the current exchange server time. -func (c *CoinbasePro) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - st, err := c.GetCurrentServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + st, err := e.GetCurrentServerTime(ctx) if err != nil { return time.Time{}, err } @@ -848,23 +848,23 @@ func (c *CoinbasePro) GetServerTime(ctx context.Context, _ asset.Item) (time.Tim } // GetLatestFundingRates returns the latest funding rates data -func (c *CoinbasePro) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (c *CoinbasePro) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (c *CoinbasePro) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (c *CoinbasePro) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := c.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index c1820f89277..c6addec5941 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -48,43 +48,43 @@ const ( var errLookupInstrumentID = errors.New("unable to lookup instrument ID") -// COINUT is the overarching type across the coinut package -type COINUT struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with COINUT +type Exchange struct { exchange.Base instrumentMap instrumentMap } // SeedInstruments seeds the instrument map -func (c *COINUT) SeedInstruments(ctx context.Context) error { - i, err := c.GetInstruments(ctx) +func (e *Exchange) SeedInstruments(ctx context.Context) error { + i, err := e.GetInstruments(ctx) if err != nil { return err } for _, y := range i.Instruments { - c.instrumentMap.Seed(y[0].Base+y[0].Quote, y[0].InstrumentID) + e.instrumentMap.Seed(y[0].Base+y[0].Quote, y[0].InstrumentID) } return nil } // GetInstruments returns instruments -func (c *COINUT) GetInstruments(ctx context.Context) (Instruments, error) { +func (e *Exchange) GetInstruments(ctx context.Context) (Instruments, error) { var result Instruments params := make(map[string]any) params["sec_type"] = strings.ToUpper(asset.Spot.String()) - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) } // GetInstrumentTicker returns a ticker for a specific instrument -func (c *COINUT) GetInstrumentTicker(ctx context.Context, instrumentID int64) (Ticker, error) { +func (e *Exchange) GetInstrumentTicker(ctx context.Context, instrumentID int64) (Ticker, error) { var result Ticker params := make(map[string]any) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTicker, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutTicker, params, false, &result) } // GetInstrumentOrderbook returns the orderbooks for a specific instrument -func (c *COINUT) GetInstrumentOrderbook(ctx context.Context, instrumentID, limit int64) (*Orderbook, error) { +func (e *Exchange) GetInstrumentOrderbook(ctx context.Context, instrumentID, limit int64) (*Orderbook, error) { var result Orderbook params := make(map[string]any) params["inst_id"] = instrumentID @@ -92,26 +92,26 @@ func (c *COINUT) GetInstrumentOrderbook(ctx context.Context, instrumentID, limit params["top_n"] = limit } - return &result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrderbook, params, false, &result) + return &result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrderbook, params, false, &result) } // GetTrades returns trade information -func (c *COINUT) GetTrades(ctx context.Context, instrumentID int64) (Trades, error) { +func (e *Exchange) GetTrades(ctx context.Context, instrumentID int64) (Trades, error) { var result Trades params := make(map[string]any) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTrades, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutTrades, params, false, &result) } // GetUserBalance returns the full user balance -func (c *COINUT) GetUserBalance(ctx context.Context) (*UserBalance, error) { +func (e *Exchange) GetUserBalance(ctx context.Context) (*UserBalance, error) { var result *UserBalance - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutBalance, nil, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutBalance, nil, true, &result) } // NewOrder places a new order on the exchange -func (c *COINUT) NewOrder(ctx context.Context, instrumentID int64, quantity, price float64, buy bool, orderID uint32) (any, error) { +func (e *Exchange) NewOrder(ctx context.Context, instrumentID int64, quantity, price float64, buy bool, orderID uint32) (any, error) { var result any params := make(map[string]any) params["inst_id"] = instrumentID @@ -125,28 +125,28 @@ func (c *COINUT) NewOrder(ctx context.Context, instrumentID int64, quantity, pri } params["client_ord_id"] = orderID - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrder, params, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrder, params, true, &result) } // NewOrders places multiple orders on the exchange -func (c *COINUT) NewOrders(ctx context.Context, orders []Order) ([]OrdersBase, error) { +func (e *Exchange) NewOrders(ctx context.Context, orders []Order) ([]OrdersBase, error) { var result OrdersResponse params := make(map[string]any) params["orders"] = orders - return result.Data, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrders, params, true, &result.Data) + return result.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrders, params, true, &result.Data) } // GetOpenOrders returns a list of open order and relevant information -func (c *COINUT) GetOpenOrders(ctx context.Context, instrumentID int64) (GetOpenOrdersResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, instrumentID int64) (GetOpenOrdersResponse, error) { var result GetOpenOrdersResponse params := make(map[string]any) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersOpen, params, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersOpen, params, true, &result) } // CancelExistingOrder cancels a specific order and returns if it was actioned -func (c *COINUT) CancelExistingOrder(ctx context.Context, instrumentID, orderID int64) (bool, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, instrumentID, orderID int64) (bool, error) { var result GenericResponse params := make(map[string]any) type Request struct { @@ -162,7 +162,7 @@ func (c *COINUT) CancelExistingOrder(ctx context.Context, instrumentID, orderID entries := []Request{entry} params["entries"] = entries - err := c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) if err != nil { return false, err } @@ -170,18 +170,18 @@ func (c *COINUT) CancelExistingOrder(ctx context.Context, instrumentID, orderID } // CancelOrders cancels multiple orders -func (c *COINUT) CancelOrders(ctx context.Context, orders []CancelOrders) (CancelOrdersResponse, error) { +func (e *Exchange) CancelOrders(ctx context.Context, orders []CancelOrders) (CancelOrdersResponse, error) { var result CancelOrdersResponse params := make(map[string]any) var entries []CancelOrders entries = append(entries, orders...) params["entries"] = entries - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) } // GetTradeHistory returns trade history for a specific instrument. -func (c *COINUT) GetTradeHistory(ctx context.Context, instrumentID, start, limit int64) (TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, instrumentID, start, limit int64) (TradeHistory, error) { var result TradeHistory params := make(map[string]any) params["inst_id"] = instrumentID @@ -192,39 +192,39 @@ func (c *COINUT) GetTradeHistory(ctx context.Context, instrumentID, start, limit params["limit"] = limit } - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTradeHistory, params, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutTradeHistory, params, true, &result) } // GetIndexTicker returns the index ticker for an asset -func (c *COINUT) GetIndexTicker(ctx context.Context, asset string) (IndexTicker, error) { +func (e *Exchange) GetIndexTicker(ctx context.Context, asset string) (IndexTicker, error) { var result IndexTicker params := make(map[string]any) params["asset"] = asset - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutIndexTicker, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutIndexTicker, params, false, &result) } // GetDerivativeInstruments returns a list of derivative instruments -func (c *COINUT) GetDerivativeInstruments(ctx context.Context, secType string) (any, error) { +func (e *Exchange) GetDerivativeInstruments(ctx context.Context, secType string) (any, error) { var result any // TODO: Make this a concrete type params := make(map[string]any) params["sec_type"] = secType - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) } // GetOptionChain returns option chain -func (c *COINUT) GetOptionChain(ctx context.Context, asset, secType string) (OptionChainResponse, error) { +func (e *Exchange) GetOptionChain(ctx context.Context, asset, secType string) (OptionChainResponse, error) { var result OptionChainResponse params := make(map[string]any) params["asset"] = asset params["sec_type"] = secType - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOptionChain, params, false, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOptionChain, params, false, &result) } // GetPositionHistory returns position history -func (c *COINUT) GetPositionHistory(ctx context.Context, secType string, start, limit int) (PositionHistory, error) { +func (e *Exchange) GetPositionHistory(ctx context.Context, secType string, start, limit int) (PositionHistory, error) { var result PositionHistory params := make(map[string]any) params["sec_type"] = secType @@ -235,11 +235,11 @@ func (c *COINUT) GetPositionHistory(ctx context.Context, secType string, start, params["limit"] = limit } - return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionHistory, params, true, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionHistory, params, true, &result) } // GetOpenPositionsForInstrument returns all your current opened positions -func (c *COINUT) GetOpenPositionsForInstrument(ctx context.Context, instrumentID int) ([]OpenPosition, error) { +func (e *Exchange) GetOpenPositionsForInstrument(ctx context.Context, instrumentID int) ([]OpenPosition, error) { type Response struct { Positions []OpenPosition `json:"positions"` } @@ -248,12 +248,12 @@ func (c *COINUT) GetOpenPositionsForInstrument(ctx context.Context, instrumentID params["inst_id"] = instrumentID return result.Positions, - c.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionOpen, params, true, &result) + e.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionOpen, params, true, &result) } // SendHTTPRequest sends either an authenticated or unauthenticated HTTP request -func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiRequest string, params map[string]any, authenticated bool, result any) (err error) { - endpoint, err := c.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiRequest string, params map[string]any, authenticated bool, result any) (err error) { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -267,7 +267,7 @@ func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiReques requestType = request.AuthenticatedRequest } var rawMsg json.RawMessage - err = c.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { params["nonce"] = getNonce() params["request"] = apiRequest @@ -280,7 +280,7 @@ func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiReques headers := make(map[string]string) if authenticated { var creds *account.Credentials - creds, err = c.GetCredentials(ctx) + creds, err = e.GetCredentials(ctx) if err != nil { return nil, err } @@ -303,9 +303,9 @@ func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiReques Body: bytes.NewBuffer(payload), Result: &rawMsg, NonceEnabled: true, - Verbose: c.Verbose, - HTTPDebugging: c.HTTPDebugging, - HTTPRecording: c.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, requestType) if err != nil { @@ -322,18 +322,18 @@ func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiReques if authenticated { return fmt.Errorf("%w %v", request.ErrAuthRequestFailed, genResp.Status[0]) } - return fmt.Errorf("%s SendHTTPRequest error: %s", c.Name, genResp.Status[0]) + return fmt.Errorf("%s SendHTTPRequest error: %s", e.Name, genResp.Status[0]) } return json.Unmarshal(rawMsg, result) } // GetFee returns an estimate of fee based on type of transaction -func (c *COINUT) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - fee = c.calculateTradingFee(feeBuilder.Pair.Base, + fee = e.calculateTradingFee(feeBuilder.Pair.Base, feeBuilder.Pair.Quote, feeBuilder.PurchasePrice, feeBuilder.Amount, @@ -363,7 +363,7 @@ func getOfflineTradeFee(c currency.Pair, price, amount float64) float64 { return 0.002 * price * amount } -func (c *COINUT) calculateTradingFee(base, quote currency.Code, purchasePrice, amount float64, isMaker bool) float64 { +func (e *Exchange) calculateTradingFee(base, quote currency.Code, purchasePrice, amount float64, isMaker bool) float64 { var fee float64 switch { diff --git a/exchanges/coinut/coinut_test.go b/exchanges/coinut/coinut_test.go index 734e767f87b..1e3dd55737e 100644 --- a/exchanges/coinut/coinut_test.go +++ b/exchanges/coinut/coinut_test.go @@ -25,7 +25,7 @@ import ( ) var ( - c *COINUT + e *Exchange wsSetupRan bool ) @@ -37,18 +37,18 @@ const ( ) func TestMain(m *testing.M) { - c = new(COINUT) - if err := testexch.Setup(c); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Coinut Setup error: %s", err) } if apiKey != "" && clientID != "" { - c.API.AuthenticatedSupport = true - c.API.AuthenticatedWebsocketSupport = true - c.SetCredentials(apiKey, clientID, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, clientID, "", "", "", "") } - if err := c.SeedInstruments(context.Background()); err != nil { + if err := e.SeedInstruments(context.Background()); err != nil { log.Fatalf("Coinut SeedInstruments error: %s", err) } @@ -61,45 +61,45 @@ func setupWSTestAuth(t *testing.T) { return } - if !c.Websocket.IsEnabled() && !c.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(c) { + if !e.Websocket.IsEnabled() && !e.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } - if sharedtestvalues.AreAPICredentialsSet(c) { - c.Websocket.SetCanUseAuthenticatedEndpoints(true) + if sharedtestvalues.AreAPICredentialsSet(e) { + e.Websocket.SetCanUseAuthenticatedEndpoints(true) } var dialer gws.Dialer - err := c.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) if err != nil { t.Fatal(err) } - go c.wsReadData(t.Context()) - err = c.wsAuthenticate(t.Context()) + go e.wsReadData(t.Context()) + err = e.wsAuthenticate(t.Context()) if err != nil { t.Error(err) } wsSetupRan = true - _, err = c.WsGetInstruments(t.Context()) + _, err = e.WsGetInstruments(t.Context()) if err != nil { t.Error(err) } } func TestGetInstruments(t *testing.T) { - _, err := c.GetInstruments(t.Context()) + _, err := e.GetInstruments(t.Context()) if err != nil { t.Error("GetInstruments() error", err) } } func TestSeedInstruments(t *testing.T) { - err := c.SeedInstruments(t.Context()) + err := e.SeedInstruments(t.Context()) if err != nil { // No point checking the next condition t.Fatal(err) } - if len(c.instrumentMap.GetInstrumentIDs()) == 0 { + if len(e.instrumentMap.GetInstrumentIDs()) == 0 { t.Error("instrument map hasn't been seeded") } } @@ -116,7 +116,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := c.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } @@ -135,7 +135,7 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -143,35 +143,35 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -179,7 +179,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.EUR - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -187,7 +187,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.USD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -195,7 +195,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.SGD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -203,7 +203,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -211,7 +211,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.CAD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -219,7 +219,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.SGD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -227,7 +227,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.CAD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } } @@ -235,7 +235,7 @@ func TestGetFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.WithdrawCryptoViaWebsiteOnlyText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText - withdrawPermissions := c.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -248,8 +248,8 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, Side: order.AnySide, } - _, err := c.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) } } @@ -264,8 +264,8 @@ func TestGetOrderHistoryWrapper(t *testing.T) { Side: order.AnySide, } - _, err := c.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) } } @@ -275,10 +275,10 @@ func TestGetOrderHistoryWrapper(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: c.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.BTC, Quote: currency.USD, @@ -290,17 +290,17 @@ func TestSubmitOrder(t *testing.T) { ClientID: "123", AssetType: asset.Spot, } - response, err := c.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(c) && (err != nil || response.Status != order.New) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewBTCUSD() orderCancellation := &order.Cancel{ @@ -310,18 +310,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := c.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -331,12 +331,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := c.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(c) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(c) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } @@ -348,12 +348,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if apiKey != "" || clientID != "" { - _, err := c.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err != nil { t.Error("GetAccountInfo() error", err) } } else { - _, err := c.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -362,9 +362,9 @@ func TestGetAccountInfo(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - _, err := c.ModifyOrder(t.Context(), + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") @@ -373,10 +373,10 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: c.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -385,7 +385,7 @@ func TestWithdraw(t *testing.T) { }, } - _, err := c.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected 'Not supported', received %v", err) @@ -394,10 +394,10 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := c.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -405,10 +405,10 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, c, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := c.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -416,7 +416,7 @@ func TestWithdrawInternationalBank(t *testing.T) { } func TestGetDepositAddress(t *testing.T) { - _, err := c.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress() function unsupported cannot be nil") } @@ -425,7 +425,7 @@ func TestGetDepositAddress(t *testing.T) { // TestWsAuthGetAccountBalance dials websocket, retrieves account balance func TestWsAuthGetAccountBalance(t *testing.T) { setupWSTestAuth(t) - if _, err := c.wsGetAccountBalance(t.Context()); err != nil { + if _, err := e.wsGetAccountBalance(t.Context()); err != nil { t.Error(err) } } @@ -443,7 +443,7 @@ func TestWsAuthSubmitOrder(t *testing.T) { Price: 1, Side: order.Buy, } - if _, err := c.wsSubmitOrder(t.Context(), &ord); err != nil { + if _, err := e.wsSubmitOrder(t.Context(), &ord); err != nil { t.Error(err) } } @@ -468,7 +468,7 @@ func TestWsAuthSubmitOrders(t *testing.T) { Price: 2, Side: order.Buy, } - _, err := c.wsSubmitOrders(t.Context(), []WsSubmitOrderParameters{order1, order2}) + _, err := e.wsSubmitOrders(t.Context(), []WsSubmitOrderParameters{order1, order2}) if err != nil { t.Error(err) } @@ -489,7 +489,7 @@ func TestWsAuthCancelOrders(t *testing.T) { Currency: currency.NewPair(currency.LTC, currency.BTC), OrderID: 2, } - resp, err := c.wsCancelOrders(t.Context(), []WsCancelOrderParameters{ord, order2}) + resp, err := e.wsCancelOrders(t.Context(), []WsCancelOrderParameters{ord, order2}) if err != nil { t.Error(err) } @@ -508,7 +508,7 @@ func TestWsAuthCancelOrdersWrapper(t *testing.T) { orderDetails := order.Cancel{ Pair: currency.NewPair(currency.LTC, currency.BTC), } - _, err := c.CancelAllOrders(t.Context(), &orderDetails) + _, err := e.CancelAllOrders(t.Context(), &orderDetails) if err != nil { t.Error(err) } @@ -524,7 +524,7 @@ func TestWsAuthCancelOrder(t *testing.T) { Currency: currency.NewPair(currency.LTC, currency.BTC), OrderID: 1, } - resp, err := c.wsCancelOrder(t.Context(), ord) + resp, err := e.wsCancelOrder(t.Context(), ord) if err != nil { t.Error(err) } @@ -536,7 +536,7 @@ func TestWsAuthCancelOrder(t *testing.T) { // TestWsAuthGetOpenOrders dials websocket, retrieves open orders func TestWsAuthGetOpenOrders(t *testing.T) { setupWSTestAuth(t) - _, err := c.wsGetOpenOrders(t.Context(), currency.NewPair(currency.LTC, currency.BTC).String()) + _, err := e.wsGetOpenOrders(t.Context(), currency.NewPair(currency.LTC, currency.BTC).String()) if err != nil { t.Error(err) } @@ -636,7 +636,7 @@ func TestWsOrderbook(t *testing.T) { "reply": "inst_order_book", "status": [ "OK" ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -650,7 +650,7 @@ func TestWsOrderbook(t *testing.T) { "side": "BUY", "trans_id": 169384 }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -668,7 +668,7 @@ func TestWsTicker(t *testing.T) { "volume": "0.07650000", "volume24": "56.07650000" }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -700,11 +700,11 @@ func TestWsGetInstruments(t *testing.T) { "OK" ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } - if c.instrumentMap.LookupID("ETHBTC") != 2 { + if e.instrumentMap.LookupID("ETHBTC") != 2 { t.Error("Expected id to load") } } @@ -747,7 +747,7 @@ func TestWsTrades(t *testing.T) { "trans_id": 169502 }] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -760,7 +760,7 @@ func TestWsTrades(t *testing.T) { "timestamp": 0, "trans_id": 169478 }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -792,7 +792,7 @@ func TestWsLogin(t *testing.T) { }`) ctx := account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "b46e658f-d4c4-433c-b032-093423b1aaa4", ClientID: "dummy"}) - err := c.wsHandleData(ctx, pressXToJSON) + err := e.wsHandleData(ctx, pressXToJSON) if err != nil { t.Error(err) } @@ -816,7 +816,7 @@ func TestWsAccountBalance(t *testing.T) { "reply": "user_balance", "trans_id": 15159032 }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -838,7 +838,7 @@ func TestWsOrder(t *testing.T) { "side":"SELL", "trans_id":127303 }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -868,7 +868,7 @@ func TestWsOrder(t *testing.T) { "timestamp": 1482903034617491, "trans_id": 20859252 }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -892,7 +892,7 @@ func TestWsOrder(t *testing.T) { "side": "BUY", "trans_id": 3282993 }`) - err = c.wsHandleData(t.Context(), pressXToJSON) + err = e.wsHandleData(t.Context(), pressXToJSON) if err == nil { t.Error("Expected not enough balance error") } @@ -933,7 +933,7 @@ func TestWsOrders(t *testing.T) { "trans_id": 15155497 } ]`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -969,7 +969,7 @@ func TestWsOpenOrders(t *testing.T) { } ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -985,7 +985,7 @@ func TestWsCancelOrder(t *testing.T) { "OK" ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -1014,7 +1014,7 @@ func TestWsCancelOrders(t *testing.T) { ], "trans_id": 15166063 }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -1071,7 +1071,7 @@ func TestWsOrderHistory(t *testing.T) { } ] }`) - err := c.wsHandleData(t.Context(), pressXToJSON) + err := e.wsHandleData(t.Context(), pressXToJSON) if err != nil { t.Error(err) } @@ -1104,7 +1104,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetRecentTrades(t.Context(), currencyPair, asset.Spot) + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1116,7 +1116,7 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetHistoricTrades(t.Context(), + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) @@ -1125,8 +1125,8 @@ func TestGetHistoricTrades(t *testing.T) { func TestCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, c, canManipulateRealOrders) - _, err := c.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1234", AssetType: asset.Spot, @@ -1140,12 +1140,12 @@ func TestCancelBatchOrders(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, c) - for _, a := range c.GetAssetTypes(false) { - pairs, err := c.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := c.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/coinut/coinut_websocket.go b/exchanges/coinut/coinut_websocket.go index 5dce632bfc6..34f637fb1c7 100644 --- a/exchanges/coinut/coinut_websocket.go +++ b/exchanges/coinut/coinut_websocket.go @@ -40,31 +40,31 @@ var channels map[string]chan []byte // wss://wsapi-eu.coinut.com // WsConnect initiates a websocket connection -func (c *COINUT) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !c.Websocket.IsEnabled() || !c.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := c.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - c.Websocket.Wg.Add(1) - go c.wsReadData(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) - if !c.instrumentMap.IsLoaded() { - _, err = c.WsGetInstruments(ctx) + if !e.instrumentMap.IsLoaded() { + _, err = e.WsGetInstruments(ctx) if err != nil { return err } } - if c.IsWebsocketAuthenticationSupported() { - if err = c.wsAuthenticate(ctx); err != nil { - c.Websocket.SetCanUseAuthenticatedEndpoints(false) - log.Errorln(log.WebsocketMgr, c.Name+" "+err.Error()) + if e.IsWebsocketAuthenticationSupported() { + if err = e.wsAuthenticate(ctx); err != nil { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorln(log.WebsocketMgr, e.Name+" "+err.Error()) } } @@ -76,11 +76,11 @@ func (c *COINUT) WsConnect() error { } // wsReadData receives and passes on websocket messages for processing -func (c *COINUT) wsReadData(ctx context.Context) { - defer c.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := c.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } @@ -89,42 +89,42 @@ func (c *COINUT) wsReadData(ctx context.Context) { var incoming []wsResponse err := json.Unmarshal(resp.Raw, &incoming) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err continue } for i := range incoming { if incoming[i].Nonce > 0 { - if c.Websocket.Match.IncomingWithData(incoming[i].Nonce, resp.Raw) { + if e.Websocket.Match.IncomingWithData(incoming[i].Nonce, resp.Raw) { break } } var individualJSON []byte individualJSON, err = json.Marshal(incoming[i]) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err continue } - err = c.wsHandleData(ctx, individualJSON) + err = e.wsHandleData(ctx, individualJSON) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } else { var incoming wsResponse err := json.Unmarshal(resp.Raw, &incoming) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err continue } - err = c.wsHandleData(ctx, resp.Raw) + err = e.wsHandleData(ctx, resp.Raw) if err != nil { - c.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(_ context.Context, respRaw []byte) error { if strings.HasPrefix(string(respRaw), "[") { var orders []wsOrderContainer err := json.Unmarshal(respRaw, &orders) @@ -132,11 +132,11 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { return err } for i := range orders { - o, err2 := c.parseOrderContainer(&orders[i]) + o, err2 := e.parseOrderContainer(&orders[i]) if err2 != nil { return err2 } - c.Websocket.DataHandler <- o + e.Websocket.DataHandler <- o } return nil } @@ -146,11 +146,11 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - if c.Websocket.Match.IncomingWithData(incoming.Nonce, respRaw) { + if e.Websocket.Match.IncomingWithData(incoming.Nonce, respRaw) { return nil } - format, err := c.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -176,8 +176,8 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - c.Websocket.DataHandler <- &order.Detail{ - Exchange: c.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: strconv.FormatInt(cancel.OrderID, 10), Status: order.Cancelled, LastUpdated: time.Now(), @@ -190,8 +190,8 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { return err } for i := range cancels.Results { - c.Websocket.DataHandler <- &order.Detail{ - Exchange: c.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: strconv.FormatInt(cancels.Results[i].OrderID, 10), Status: order.Cancelled, LastUpdated: time.Now(), @@ -212,7 +212,7 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { } for k, v := range instList.Spot { for _, v2 := range v { - c.instrumentMap.Seed(k, v2.InstrumentID) + e.instrumentMap.Seed(k, v2.InstrumentID) } } case "inst_tick": @@ -221,11 +221,11 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - pairs, err := c.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - currencyPair := c.instrumentMap.LookupInstrument(wsTicker.InstID) + currencyPair := e.instrumentMap.LookupInstrument(wsTicker.InstID) p, err := currency.NewPairFromFormattedPairs(currencyPair, pairs, format) @@ -233,8 +233,8 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { return err } - c.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: c.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Volume: wsTicker.Volume24, QuoteVolume: wsTicker.Volume24Quote, Bid: wsTicker.HighestBuy, @@ -252,7 +252,7 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - err = c.WsProcessOrderbookSnapshot(&orderbookSnapshot) + err = e.WsProcessOrderbookSnapshot(&orderbookSnapshot) if err != nil { return err } @@ -262,12 +262,12 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - err = c.WsProcessOrderbookUpdate(&orderbookUpdate) + err = e.WsProcessOrderbookUpdate(&orderbookUpdate) if err != nil { return err } case "inst_trade": - if !c.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } var tradeSnap WsTradeSnapshot @@ -277,11 +277,11 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { } var trades []trade.Data for i := range tradeSnap.Trades { - pairs, err := c.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - currencyPair := c.instrumentMap.LookupInstrument(tradeSnap.InstrumentID) + currencyPair := e.instrumentMap.LookupInstrument(tradeSnap.InstrumentID) p, err := currency.NewPairFromFormattedPairs(currencyPair, pairs, format) @@ -291,8 +291,8 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { tSide, err := order.StringToOrderSide(tradeSnap.Trades[i].Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, Err: err, } } @@ -301,7 +301,7 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { Timestamp: tradeSnap.Trades[i].Timestamp.Time(), CurrencyPair: p, AssetType: asset.Spot, - Exchange: c.Name, + Exchange: e.Name, Price: tradeSnap.Trades[i].Price, Side: tSide, Amount: tradeSnap.Trades[i].Quantity, @@ -310,7 +310,7 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { } return trade.AddTradesToBuffer(trades...) case "inst_trade_update": - if !c.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } var tradeUpdate WsTradeUpdate @@ -319,11 +319,11 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { return err } - pairs, err := c.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - currencyPair := c.instrumentMap.LookupInstrument(tradeUpdate.InstID) + currencyPair := e.instrumentMap.LookupInstrument(tradeUpdate.InstID) p, err := currency.NewPairFromFormattedPairs(currencyPair, pairs, format) @@ -333,8 +333,8 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { tSide, err := order.StringToOrderSide(tradeUpdate.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, Err: err, } } @@ -343,7 +343,7 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { Timestamp: tradeUpdate.Timestamp.Time(), CurrencyPair: p, AssetType: asset.Spot, - Exchange: c.Name, + Exchange: e.Name, Price: tradeUpdate.Price, Side: tSide, Amount: tradeUpdate.Quantity, @@ -355,13 +355,13 @@ func (c *COINUT) wsHandleData(_ context.Context, respRaw []byte) error { if err != nil { return err } - o, err := c.parseOrderContainer(&orderContainer) + o, err := e.parseOrderContainer(&orderContainer) if err != nil { return err } - c.Websocket.DataHandler <- o + e.Websocket.DataHandler <- o default: - c.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: c.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } return nil @@ -383,7 +383,7 @@ func stringToOrderStatus(status string, quantity float64) (order.Status, error) } } -func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detail, error) { +func (e *Exchange) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detail, error) { var oSide order.Side var oStatus order.Status var err error @@ -391,8 +391,8 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai if oContainer.Side != "" { oSide, err = order.StringToOrderSide(oContainer.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -400,8 +400,8 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai } else if oContainer.Order.Side != "" { oSide, err = order.StringToOrderSide(oContainer.Order.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -410,17 +410,17 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai oStatus, err = stringToOrderStatus(oContainer.Reply, oContainer.OpenQuantity) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } } if oContainer.Status[0] != "OK" { - return nil, fmt.Errorf("%s - Order rejected: %v", c.Name, oContainer.Status) + return nil, fmt.Errorf("%s - Order rejected: %v", e.Name, oContainer.Status) } if len(oContainer.Reasons) > 0 { - return nil, fmt.Errorf("%s - Order rejected: %v", c.Name, oContainer.Reasons) + return nil, fmt.Errorf("%s - Order rejected: %v", e.Name, oContainer.Reasons) } o := &order.Detail{ @@ -428,7 +428,7 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai Amount: oContainer.Quantity, ExecutedAmount: oContainer.FillQuantity, RemainingAmount: oContainer.OpenQuantity, - Exchange: c.Name, + Exchange: e.Name, OrderID: orderID, Side: oSide, Status: oStatus, @@ -438,8 +438,8 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai if oContainer.Reply == "order_filled" { o.Side, err = order.StringToOrderSide(oContainer.Order.Side) if err != nil { - c.Websocket.DataHandler <- order.ClassificationError{ - Exchange: c.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -448,7 +448,7 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai o.Amount = oContainer.Order.Quantity o.OrderID = strconv.FormatInt(oContainer.Order.OrderID, 10) o.LastUpdated = oContainer.Timestamp.Time() - o.Pair, o.AssetType, err = c.GetRequestFormattedPairAndAssetType(c.instrumentMap.LookupInstrument(oContainer.Order.InstrumentID)) + o.Pair, o.AssetType, err = e.GetRequestFormattedPairAndAssetType(e.instrumentMap.LookupInstrument(oContainer.Order.InstrumentID)) if err != nil { return nil, err } @@ -456,14 +456,14 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai { Price: oContainer.FillPrice, Amount: oContainer.FillQuantity, - Exchange: c.Name, + Exchange: e.Name, TID: strconv.FormatInt(oContainer.TransactionID, 10), Side: oSide, Timestamp: oContainer.Timestamp.Time(), }, } } else { - o.Pair, o.AssetType, err = c.GetRequestFormattedPairAndAssetType(c.instrumentMap.LookupInstrument(oContainer.InstrumentID)) + o.Pair, o.AssetType, err = e.GetRequestFormattedPairAndAssetType(e.instrumentMap.LookupInstrument(oContainer.InstrumentID)) if err != nil { return nil, err } @@ -472,14 +472,14 @@ func (c *COINUT) parseOrderContainer(oContainer *wsOrderContainer) (*order.Detai } // WsGetInstruments fetches instrument list and propagates a local cache -func (c *COINUT) WsGetInstruments(ctx context.Context) (Instruments, error) { +func (e *Exchange) WsGetInstruments(ctx context.Context) (Instruments, error) { var list Instruments req := wsRequest{ Request: "inst_list", SecurityType: strings.ToUpper(asset.Spot.String()), Nonce: getNonce(), } - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Nonce, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Nonce, req) if err != nil { return list, err } @@ -488,16 +488,16 @@ func (c *COINUT) WsGetInstruments(ctx context.Context) (Instruments, error) { return list, err } for curr, data := range list.Instruments { - c.instrumentMap.Seed(curr, data[0].InstrumentID) + e.instrumentMap.Seed(curr, data[0].InstrumentID) } - if len(c.instrumentMap.GetInstrumentIDs()) == 0 { + if len(e.instrumentMap.GetInstrumentIDs()) == 0 { return list, errors.New("instrument list failed to populate") } return list, nil } // WsProcessOrderbookSnapshot processes the orderbook snapshot -func (c *COINUT) WsProcessOrderbookSnapshot(ob *WsOrderbookSnapshot) error { +func (e *Exchange) WsProcessOrderbookSnapshot(ob *WsOrderbookSnapshot) error { bids := make([]orderbook.Level, len(ob.Buy)) for i := range ob.Buy { bids[i] = orderbook.Level{ @@ -517,20 +517,20 @@ func (c *COINUT) WsProcessOrderbookSnapshot(ob *WsOrderbookSnapshot) error { var newOrderBook orderbook.Book newOrderBook.Asks = asks newOrderBook.Bids = bids - newOrderBook.ValidateOrderbook = c.ValidateOrderbook + newOrderBook.ValidateOrderbook = e.ValidateOrderbook - pairs, err := c.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := c.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } newOrderBook.Pair, err = currency.NewPairFromFormattedPairs( - c.instrumentMap.LookupInstrument(ob.InstID), + e.instrumentMap.LookupInstrument(ob.InstID), pairs, format) if err != nil { @@ -538,26 +538,26 @@ func (c *COINUT) WsProcessOrderbookSnapshot(ob *WsOrderbookSnapshot) error { } newOrderBook.Asset = asset.Spot - newOrderBook.Exchange = c.Name + newOrderBook.Exchange = e.Name newOrderBook.LastUpdated = time.Now() // No time sent - return c.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } // WsProcessOrderbookUpdate process an orderbook update -func (c *COINUT) WsProcessOrderbookUpdate(update *WsOrderbookUpdate) error { - pairs, err := c.GetEnabledPairs(asset.Spot) +func (e *Exchange) WsProcessOrderbookUpdate(update *WsOrderbookUpdate) error { + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := c.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } p, err := currency.NewPairFromFormattedPairs( - c.instrumentMap.LookupInstrument(update.InstID), + e.instrumentMap.LookupInstrument(update.InstID), pairs, format) if err != nil { @@ -575,14 +575,14 @@ func (c *COINUT) WsProcessOrderbookUpdate(update *WsOrderbookUpdate) error { } else { bufferUpdate.Asks = []orderbook.Level{{Price: update.Price, Amount: update.Volume}} } - return c.Websocket.Orderbook.Update(bufferUpdate) + return e.Websocket.Orderbook.Update(bufferUpdate) } // GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions() -func (c *COINUT) GenerateDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateDefaultSubscriptions() (subscription.List, error) { channels := []string{"inst_tick", "inst_order_book", "inst_trade"} var subscriptions subscription.List - enabledPairs, err := c.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } @@ -599,14 +599,14 @@ func (c *COINUT) GenerateDefaultSubscriptions() (subscription.List, error) { } // Subscribe sends a websocket message to receive data from the channel -func (c *COINUT) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() var errs error for _, s := range subs { if len(s.Pairs) != 1 { return subscription.ErrNotSinglePair } - fPair, err := c.FormatExchangeCurrency(s.Pairs[0], asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pairs[0], asset.Spot) if err != nil { errs = common.AppendError(errs, err) continue @@ -614,13 +614,13 @@ func (c *COINUT) Subscribe(subs subscription.List) error { subscribe := wsRequest{ Request: s.Channel, - InstrumentID: c.instrumentMap.LookupID(fPair.String()), + InstrumentID: e.instrumentMap.LookupID(fPair.String()), Subscribe: true, Nonce: getNonce(), } - err = c.Websocket.Conn.SendJSONMessage(ctx, request.Unset, subscribe) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, subscribe) if err == nil { - err = c.Websocket.AddSuccessfulSubscriptions(c.Websocket.Conn, s) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) } if err != nil { errs = common.AppendError(errs, err) @@ -630,14 +630,14 @@ func (c *COINUT) Subscribe(subs subscription.List) error { } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (c *COINUT) Unsubscribe(channelToUnsubscribe subscription.List) error { +func (e *Exchange) Unsubscribe(channelToUnsubscribe subscription.List) error { ctx := context.TODO() var errs error for _, s := range channelToUnsubscribe { if len(s.Pairs) != 1 { return subscription.ErrNotSinglePair } - fPair, err := c.FormatExchangeCurrency(s.Pairs[0], asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pairs[0], asset.Spot) if err != nil { errs = common.AppendError(errs, err) continue @@ -645,11 +645,11 @@ func (c *COINUT) Unsubscribe(channelToUnsubscribe subscription.List) error { subscribe := wsRequest{ Request: s.Channel, - InstrumentID: c.instrumentMap.LookupID(fPair.String()), + InstrumentID: e.instrumentMap.LookupID(fPair.String()), Subscribe: false, Nonce: getNonce(), } - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, subscribe.Nonce, subscribe) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, subscribe.Nonce, subscribe) if err != nil { errs = common.AppendError(errs, err) continue @@ -662,9 +662,9 @@ func (c *COINUT) Unsubscribe(channelToUnsubscribe subscription.List) error { case !ok: err = common.GetTypeAssertError("[]any", response["status"]) case len(val) == 0, val[0] != "OK": - err = common.AppendError(errs, fmt.Errorf("%v unsubscribe failed for channel %v", c.Name, s.Channel)) + err = common.AppendError(errs, fmt.Errorf("%v unsubscribe failed for channel %v", e.Name, s.Channel)) default: - err = c.Websocket.RemoveSubscriptions(c.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } } if err != nil { @@ -674,8 +674,8 @@ func (c *COINUT) Unsubscribe(channelToUnsubscribe subscription.List) error { return errs } -func (c *COINUT) wsAuthenticate(ctx context.Context) error { - creds, err := c.GetCredentials(ctx) +func (e *Exchange) wsAuthenticate(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -692,7 +692,7 @@ func (c *COINUT) wsAuthenticate(ctx context.Context) error { } r.Hmac = hex.EncodeToString(hmac) - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, r.Nonce, r) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, r.Nonce, r) if err != nil { return err } @@ -702,20 +702,20 @@ func (c *COINUT) wsAuthenticate(ctx context.Context) error { return errors.New("failed to authenticate") } - c.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) return nil } -func (c *COINUT) wsGetAccountBalance(ctx context.Context) (*UserBalance, error) { - if !c.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authorised to submit order", c.Name) +func (e *Exchange) wsGetAccountBalance(ctx context.Context) (*UserBalance, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authorised to submit order", e.Name) } accBalance := wsRequest{ Request: "user_balance", Nonce: getNonce(), } - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, accBalance.Nonce, accBalance) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, accBalance.Nonce, accBalance) if err != nil { return nil, err } @@ -725,17 +725,17 @@ func (c *COINUT) wsGetAccountBalance(ctx context.Context) (*UserBalance, error) return nil, err } if response.Status[0] != "OK" { - return &response, fmt.Errorf("%v get account balance failed", c.Name) + return &response, fmt.Errorf("%v get account balance failed", e.Name) } return &response, nil } -func (c *COINUT) wsSubmitOrder(ctx context.Context, o *WsSubmitOrderParameters) (*order.Detail, error) { - if !c.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authorised to submit order", c.Name) +func (e *Exchange) wsSubmitOrder(ctx context.Context, o *WsSubmitOrderParameters) (*order.Detail, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authorised to submit order", e.Name) } - curr, err := c.FormatExchangeCurrency(o.Currency, asset.Spot) + curr, err := e.FormatExchangeCurrency(o.Currency, asset.Spot) if err != nil { return nil, err } @@ -743,7 +743,7 @@ func (c *COINUT) wsSubmitOrder(ctx context.Context, o *WsSubmitOrderParameters) var orderSubmissionRequest WsSubmitOrderRequest orderSubmissionRequest.Request = "new_order" orderSubmissionRequest.Nonce = getNonce() - orderSubmissionRequest.InstrumentID = c.instrumentMap.LookupID(curr.String()) + orderSubmissionRequest.InstrumentID = e.instrumentMap.LookupID(curr.String()) orderSubmissionRequest.Quantity = o.Amount orderSubmissionRequest.Price = o.Price orderSubmissionRequest.Side = o.Side.String() @@ -751,7 +751,7 @@ func (c *COINUT) wsSubmitOrder(ctx context.Context, o *WsSubmitOrderParameters) if o.OrderID > 0 { orderSubmissionRequest.OrderID = o.OrderID } - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, orderSubmissionRequest.Nonce, orderSubmissionRequest) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, orderSubmissionRequest.Nonce, orderSubmissionRequest) if err != nil { return nil, err } @@ -761,23 +761,23 @@ func (c *COINUT) wsSubmitOrder(ctx context.Context, o *WsSubmitOrderParameters) return nil, err } var ord *order.Detail - ord, err = c.parseOrderContainer(&incoming) + ord, err = e.parseOrderContainer(&incoming) if err != nil { return nil, err } return ord, nil } -func (c *COINUT) wsSubmitOrders(ctx context.Context, orders []WsSubmitOrderParameters) ([]order.Detail, []error) { +func (e *Exchange) wsSubmitOrders(ctx context.Context, orders []WsSubmitOrderParameters) ([]order.Detail, []error) { var errs []error - if !c.Websocket.CanUseAuthenticatedEndpoints() { + if !e.Websocket.CanUseAuthenticatedEndpoints() { errs = append(errs, fmt.Errorf("%v not authorised to submit orders", - c.Name)) + e.Name)) return nil, errs } orderRequest := WsSubmitOrdersRequest{} for i := range orders { - curr, err := c.FormatExchangeCurrency(orders[i].Currency, asset.Spot) + curr, err := e.FormatExchangeCurrency(orders[i].Currency, asset.Spot) if err != nil { return nil, []error{err} } @@ -787,14 +787,14 @@ func (c *COINUT) wsSubmitOrders(ctx context.Context, orders []WsSubmitOrderParam Quantity: orders[i].Amount, Price: orders[i].Price, Side: orders[i].Side.String(), - InstrumentID: c.instrumentMap.LookupID(curr.String()), + InstrumentID: e.instrumentMap.LookupID(curr.String()), ClientOrderID: i + 1, }) } orderRequest.Nonce = getNonce() orderRequest.Request = "new_orders" - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, orderRequest.Nonce, orderRequest) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, orderRequest.Nonce, orderRequest) if err != nil { errs = append(errs, err) return nil, errs @@ -808,7 +808,7 @@ func (c *COINUT) wsSubmitOrders(ctx context.Context, orders []WsSubmitOrderParam ordersResponse := make([]order.Detail, 0, len(incoming)) for i := range incoming { - o, err := c.parseOrderContainer(&incoming[i]) + o, err := e.parseOrderContainer(&incoming[i]) if err != nil { errs = append(errs, err) continue @@ -819,18 +819,18 @@ func (c *COINUT) wsSubmitOrders(ctx context.Context, orders []WsSubmitOrderParam return ordersResponse, errs } -func (c *COINUT) wsGetOpenOrders(ctx context.Context, curr string) (*WsUserOpenOrdersResponse, error) { +func (e *Exchange) wsGetOpenOrders(ctx context.Context, curr string) (*WsUserOpenOrdersResponse, error) { var response *WsUserOpenOrdersResponse - if !c.Websocket.CanUseAuthenticatedEndpoints() { + if !e.Websocket.CanUseAuthenticatedEndpoints() { return response, fmt.Errorf("%v not authorised to get open orders", - c.Name) + e.Name) } var openOrdersRequest WsGetOpenOrdersRequest openOrdersRequest.Request = "user_open_orders" openOrdersRequest.Nonce = getNonce() - openOrdersRequest.InstrumentID = c.instrumentMap.LookupID(curr) + openOrdersRequest.InstrumentID = e.instrumentMap.LookupID(curr) - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, openOrdersRequest.Nonce, openOrdersRequest) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, openOrdersRequest.Nonce, openOrdersRequest) if err != nil { return response, err } @@ -840,30 +840,30 @@ func (c *COINUT) wsGetOpenOrders(ctx context.Context, curr string) (*WsUserOpenO } if response.Status[0] != "OK" { return response, fmt.Errorf("%v get open orders failed for currency %v", - c.Name, + e.Name, curr) } return response, nil } -func (c *COINUT) wsCancelOrder(ctx context.Context, cancellation *WsCancelOrderParameters) (*CancelOrdersResponse, error) { +func (e *Exchange) wsCancelOrder(ctx context.Context, cancellation *WsCancelOrderParameters) (*CancelOrdersResponse, error) { var response *CancelOrdersResponse - if !c.Websocket.CanUseAuthenticatedEndpoints() { - return response, fmt.Errorf("%v not authorised to cancel order", c.Name) + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return response, fmt.Errorf("%v not authorised to cancel order", e.Name) } - curr, err := c.FormatExchangeCurrency(cancellation.Currency, asset.Spot) + curr, err := e.FormatExchangeCurrency(cancellation.Currency, asset.Spot) if err != nil { return nil, err } var cancellationRequest WsCancelOrderRequest cancellationRequest.Request = "cancel_order" - cancellationRequest.InstrumentID = c.instrumentMap.LookupID(curr.String()) + cancellationRequest.InstrumentID = e.instrumentMap.LookupID(curr.String()) cancellationRequest.OrderID = cancellation.OrderID cancellationRequest.Nonce = getNonce() - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, cancellationRequest.Nonce, cancellationRequest) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, cancellationRequest.Nonce, cancellationRequest) if err != nil { return response, err } @@ -873,7 +873,7 @@ func (c *COINUT) wsCancelOrder(ctx context.Context, cancellation *WsCancelOrderP } if response.Status[0] != "OK" { return response, fmt.Errorf("%v order cancellation failed for currency %v and orderID %v, message %v", - c.Name, + e.Name, cancellation.Currency, cancellation.OrderID, response.Status[0]) @@ -881,30 +881,30 @@ func (c *COINUT) wsCancelOrder(ctx context.Context, cancellation *WsCancelOrderP return response, nil } -func (c *COINUT) wsCancelOrders(ctx context.Context, cancellations []WsCancelOrderParameters) (*CancelOrdersResponse, error) { +func (e *Exchange) wsCancelOrders(ctx context.Context, cancellations []WsCancelOrderParameters) (*CancelOrdersResponse, error) { var err error var response *CancelOrdersResponse - if !c.Websocket.CanUseAuthenticatedEndpoints() { + if !e.Websocket.CanUseAuthenticatedEndpoints() { return nil, err } var cancelOrderRequest WsCancelOrdersRequest for i := range cancellations { var curr currency.Pair - curr, err = c.FormatExchangeCurrency(cancellations[i].Currency, + curr, err = e.FormatExchangeCurrency(cancellations[i].Currency, asset.Spot) if err != nil { return nil, err } cancelOrderRequest.Entries = append(cancelOrderRequest.Entries, WsCancelOrdersRequestEntry{ - InstID: c.instrumentMap.LookupID(curr.String()), + InstID: e.instrumentMap.LookupID(curr.String()), OrderID: cancellations[i].OrderID, }) } cancelOrderRequest.Request = "cancel_orders" cancelOrderRequest.Nonce = getNonce() - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, cancelOrderRequest.Nonce, cancelOrderRequest) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, cancelOrderRequest.Nonce, cancelOrderRequest) if err != nil { return response, err } @@ -915,26 +915,26 @@ func (c *COINUT) wsCancelOrders(ctx context.Context, cancellations []WsCancelOrd return response, err } -func (c *COINUT) wsGetTradeHistory(ctx context.Context, p currency.Pair, start, limit int64) (*WsTradeHistoryResponse, error) { +func (e *Exchange) wsGetTradeHistory(ctx context.Context, p currency.Pair, start, limit int64) (*WsTradeHistoryResponse, error) { var response *WsTradeHistoryResponse - if !c.Websocket.CanUseAuthenticatedEndpoints() { + if !e.Websocket.CanUseAuthenticatedEndpoints() { return response, fmt.Errorf("%v not authorised to get trade history", - c.Name) + e.Name) } - curr, err := c.FormatExchangeCurrency(p, asset.Spot) + curr, err := e.FormatExchangeCurrency(p, asset.Spot) if err != nil { return nil, err } var req WsTradeHistoryRequest req.Request = "trade_history" - req.InstID = c.instrumentMap.LookupID(curr.String()) + req.InstID = e.instrumentMap.LookupID(curr.String()) req.Nonce = getNonce() req.Start = start req.Limit = limit - resp, err := c.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Nonce, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.Nonce, req) if err != nil { return response, err } @@ -943,7 +943,7 @@ func (c *COINUT) wsGetTradeHistory(ctx context.Context, p currency.Pair, start, return response, err } if response.Status[0] != "OK" { - return response, fmt.Errorf("%v get trade history failed for %v", c.Name, req) + return response, fmt.Errorf("%v get trade history failed for %v", e.Name, req) } return response, nil } diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index e55de2dcee8..2a0ef2ae946 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -32,21 +32,21 @@ import ( ) // SetDefaults sets current default values -func (c *COINUT) SetDefaults() { - c.Name = "COINUT" - c.Enabled = true - c.Verbose = true - c.API.CredentialsValidator.RequiresKey = true - c.API.CredentialsValidator.RequiresClientID = true +func (e *Exchange) SetDefaults() { + e.Name = "COINUT" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresClientID = true requestFmt := ¤cy.PairFormat{Uppercase: true} configFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter} - err := c.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - c.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -91,54 +91,54 @@ func (c *COINUT) SetDefaults() { }, } - c.Requester, err = request.New(c.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) if err != nil { log.Errorln(log.ExchangeSys, err) } - c.API.Endpoints = c.NewEndpoints() - err = c.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: coinutAPIURL, exchange.WebsocketSpot: coinutWebsocketURL, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - c.Websocket = websocket.NewManager() - c.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - c.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - c.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets the current exchange configuration -func (c *COINUT) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - c.SetEnabled(false) + e.SetEnabled(false) return nil } - err = c.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := c.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = c.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: coinutWebsocketURL, RunningURL: wsRunningURL, - Connector: c.WsConnect, - Subscriber: c.Subscribe, - Unsubscriber: c.Unsubscribe, - GenerateSubscriptions: c.GenerateDefaultSubscriptions, - Features: &c.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.GenerateDefaultSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, @@ -148,7 +148,7 @@ func (c *COINUT) Setup(exch *config.Exchange) error { return err } - return c.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, RateLimit: request.NewWeightedRateLimitByDuration(33 * time.Millisecond), @@ -156,13 +156,13 @@ func (c *COINUT) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (c *COINUT) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { var resp Instruments var err error - if c.Websocket.IsConnected() { - resp, err = c.WsGetInstruments(ctx) + if e.Websocket.IsConnected() { + resp, err = e.WsGetInstruments(ctx) } else { - resp, err = c.GetInstruments(ctx) + resp, err = e.GetInstruments(ctx) } if err != nil { return nil, err @@ -174,7 +174,7 @@ func (c *COINUT) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency if len(instrument) == 0 { return nil, errors.New("invalid data received") } - c.instrumentMap.Seed(instrument[0].Base+instrument[0].Quote, instrument[0].InstrumentID) + e.instrumentMap.Seed(instrument[0].Base+instrument[0].Quote, instrument[0].InstrumentID) pair, err = currency.NewPairFromStrings(instrument[0].Base, instrument[0].Quote) if err != nil { return nil, err @@ -186,33 +186,33 @@ func (c *COINUT) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (c *COINUT) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := c.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = c.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return c.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateAccountInfo retrieves balances for all enabled currencies for the // COINUT exchange -func (c *COINUT) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var bal *UserBalance var err error - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { var resp *UserBalance - resp, err = c.wsGetAccountBalance(ctx) + resp, err = e.wsGetAccountBalance(ctx) if err != nil { return info, err } bal = resp } else { - bal, err = c.GetUserBalance(ctx) + bal, err = e.GetUserBalance(ctx) if err != nil { return info, err } @@ -276,13 +276,13 @@ func (c *COINUT) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a Total: bal.ZEC, }, } - info.Exchange = c.Name + info.Exchange = e.Name info.Accounts = append(info.Accounts, account.SubAccount{ AssetType: assetType, Currencies: balances, }) - creds, err := c.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -295,34 +295,34 @@ func (c *COINUT) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (c *COINUT) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (c *COINUT) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if !c.SupportsAsset(a) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - err := c.loadInstrumentsIfNotLoaded(ctx) + err := e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return nil, err } - fPair, err := c.FormatExchangeCurrency(p, a) + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - instID := c.instrumentMap.LookupID(fPair.String()) + instID := e.instrumentMap.LookupID(fPair.String()) if instID == 0 { return nil, errors.New("unable to lookup instrument ID") } var tick Ticker - tick, err = c.GetInstrumentTicker(ctx, instID) + tick, err = e.GetInstrumentTicker(ctx, instID) if err != nil { return nil, err } @@ -336,46 +336,46 @@ func (c *COINUT) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item Volume: tick.Volume24, Pair: p, LastUpdated: tick.Timestamp.Time(), - ExchangeName: c.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(c.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := c.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: c.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: c.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - err := c.loadInstrumentsIfNotLoaded(ctx) + err := e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return book, err } - fPair, err := c.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - instID := c.instrumentMap.LookupID(fPair.String()) + instID := e.instrumentMap.LookupID(fPair.String()) if instID == 0 { return book, errLookupInstrumentID } - orderbookNew, err := c.GetInstrumentOrderbook(ctx, instID, 200) + orderbookNew, err := e.GetInstrumentOrderbook(ctx, instID, 200) if err != nil { return book, err } @@ -399,33 +399,33 @@ func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(c.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (c *COINUT) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (c *COINUT) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { return nil, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (c *COINUT) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = c.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - currencyID := c.instrumentMap.LookupID(p.String()) + currencyID := e.instrumentMap.LookupID(p.String()) if currencyID == 0 { return nil, errLookupInstrumentID } var tradeData Trades - tradeData, err = c.GetTrades(ctx, currencyID) + tradeData, err = e.GetTrades(ctx, currencyID) if err != nil { return nil, err } @@ -437,7 +437,7 @@ func (c *COINUT) GetRecentTrades(ctx context.Context, p currency.Pair, assetType return nil, err } resp[i] = trade.Data{ - Exchange: c.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData.Trades[i].TransactionID, 10), CurrencyPair: p, AssetType: assetType, @@ -448,7 +448,7 @@ func (c *COINUT) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } } - err = c.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -458,26 +458,26 @@ func (c *COINUT) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } // GetHistoricTrades returns historic trade data within the timeframe provided -func (c *COINUT) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (c *COINUT) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { - err := o.Validate(c.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { + err := o.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } if _, err = strconv.Atoi(o.ClientID); err != nil { - return nil, fmt.Errorf("%s - ClientID must be a number, received: %s", c.Name, o.ClientID) + return nil, fmt.Errorf("%s - ClientID must be a number, received: %s", e.Name, o.ClientID) } var orderID string status := order.New - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { var response *order.Detail - response, err = c.wsSubmitOrder(ctx, &WsSubmitOrderParameters{ + response, err = e.wsSubmitOrder(ctx, &WsSubmitOrderParameters{ Currency: o.Pair, Side: o.Side, Amount: o.Amount, @@ -488,18 +488,18 @@ func (c *COINUT) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Submi } orderID = response.OrderID } else { - err = c.loadInstrumentsIfNotLoaded(ctx) + err = e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return nil, err } var fPair currency.Pair - fPair, err = c.FormatExchangeCurrency(o.Pair, asset.Spot) + fPair, err = e.FormatExchangeCurrency(o.Pair, asset.Spot) if err != nil { return nil, err } - currencyID := c.instrumentMap.LookupID(fPair.String()) + currencyID := e.instrumentMap.LookupID(fPair.String()) if currencyID == 0 { return nil, errLookupInstrumentID } @@ -510,7 +510,7 @@ func (c *COINUT) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Submi if err != nil { return nil, err } - APIResponse, err = c.NewOrder(ctx, + APIResponse, err = e.NewOrder(ctx, currencyID, o.Amount, o.Price, @@ -555,17 +555,17 @@ func (c *COINUT) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Submi // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *COINUT) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (c *COINUT) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - err := c.loadInstrumentsIfNotLoaded(ctx) + err := e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return err } @@ -574,27 +574,27 @@ func (c *COINUT) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } - fPair, err := c.FormatExchangeCurrency(o.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(o.Pair, asset.Spot) if err != nil { return err } - currencyID := c.instrumentMap.LookupID(fPair.String()) + currencyID := e.instrumentMap.LookupID(fPair.String()) - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { var resp *CancelOrdersResponse - resp, err = c.wsCancelOrder(ctx, &WsCancelOrderParameters{Currency: o.Pair, OrderID: orderIDInt}) + resp, err = e.wsCancelOrder(ctx, &WsCancelOrderParameters{Currency: o.Pair, OrderID: orderIDInt}) if err != nil { return err } if len(resp.Status) >= 1 && resp.Status[0] != "OK" { - return errors.New(c.Name + " - Failed to cancel order " + o.OrderID) + return errors.New(e.Name + " - Failed to cancel order " + o.OrderID) } } else { if currencyID == 0 { return errLookupInstrumentID } - _, err = c.CancelExistingOrder(ctx, currencyID, orderIDInt) + _, err = e.CancelExistingOrder(ctx, currencyID, orderIDInt) if err != nil { return err } @@ -604,7 +604,7 @@ func (c *COINUT) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (c *COINUT) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -614,7 +614,7 @@ func (c *COINUT) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde case o[i].ClientOrderID != "": return nil, order.ErrClientOrderIDNotSupported case o[i].OrderID != "": - currencyID := c.instrumentMap.LookupID(o[i].Pair.String()) + currencyID := e.instrumentMap.LookupID(o[i].Pair.String()) oid, err := strconv.ParseInt(o[i].OrderID, 10, 64) if err != nil { return nil, err @@ -627,7 +627,7 @@ func (c *COINUT) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde return nil, order.ErrOrderIDNotSet } } - results, err := c.CancelOrders(ctx, req) + results, err := e.CancelOrders(ctx, req) if err != nil { return nil, err } @@ -639,42 +639,42 @@ func (c *COINUT) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } // GetServerTime returns the current exchange server time. -func (c *COINUT) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (c *COINUT) CancelAllOrders(ctx context.Context, details *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, details *order.Cancel) (order.CancelAllResponse, error) { if err := details.Validate(); err != nil { return order.CancelAllResponse{}, err } var cancelAllOrdersResponse order.CancelAllResponse - err := c.loadInstrumentsIfNotLoaded(ctx) + err := e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return cancelAllOrdersResponse, err } cancelAllOrdersResponse.Status = make(map[string]string) - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - openOrders, err := c.wsGetOpenOrders(ctx, details.Pair.String()) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + openOrders, err := e.wsGetOpenOrders(ctx, details.Pair.String()) if err != nil { return cancelAllOrdersResponse, err } var ordersToCancel []WsCancelOrderParameters for i := range openOrders.Orders { var fPair currency.Pair - fPair, err = c.FormatExchangeCurrency(details.Pair, asset.Spot) + fPair, err = e.FormatExchangeCurrency(details.Pair, asset.Spot) if err != nil { return cancelAllOrdersResponse, err } - if openOrders.Orders[i].InstrumentID == c.instrumentMap.LookupID(fPair.String()) { + if openOrders.Orders[i].InstrumentID == e.instrumentMap.LookupID(fPair.String()) { ordersToCancel = append(ordersToCancel, WsCancelOrderParameters{ Currency: details.Pair, OrderID: openOrders.Orders[i].OrderID, }) } } - resp, err := c.wsCancelOrders(ctx, ordersToCancel) + resp, err := e.wsCancelOrders(ctx, ordersToCancel) if err != nil { return cancelAllOrdersResponse, err } @@ -685,14 +685,14 @@ func (c *COINUT) CancelAllOrders(ctx context.Context, details *order.Cancel) (or } } else { var allTheOrders []OrderResponse - ids := c.instrumentMap.GetInstrumentIDs() + ids := e.instrumentMap.GetInstrumentIDs() for x := range ids { - fPair, err := c.FormatExchangeCurrency(details.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(details.Pair, asset.Spot) if err != nil { return cancelAllOrdersResponse, err } - if ids[x] == c.instrumentMap.LookupID(fPair.String()) { - openOrders, err := c.GetOpenOrders(ctx, ids[x]) + if ids[x] == e.instrumentMap.LookupID(fPair.String()) { + openOrders, err := e.GetOpenOrders(ctx, ids[x]) if err != nil { return cancelAllOrdersResponse, err } @@ -710,7 +710,7 @@ func (c *COINUT) CancelAllOrders(ctx context.Context, details *order.Cancel) (or } if len(allTheOrdersToCancel) > 0 { - resp, err := c.CancelOrders(ctx, allTheOrdersToCancel) + resp, err := e.CancelOrders(ctx, allTheOrdersToCancel) if err != nil { return cancelAllOrdersResponse, err } @@ -727,53 +727,53 @@ func (c *COINUT) CancelAllOrders(ctx context.Context, details *order.Cancel) (or } // GetOrderInfo returns order information based on order ID -func (c *COINUT) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { return nil, common.ErrFunctionNotSupported } // GetDepositAddress returns a deposit address for a specified currency -func (c *COINUT) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { return nil, common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *COINUT) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (c *COINUT) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (c *COINUT) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (c *COINUT) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !c.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return c.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - err = c.loadInstrumentsIfNotLoaded(ctx) + err = e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return nil, err } @@ -782,21 +782,21 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque if len(req.Pairs) == 0 { for i := range req.Pairs { var fPair currency.Pair - fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[i], asset.Spot) if err != nil { return nil, err } currenciesToCheck = append(currenciesToCheck, fPair.String()) } } else { - for k := range c.instrumentMap.Instruments { + for k := range e.instrumentMap.Instruments { currenciesToCheck = append(currenciesToCheck, k) } } - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { for x := range currenciesToCheck { var openOrders *WsUserOpenOrdersResponse - openOrders, err = c.wsGetOpenOrders(ctx, currenciesToCheck[x]) + openOrders, err = e.wsGetOpenOrders(ctx, currenciesToCheck[x]) if err != nil { return nil, err } @@ -808,7 +808,7 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } var fPair currency.Pair - fPair, err = c.FormatExchangeCurrency(p, asset.Spot) + fPair, err = e.FormatExchangeCurrency(p, asset.Spot) if err != nil { return nil, err } @@ -820,7 +820,7 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } orders = append(orders, order.Detail{ - Exchange: c.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(openOrders.Orders[i].OrderID, 10), Pair: fPair, Side: side, @@ -837,37 +837,37 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque var instrumentsToUse []int64 for x := range req.Pairs { var curr currency.Pair - curr, err = c.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + curr, err = e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } instrumentsToUse = append(instrumentsToUse, - c.instrumentMap.LookupID(curr.String())) + e.instrumentMap.LookupID(curr.String())) } if len(instrumentsToUse) == 0 { - instrumentsToUse = c.instrumentMap.GetInstrumentIDs() + instrumentsToUse = e.instrumentMap.GetInstrumentIDs() } var pairs currency.Pairs - pairs, err = c.GetEnabledPairs(asset.Spot) + pairs, err = e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } var format currency.PairFormat - format, err = c.GetPairFormat(asset.Spot, true) + format, err = e.GetPairFormat(asset.Spot, true) if err != nil { return nil, err } for x := range instrumentsToUse { var openOrders GetOpenOrdersResponse - openOrders, err = c.GetOpenOrders(ctx, instrumentsToUse[x]) + openOrders, err = e.GetOpenOrders(ctx, instrumentsToUse[x]) if err != nil { return nil, err } for y := range openOrders.Orders { - curr := c.instrumentMap.LookupInstrument(instrumentsToUse[x]) + curr := e.instrumentMap.LookupInstrument(instrumentsToUse[x]) var p currency.Pair p, err = currency.NewPairFromFormattedPairs(curr, pairs, format) if err != nil { @@ -884,7 +884,7 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque OrderID: strconv.FormatInt(openOrders.Orders[y].OrderID, 10), Amount: openOrders.Orders[y].Quantity, Price: openOrders.Orders[y].Price, - Exchange: c.Name, + Exchange: e.Name, Side: side, Date: openOrders.Orders[y].Timestamp.Time(), Pair: p, @@ -892,32 +892,32 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } } } - return req.Filter(c.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - err = c.loadInstrumentsIfNotLoaded(ctx) + err = e.loadInstrumentsIfNotLoaded(ctx) if err != nil { return nil, err } var allOrders []order.Detail - if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { for i := range req.Pairs { for j := int64(0); ; j += 100 { var trades *WsTradeHistoryResponse - trades, err = c.wsGetTradeHistory(ctx, req.Pairs[i], j, 100) + trades, err = e.wsGetTradeHistory(ctx, req.Pairs[i], j, 100) if err != nil { return allOrders, err } for x := range trades.Trades { - curr := c.instrumentMap.LookupInstrument(trades.Trades[x].InstrumentID) + curr := e.instrumentMap.LookupInstrument(trades.Trades[x].InstrumentID) var p currency.Pair p, err = currency.NewPairFromString(curr) if err != nil { @@ -931,7 +931,7 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque } detail := order.Detail{ - Exchange: c.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(trades.Trades[x].OrderID, 10), Pair: p, Side: side, @@ -954,40 +954,40 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var instrumentsToUse []int64 for x := range req.Pairs { var curr currency.Pair - curr, err = c.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + curr, err = e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } - instrumentID := c.instrumentMap.LookupID(curr.String()) + instrumentID := e.instrumentMap.LookupID(curr.String()) if instrumentID > 0 { instrumentsToUse = append(instrumentsToUse, instrumentID) } } if len(instrumentsToUse) == 0 { - instrumentsToUse = c.instrumentMap.GetInstrumentIDs() + instrumentsToUse = e.instrumentMap.GetInstrumentIDs() } var pairs currency.Pairs - pairs, err = c.GetEnabledPairs(asset.Spot) + pairs, err = e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } var format currency.PairFormat - format, err = c.GetPairFormat(asset.Spot, true) + format, err = e.GetPairFormat(asset.Spot, true) if err != nil { return nil, err } for x := range instrumentsToUse { var orders TradeHistory - orders, err = c.GetTradeHistory(ctx, instrumentsToUse[x], -1, -1) + orders, err = e.GetTradeHistory(ctx, instrumentsToUse[x], -1, -1) if err != nil { return nil, err } for y := range orders.Trades { - curr := c.instrumentMap.LookupInstrument(instrumentsToUse[x]) + curr := e.instrumentMap.LookupInstrument(instrumentsToUse[x]) var p currency.Pair p, err = currency.NewPairFromFormattedPairs(curr, pairs, format) if err != nil { @@ -1004,7 +1004,7 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque OrderID: strconv.FormatInt(orders.Trades[y].Order.OrderID, 10), Amount: orders.Trades[y].Order.Quantity, Price: orders.Trades[y].Order.Price, - Exchange: c.Name, + Exchange: e.Name, Side: side, Date: orders.Trades[y].Order.Timestamp.Time(), Pair: p, @@ -1012,23 +1012,23 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque } } } - return req.Filter(c.Name, allOrders), nil + return req.Filter(e.Name, allOrders), nil } // AuthenticateWebsocket sends an authentication message to the websocket -func (c *COINUT) AuthenticateWebsocket(ctx context.Context) error { - return c.wsAuthenticate(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.wsAuthenticate(ctx) } -func (c *COINUT) loadInstrumentsIfNotLoaded(ctx context.Context) error { - if !c.instrumentMap.IsLoaded() { - if c.Websocket.IsConnected() { - _, err := c.WsGetInstruments(ctx) +func (e *Exchange) loadInstrumentsIfNotLoaded(ctx context.Context) error { + if !e.instrumentMap.IsLoaded() { + if e.Websocket.IsConnected() { + _, err := e.WsGetInstruments(ctx) if err != nil { return err } } else { - err := c.SeedInstruments(ctx) + err := e.SeedInstruments(ctx) if err != nil { return err } @@ -1039,39 +1039,39 @@ func (c *COINUT) loadInstrumentsIfNotLoaded(ctx context.Context) error { // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (c *COINUT) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := c.UpdateAccountInfo(ctx, assetType) - return c.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (c *COINUT) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (c *COINUT) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (c *COINUT) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (c *COINUT) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (c *COINUT) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (c *COINUT) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := c.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/deribit/deribit.go b/exchanges/deribit/deribit.go index 500f1de43b0..c8d113cf6cf 100644 --- a/exchanges/deribit/deribit.go +++ b/exchanges/deribit/deribit.go @@ -24,8 +24,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/types" ) -// Deribit is the overarching type across this package -type Deribit struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Deribit +type Exchange struct { exchange.Base } @@ -179,7 +179,7 @@ const ( ) // GetBookSummaryByCurrency gets book summary data for currency requested -func (d *Deribit) GetBookSummaryByCurrency(ctx context.Context, ccy currency.Code, kind string) ([]BookSummaryData, error) { +func (e *Exchange) GetBookSummaryByCurrency(ctx context.Context, ccy currency.Code, kind string) ([]BookSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -189,40 +189,40 @@ func (d *Deribit) GetBookSummaryByCurrency(ctx context.Context, ccy currency.Cod params.Set("kind", kind) } var resp []BookSummaryData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getBookByCurrency, params), &resp) } // GetBookSummaryByInstrument gets book summary data for instrument requested -func (d *Deribit) GetBookSummaryByInstrument(ctx context.Context, instrument string) ([]BookSummaryData, error) { +func (e *Exchange) GetBookSummaryByInstrument(ctx context.Context, instrument string) ([]BookSummaryData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } var resp []BookSummaryData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getBookByInstrument, params), &resp) } // GetContractSize gets contract size for instrument requested -func (d *Deribit) GetContractSize(ctx context.Context, instrument string) (*ContractSizeData, error) { +func (e *Exchange) GetContractSize(ctx context.Context, instrument string) (*ContractSizeData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } var resp *ContractSizeData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getContractSize, params), &resp) } // GetCurrencies gets all cryptocurrencies supported by the API -func (d *Deribit) GetCurrencies(ctx context.Context) ([]CurrencyData, error) { +func (e *Exchange) GetCurrencies(ctx context.Context) ([]CurrencyData, error) { var resp []CurrencyData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, getCurrencies, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, getCurrencies, &resp) } // GetDeliveryPrices gets all delivery prices for the given inde name -func (d *Deribit) GetDeliveryPrices(ctx context.Context, indexName string, offset, count int64) (*IndexDeliveryPrice, error) { +func (e *Exchange) GetDeliveryPrices(ctx context.Context, indexName string, offset, count int64) (*IndexDeliveryPrice, error) { if indexName == "" { return nil, errUnsupportedIndexName } @@ -235,24 +235,24 @@ func (d *Deribit) GetDeliveryPrices(ctx context.Context, indexName string, offse params.Set("count", strconv.FormatInt(count, 10)) } var resp *IndexDeliveryPrice - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getDeliveryPrices, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getDeliveryPrices, params), &resp) } // GetFundingChartData gets funding chart data for the requested instrument and time length // supported lengths: 8h, 24h, 1m <-(1month) -func (d *Deribit) GetFundingChartData(ctx context.Context, instrument, length string) (*FundingChartData, error) { +func (e *Exchange) GetFundingChartData(ctx context.Context, instrument, length string) (*FundingChartData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } params.Set("length", length) var resp *FundingChartData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getFundingChartData, params), &resp) } // GetFundingRateHistory retrieves hourly historical interest rate for requested PERPETUAL instrument. -func (d *Deribit) GetFundingRateHistory(ctx context.Context, instrumentName string, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (e *Exchange) GetFundingRateHistory(ctx context.Context, instrumentName string, startTime, endTime time.Time) ([]FundingRateHistory, error) { params, err := checkInstrument(instrumentName) if err != nil { return nil, err @@ -264,11 +264,11 @@ func (d *Deribit) GetFundingRateHistory(ctx context.Context, instrumentName stri params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp []FundingRateHistory - return resp, d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues(getFundingRateHistory, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues(getFundingRateHistory, params), &resp) } // GetFundingRateValue gets funding rate value data. -func (d *Deribit) GetFundingRateValue(ctx context.Context, instrument string, startTime, endTime time.Time) (float64, error) { +func (e *Exchange) GetFundingRateValue(ctx context.Context, instrument string, startTime, endTime time.Time) (float64, error) { params, err := checkInstrument(instrument) if err != nil { return 0, err @@ -280,63 +280,63 @@ func (d *Deribit) GetFundingRateValue(ctx context.Context, instrument string, st params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp float64 - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getFundingRateValue, params), &resp) } // GetHistoricalVolatility gets historical volatility data -func (d *Deribit) GetHistoricalVolatility(ctx context.Context, ccy currency.Code) ([]HistoricalVolatilityData, error) { +func (e *Exchange) GetHistoricalVolatility(ctx context.Context, ccy currency.Code) ([]HistoricalVolatilityData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var data []HistoricalVolatilityData - return data, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getHistoricalVolatility, params), &data) + return data, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getHistoricalVolatility, params), &data) } // GetCurrencyIndexPrice retrieves the current index price for the instruments, for the selected currency. -func (d *Deribit) GetCurrencyIndexPrice(ctx context.Context, ccy currency.Code) (*IndexPrice, error) { +func (e *Exchange) GetCurrencyIndexPrice(ctx context.Context, ccy currency.Code) (*IndexPrice, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp *IndexPrice - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getCurrencyIndexPrice, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getCurrencyIndexPrice, params), &resp) } // GetIndexPrice gets price data for the requested index -func (d *Deribit) GetIndexPrice(ctx context.Context, index string) (*IndexPriceData, error) { +func (e *Exchange) GetIndexPrice(ctx context.Context, index string) (*IndexPriceData, error) { if index == "" { return nil, errUnsupportedIndexName } params := url.Values{} params.Set("index_name", index) var resp *IndexPriceData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getIndexPrice, params), &resp) } // GetIndexPriceNames gets names of indexes -func (d *Deribit) GetIndexPriceNames(ctx context.Context) ([]string, error) { +func (e *Exchange) GetIndexPriceNames(ctx context.Context) ([]string, error) { var resp []string - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, getIndexPriceNames, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, getIndexPriceNames, &resp) } // GetInstrument retrieves instrument detail -func (d *Deribit) GetInstrument(ctx context.Context, instrument string) (*InstrumentData, error) { +func (e *Exchange) GetInstrument(ctx context.Context, instrument string) (*InstrumentData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } var resp *InstrumentData - return resp, d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues(getInstrument, params), &resp) } // GetInstruments gets data for all available instruments -func (d *Deribit) GetInstruments(ctx context.Context, ccy currency.Code, kind string, expired bool) ([]*InstrumentData, error) { +func (e *Exchange) GetInstruments(ctx context.Context, ccy currency.Code, kind string, expired bool) ([]*InstrumentData, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -348,11 +348,11 @@ func (d *Deribit) GetInstruments(ctx context.Context, ccy currency.Code, kind st params.Set("expired", "true") } var resp []*InstrumentData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getInstruments, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getInstruments, params), &resp) } // GetLastSettlementsByCurrency gets last settlement data by currency -func (d *Deribit) GetLastSettlementsByCurrency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTime time.Time) (*SettlementsData, error) { +func (e *Exchange) GetLastSettlementsByCurrency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTime time.Time) (*SettlementsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -371,12 +371,12 @@ func (d *Deribit) GetLastSettlementsByCurrency(ctx context.Context, ccy currency params.Set("search_start_timestamp", strconv.FormatInt(searchStartTime.UnixMilli(), 10)) } var resp *SettlementsData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastSettlementsByCurrency, params), &resp) } // GetLastSettlementsByInstrument gets last settlement data for requested instrument -func (d *Deribit) GetLastSettlementsByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { +func (e *Exchange) GetLastSettlementsByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -394,12 +394,12 @@ func (d *Deribit) GetLastSettlementsByInstrument(ctx context.Context, instrument params.Set("search_start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) } var resp *SettlementsData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastSettlementsByInstrument, params), &resp) } // GetLastTradesByCurrency gets last trades for requested currency -func (d *Deribit) GetLastTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { +func (e *Exchange) GetLastTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -424,12 +424,12 @@ func (d *Deribit) GetLastTradesByCurrency(ctx context.Context, ccy currency.Code params.Set("include_old", "true") } var resp *PublicTradesData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastTradesByCurrency, params), &resp) } // GetLastTradesByCurrencyAndTime gets last trades for requested currency and time intervals -func (d *Deribit) GetLastTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*PublicTradesData, error) { +func (e *Exchange) GetLastTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*PublicTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -451,12 +451,12 @@ func (d *Deribit) GetLastTradesByCurrencyAndTime(ctx context.Context, ccy curren params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp *PublicTradesData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastTradesByCurrencyAndTime, params), &resp) } // GetLastTradesByInstrument gets last trades for requested instrument requested -func (d *Deribit) GetLastTradesByInstrument(ctx context.Context, instrument, startSeq, endSeq, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { +func (e *Exchange) GetLastTradesByInstrument(ctx context.Context, instrument, startSeq, endSeq, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -477,11 +477,11 @@ func (d *Deribit) GetLastTradesByInstrument(ctx context.Context, instrument, sta params.Set("include_old", "true") } var resp *PublicTradesData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastTradesByInstrument, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastTradesByInstrument, params), &resp) } // GetLastTradesByInstrumentAndTime gets last trades for requested instrument requested and time intervals -func (d *Deribit) GetLastTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, startTime, endTime time.Time) (*PublicTradesData, error) { +func (e *Exchange) GetLastTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, startTime, endTime time.Time) (*PublicTradesData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -499,12 +499,12 @@ func (d *Deribit) GetLastTradesByInstrumentAndTime(ctx context.Context, instrume params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp *PublicTradesData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getLastTradesByInstrumentAndTime, params), &resp) } // GetMarkPriceHistory gets data for mark price history -func (d *Deribit) GetMarkPriceHistory(ctx context.Context, instrument string, startTime, endTime time.Time) ([]MarkPriceHistory, error) { +func (e *Exchange) GetMarkPriceHistory(ctx context.Context, instrument string, startTime, endTime time.Time) ([]MarkPriceHistory, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -516,7 +516,7 @@ func (d *Deribit) GetMarkPriceHistory(ctx context.Context, instrument string, st params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp []MarkPriceHistory - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getMarkPriceHistory, params), &resp) } @@ -530,7 +530,7 @@ func checkInstrument(instrumentName string) (url.Values, error) { } // GetOrderbook gets data orderbook of requested instrument -func (d *Deribit) GetOrderbook(ctx context.Context, instrument string, depth int64) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, instrument string, depth int64) (*Orderbook, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -539,12 +539,12 @@ func (d *Deribit) GetOrderbook(ctx context.Context, instrument string, depth int params.Set("depth", strconv.FormatInt(depth, 10)) } var resp *Orderbook - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getOrderbook, params), &resp) } // GetOrderbookByInstrumentID retrieves orderbook by instrument ID -func (d *Deribit) GetOrderbookByInstrumentID(ctx context.Context, instrumentID int64, depth float64) (*Orderbook, error) { +func (e *Exchange) GetOrderbookByInstrumentID(ctx context.Context, instrumentID int64, depth float64) (*Orderbook, error) { if instrumentID == 0 { return nil, errInvalidInstrumentID } @@ -554,22 +554,22 @@ func (d *Deribit) GetOrderbookByInstrumentID(ctx context.Context, instrumentID i params.Set("depth", strconv.FormatFloat(depth, 'f', -1, 64)) } var resp *Orderbook - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getOrderbookByInstrumentID, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getOrderbookByInstrumentID, params), &resp) } // GetSupportedIndexNames retrieves the identifiers of all supported Price Indexes // 'type' represents Type of a cryptocurrency price index. possible 'all', 'spot', 'derivative' -func (d *Deribit) GetSupportedIndexNames(ctx context.Context, priceIndexType string) ([]string, error) { +func (e *Exchange) GetSupportedIndexNames(ctx context.Context, priceIndexType string) ([]string, error) { params := url.Values{} if priceIndexType != "" { params.Set("type", priceIndexType) } var resp []string - return resp, d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues("public/get_supported_index_names", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues("public/get_supported_index_names", params), &resp) } // GetRequestForQuote retrieves RFQ information. -func (d *Deribit) GetRequestForQuote(ctx context.Context, ccy currency.Code, kind string) ([]RequestForQuote, error) { +func (e *Exchange) GetRequestForQuote(ctx context.Context, ccy currency.Code, kind string) ([]RequestForQuote, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -579,22 +579,22 @@ func (d *Deribit) GetRequestForQuote(ctx context.Context, ccy currency.Code, kin params.Set("kind", kind) } var resp []RequestForQuote - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getRFQ, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getRFQ, params), &resp) } // GetTradeVolumes gets trade volumes' data of all instruments -func (d *Deribit) GetTradeVolumes(ctx context.Context, extended bool) ([]TradeVolumesData, error) { +func (e *Exchange) GetTradeVolumes(ctx context.Context, extended bool) ([]TradeVolumesData, error) { params := url.Values{} if extended { params.Set("extended", "true") } var resp []TradeVolumesData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getTradeVolumes, params), &resp) } // GetTradingViewChart gets volatility index data for the requested instrument -func (d *Deribit) GetTradingViewChart(ctx context.Context, instrument, resolution string, startTime, endTime time.Time) (*TVChartData, error) { +func (e *Exchange) GetTradingViewChart(ctx context.Context, instrument, resolution string, startTime, endTime time.Time) (*TVChartData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -610,12 +610,12 @@ func (d *Deribit) GetTradingViewChart(ctx context.Context, instrument, resolutio params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) params.Set("resolution", resolution) var resp *TVChartData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getTradingViewChartData, params), &resp) } // GetResolutionFromInterval returns the string representation of intervals given kline.Interval instance. -func (d *Deribit) GetResolutionFromInterval(interval kline.Interval) (string, error) { +func (e *Exchange) GetResolutionFromInterval(interval kline.Interval) (string, error) { switch interval { case kline.HundredMilliseconds: return "100ms", nil @@ -651,7 +651,7 @@ func (d *Deribit) GetResolutionFromInterval(interval kline.Interval) (string, er } // GetVolatilityIndex gets volatility index for the requested currency -func (d *Deribit) GetVolatilityIndex(ctx context.Context, ccy currency.Code, resolution string, startTime, endTime time.Time) ([]VolatilityIndexData, error) { +func (e *Exchange) GetVolatilityIndex(ctx context.Context, ccy currency.Code, resolution string, startTime, endTime time.Time) ([]VolatilityIndexData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -668,7 +668,7 @@ func (d *Deribit) GetVolatilityIndex(ctx context.Context, ccy currency.Code, res params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) params.Set("resolution", resolution) var resp VolatilityIndexRawData - err = d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, + err = e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getVolatilityIndex, params), &resp) if err != nil { return nil, err @@ -687,18 +687,18 @@ func (d *Deribit) GetVolatilityIndex(ctx context.Context, ccy currency.Code, res } // GetPublicTicker gets public ticker data of the instrument requested -func (d *Deribit) GetPublicTicker(ctx context.Context, instrument string) (*TickerData, error) { +func (e *Exchange) GetPublicTicker(ctx context.Context, instrument string) (*TickerData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } var resp *TickerData - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getTicker, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getTicker, params), &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (d *Deribit) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, path string, result any) error { - endpoint, err := d.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -709,20 +709,20 @@ func (d *Deribit) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl requ }{ Data: result, } - return d.SendPayload(ctx, epl, func() (*request.Item, error) { + return e.SendPayload(ctx, epl, func() (*request.Item, error) { return &request.Item{ Method: http.MethodGet, Path: endpoint + deribitAPIVersion + "/" + path, Result: data, - Verbose: d.Verbose, - HTTPDebugging: d.HTTPDebugging, - HTTPRecording: d.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.UnauthenticatedRequest) } // GetAccountSummary gets account summary data for the requested instrument -func (d *Deribit) GetAccountSummary(ctx context.Context, ccy currency.Code, extended bool) (*AccountSummaryData, error) { +func (e *Exchange) GetAccountSummary(ctx context.Context, ccy currency.Code, extended bool) (*AccountSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -732,11 +732,11 @@ func (d *Deribit) GetAccountSummary(ctx context.Context, ccy currency.Code, exte params.Set("extended", "true") } var resp *AccountSummaryData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAccountSummary, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAccountSummary, params, &resp) } // CancelWithdrawal cancels withdrawal request for a given currency by its id -func (d *Deribit) CancelWithdrawal(ctx context.Context, ccy currency.Code, id int64) (*CancelWithdrawalData, error) { +func (e *Exchange) CancelWithdrawal(ctx context.Context, ccy currency.Code, id int64) (*CancelWithdrawalData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -747,12 +747,12 @@ func (d *Deribit) CancelWithdrawal(ctx context.Context, ccy currency.Code, id in params.Set("currency", ccy.String()) params.Set("id", strconv.FormatInt(id, 10)) var resp *CancelWithdrawalData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, cancelWithdrawal, params, &resp) } // CancelTransferByID cancels transfer by ID through the websocket connection. -func (d *Deribit) CancelTransferByID(ctx context.Context, ccy currency.Code, tfa string, id int64) (*AccountSummaryData, error) { +func (e *Exchange) CancelTransferByID(ctx context.Context, ccy currency.Code, tfa string, id int64) (*AccountSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -766,30 +766,30 @@ func (d *Deribit) CancelTransferByID(ctx context.Context, ccy currency.Code, tfa } params.Set("id", strconv.FormatInt(id, 10)) var resp *AccountSummaryData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, cancelTransferByID, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, cancelTransferByID, params, &resp) } // CreateDepositAddress creates a deposit address for the currency requested -func (d *Deribit) CreateDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { +func (e *Exchange) CreateDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp *DepositAddressData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, createDepositAddress, params, &resp) } // GetCurrentDepositAddress gets the current deposit address for the requested currency -func (d *Deribit) GetCurrentDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { +func (e *Exchange) GetCurrentDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp *DepositAddressData - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getCurrentDepositAddress, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getCurrentDepositAddress, params, &resp) if err != nil { return nil, err } else if resp == nil { @@ -799,7 +799,7 @@ func (d *Deribit) GetCurrentDepositAddress(ctx context.Context, ccy currency.Cod } // GetDeposits gets the deposits of a given currency -func (d *Deribit) GetDeposits(ctx context.Context, ccy currency.Code, count, offset int64) (*DepositsData, error) { +func (e *Exchange) GetDeposits(ctx context.Context, ccy currency.Code, count, offset int64) (*DepositsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -812,11 +812,11 @@ func (d *Deribit) GetDeposits(ctx context.Context, ccy currency.Code, count, off params.Set("offset", strconv.FormatInt(offset, 10)) } var resp *DepositsData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getDeposits, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getDeposits, params, &resp) } // GetTransfers gets transfers data for the requested currency -func (d *Deribit) GetTransfers(ctx context.Context, ccy currency.Code, count, offset int64) (*TransfersData, error) { +func (e *Exchange) GetTransfers(ctx context.Context, ccy currency.Code, count, offset int64) (*TransfersData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -829,12 +829,12 @@ func (d *Deribit) GetTransfers(ctx context.Context, ccy currency.Code, count, of params.Set("offset", strconv.FormatInt(offset, 10)) } var resp *TransfersData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getTransfers, params, &resp) } // GetWithdrawals gets withdrawals data for a requested currency -func (d *Deribit) GetWithdrawals(ctx context.Context, ccy currency.Code, count, offset int64) (*WithdrawalsData, error) { +func (e *Exchange) GetWithdrawals(ctx context.Context, ccy currency.Code, count, offset int64) (*WithdrawalsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -847,14 +847,14 @@ func (d *Deribit) GetWithdrawals(ctx context.Context, ccy currency.Code, count, params.Set("offset", strconv.FormatInt(offset, 10)) } var resp *WithdrawalsData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getWithdrawals, params, &resp) } // SubmitTransferBetweenSubAccounts transfer funds between two (sub)accounts. // Id of the source (sub)account. Can be found in My Account >> Subaccounts tab. By default, it is the Id of the account which made the request. // However, if a different "source" is specified, the user must possess the mainaccount scope, and only other subaccounts can be designated as the source. -func (d *Deribit) SubmitTransferBetweenSubAccounts(ctx context.Context, ccy currency.Code, amount float64, destinationID int64, source string) (*TransferData, error) { +func (e *Exchange) SubmitTransferBetweenSubAccounts(ctx context.Context, ccy currency.Code, amount float64, destinationID int64, source string) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -872,11 +872,11 @@ func (d *Deribit) SubmitTransferBetweenSubAccounts(ctx context.Context, ccy curr params.Set("source", source) } var resp *TransferData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitTransferBetweenSubAccounts, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitTransferBetweenSubAccounts, params, &resp) } // SubmitTransferToSubAccount submits a request to transfer a currency to a subaccount -func (d *Deribit) SubmitTransferToSubAccount(ctx context.Context, ccy currency.Code, amount float64, destinationID int64) (*TransferData, error) { +func (e *Exchange) SubmitTransferToSubAccount(ctx context.Context, ccy currency.Code, amount float64, destinationID int64) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -891,12 +891,12 @@ func (d *Deribit) SubmitTransferToSubAccount(ctx context.Context, ccy currency.C params.Set("destination", strconv.FormatInt(destinationID, 10)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var resp *TransferData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitTransferToSubaccount, params, &resp) } // SubmitTransferToUser submits a request to transfer a currency to another user -func (d *Deribit) SubmitTransferToUser(ctx context.Context, ccy currency.Code, tfa, destinationAddress string, amount float64) (*TransferData, error) { +func (e *Exchange) SubmitTransferToUser(ctx context.Context, ccy currency.Code, tfa, destinationAddress string, amount float64) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -914,11 +914,11 @@ func (d *Deribit) SubmitTransferToUser(ctx context.Context, ccy currency.Code, t params.Set("destination", destinationAddress) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var resp *TransferData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitTransferToUser, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitTransferToUser, params, &resp) } // SubmitWithdraw submits a withdrawal request to the exchange for the requested currency -func (d *Deribit) SubmitWithdraw(ctx context.Context, ccy currency.Code, address, priority string, amount float64) (*WithdrawData, error) { +func (e *Exchange) SubmitWithdraw(ctx context.Context, ccy currency.Code, address, priority string, amount float64) (*WithdrawData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -936,12 +936,12 @@ func (d *Deribit) SubmitWithdraw(ctx context.Context, ccy currency.Code, address } params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var resp *WithdrawData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, submitWithdraw, params, &resp) } // GetAnnouncements retrieves announcements. Default "start_timestamp" parameter value is current timestamp, "count" parameter value must be between 1 and 50, default is 5. -func (d *Deribit) GetAnnouncements(ctx context.Context, startTime time.Time, count int64) ([]Announcement, error) { +func (e *Exchange) GetAnnouncements(ctx context.Context, startTime time.Time, count int64) ([]Announcement, error) { params := url.Values{} if !startTime.IsZero() { params.Set("start_time", strconv.FormatInt(startTime.UnixMilli(), 10)) @@ -950,11 +950,11 @@ func (d *Deribit) GetAnnouncements(ctx context.Context, startTime time.Time, cou params.Set("count", strconv.FormatInt(count, 10)) } var resp []Announcement - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getAnnouncements, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getAnnouncements, params), &resp) } // ChangeAPIKeyName changes the name of the api key requested -func (d *Deribit) ChangeAPIKeyName(ctx context.Context, id int64, name string) (*APIKeyData, error) { +func (e *Exchange) ChangeAPIKeyName(ctx context.Context, id int64, name string) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } @@ -965,14 +965,14 @@ func (d *Deribit) ChangeAPIKeyName(ctx context.Context, id int64, name string) ( params.Set("id", strconv.FormatInt(id, 10)) params.Set("name", name) var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, changeAPIKeyName, params, &resp) } // ChangeMarginModel change margin model // Margin model: 'cross_pm', 'cross_sm', 'segregated_pm', 'segregated_sm' // 'dry_run': If true request returns the result without switching the margining model. Default: false -func (d *Deribit) ChangeMarginModel(ctx context.Context, userID int64, marginModel string, dryRun bool) ([]TogglePortfolioMarginResponse, error) { +func (e *Exchange) ChangeMarginModel(ctx context.Context, userID int64, marginModel string, dryRun bool) ([]TogglePortfolioMarginResponse, error) { if marginModel == "" { return nil, errInvalidMarginModel } @@ -985,11 +985,11 @@ func (d *Deribit) ChangeMarginModel(ctx context.Context, userID int64, marginMod params.Set("dry_run", "true") } var resp []TogglePortfolioMarginResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, changeMarginModel, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, changeMarginModel, params, &resp) } // ChangeScopeInAPIKey changes the scope of the api key requested -func (d *Deribit) ChangeScopeInAPIKey(ctx context.Context, id int64, maxScope string) (*APIKeyData, error) { +func (e *Exchange) ChangeScopeInAPIKey(ctx context.Context, id int64, maxScope string) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } @@ -997,12 +997,12 @@ func (d *Deribit) ChangeScopeInAPIKey(ctx context.Context, id int64, maxScope st params.Set("id", strconv.FormatInt(id, 10)) params.Set("max_scope", maxScope) var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, changeScopeInAPIKey, params, &resp) } // ChangeSubAccountName changes the name of the requested subaccount id -func (d *Deribit) ChangeSubAccountName(ctx context.Context, sid int64, name string) error { +func (e *Exchange) ChangeSubAccountName(ctx context.Context, sid int64, name string) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1013,7 +1013,7 @@ func (d *Deribit) ChangeSubAccountName(ctx context.Context, sid int64, name stri params.Set("sid", strconv.FormatInt(sid, 10)) params.Set("name", name) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, changeSubAccountName, params, &resp) if err != nil { return err @@ -1025,7 +1025,7 @@ func (d *Deribit) ChangeSubAccountName(ctx context.Context, sid int64, name stri } // CreateAPIKey creates an api key based on the provided settings -func (d *Deribit) CreateAPIKey(ctx context.Context, maxScope, name string, defaultKey bool) (*APIKeyData, error) { +func (e *Exchange) CreateAPIKey(ctx context.Context, maxScope, name string, defaultKey bool) (*APIKeyData, error) { params := url.Values{} params.Set("max_scope", maxScope) if name != "" { @@ -1035,26 +1035,26 @@ func (d *Deribit) CreateAPIKey(ctx context.Context, maxScope, name string, defau params.Set("default", "true") } var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, createAPIKey, params, &resp) } // CreateSubAccount creates a new subaccount -func (d *Deribit) CreateSubAccount(ctx context.Context) (*SubAccountData, error) { +func (e *Exchange) CreateSubAccount(ctx context.Context) (*SubAccountData, error) { var resp *SubAccountData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, createSubAccount, nil, &resp) } // DisableAPIKey disables the api key linked to the provided id -func (d *Deribit) DisableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { +func (e *Exchange) DisableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } params := url.Values{} params.Set("id", strconv.FormatInt(id, 10)) var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, disableAPIKey, params, &resp) } @@ -1064,7 +1064,7 @@ func (d *Deribit) DisableAPIKey(ctx context.Context, id int64) (*APIKeyData, err // wallet:[read, read_write, none], // account:[read, read_write, none], // block_trade:[read, read_write, none]. -func (d *Deribit) EditAPIKey(ctx context.Context, id int64, maxScope, name string, enabled bool, enabledFeatures, ipWhitelist []string) (*APIKeyData, error) { +func (e *Exchange) EditAPIKey(ctx context.Context, id int64, maxScope, name string, enabled bool, enabledFeatures, ipWhitelist []string) (*APIKeyData, error) { if id == 0 { return nil, errInvalidAPIKeyID } @@ -1093,13 +1093,13 @@ func (d *Deribit) EditAPIKey(ctx context.Context, id int64, maxScope, name strin params.Set("ip_whitelist", string(ipWhitelistByte)) } var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, editAPIKey, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, editAPIKey, params, &resp) } // EnableAffiliateProgram enables the affiliate program -func (d *Deribit) EnableAffiliateProgram(ctx context.Context) error { +func (e *Exchange) EnableAffiliateProgram(ctx context.Context) error { var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, enableAffiliateProgram, nil, &resp) if err != nil { return err @@ -1111,19 +1111,19 @@ func (d *Deribit) EnableAffiliateProgram(ctx context.Context) error { } // EnableAPIKey enables the api key linked to the provided id -func (d *Deribit) EnableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { +func (e *Exchange) EnableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } params := url.Values{} params.Set("id", strconv.FormatInt(id, 10)) var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, enableAPIKey, params, &resp) } // GetAccessLog lists access logs for the user -func (d *Deribit) GetAccessLog(ctx context.Context, offset, count int64) (*AccessLog, error) { +func (e *Exchange) GetAccessLog(ctx context.Context, offset, count int64) (*AccessLog, error) { params := url.Values{} if offset > 0 { params.Set("offset", strconv.FormatInt(offset, 10)) @@ -1132,53 +1132,53 @@ func (d *Deribit) GetAccessLog(ctx context.Context, offset, count int64) (*Acces params.Set("count", strconv.FormatInt(count, 10)) } var resp *AccessLog - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAccessLog, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAccessLog, params, &resp) } // GetAffiliateProgramInfo gets the affiliate program info -func (d *Deribit) GetAffiliateProgramInfo(ctx context.Context) (*AffiliateProgramInfo, error) { +func (e *Exchange) GetAffiliateProgramInfo(ctx context.Context) (*AffiliateProgramInfo, error) { var resp *AffiliateProgramInfo - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAffiliateProgramInfo, nil, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getAffiliateProgramInfo, nil, &resp) } // GetEmailLanguage gets the current language set for the email -func (d *Deribit) GetEmailLanguage(ctx context.Context) (string, error) { +func (e *Exchange) GetEmailLanguage(ctx context.Context) (string, error) { var resp string - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getEmailLanguage, nil, &resp) } // GetNewAnnouncements gets new announcements -func (d *Deribit) GetNewAnnouncements(ctx context.Context) ([]Announcement, error) { +func (e *Exchange) GetNewAnnouncements(ctx context.Context) ([]Announcement, error) { var resp []Announcement - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getNewAnnouncements, nil, &resp) } // GetPosition gets the data of all positions in the requested instrument name -func (d *Deribit) GetPosition(ctx context.Context, instrument string) (*PositionData, error) { +func (e *Exchange) GetPosition(ctx context.Context, instrument string) (*PositionData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err } var resp *PositionData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getPosition, params, &resp) } // GetSubAccounts gets all subaccounts' data -func (d *Deribit) GetSubAccounts(ctx context.Context, withPortfolio bool) ([]SubAccountData, error) { +func (e *Exchange) GetSubAccounts(ctx context.Context, withPortfolio bool) ([]SubAccountData, error) { params := url.Values{} if withPortfolio { params.Set("with_portfolio", "true") } var resp []SubAccountData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getSubAccounts, params, &resp) } // GetSubAccountDetails retrieves sub accounts detail information. -func (d *Deribit) GetSubAccountDetails(ctx context.Context, ccy currency.Code, withOpenOrders bool) ([]SubAccountDetail, error) { +func (e *Exchange) GetSubAccountDetails(ctx context.Context, ccy currency.Code, withOpenOrders bool) ([]SubAccountDetail, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1188,11 +1188,11 @@ func (d *Deribit) GetSubAccountDetails(ctx context.Context, ccy currency.Code, w params.Set("with_open_orders", "true") } var resp []SubAccountDetail - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getSubAccountDetails, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getSubAccountDetails, params, &resp) } // GetPositions gets positions data of the user account -func (d *Deribit) GetPositions(ctx context.Context, ccy currency.Code, kind string) ([]PositionData, error) { +func (e *Exchange) GetPositions(ctx context.Context, ccy currency.Code, kind string) ([]PositionData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1202,12 +1202,12 @@ func (d *Deribit) GetPositions(ctx context.Context, ccy currency.Code, kind stri params.Set("kind", kind) } var resp []PositionData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getPositions, params, &resp) } // GetTransactionLog gets transaction logs' data -func (d *Deribit) GetTransactionLog(ctx context.Context, ccy currency.Code, query string, startTime, endTime time.Time, count, continuation int64) (*TransactionsData, error) { +func (e *Exchange) GetTransactionLog(ctx context.Context, ccy currency.Code, query string, startTime, endTime time.Time, count, continuation int64) (*TransactionsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1229,46 +1229,46 @@ func (d *Deribit) GetTransactionLog(ctx context.Context, ccy currency.Code, quer params.Set("continuation", strconv.FormatInt(continuation, 10)) } var resp *TransactionsData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getTransactionLog, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getTransactionLog, params, &resp) } // GetUserLocks retrieves information about locks on user account. -func (d *Deribit) GetUserLocks(ctx context.Context) ([]UserLock, error) { +func (e *Exchange) GetUserLocks(ctx context.Context) ([]UserLock, error) { var resp []UserLock - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserLocks, nil, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserLocks, nil, &resp) } // ListAPIKeys lists all the api keys associated with a user account -func (d *Deribit) ListAPIKeys(ctx context.Context, tfa string) ([]APIKeyData, error) { +func (e *Exchange) ListAPIKeys(ctx context.Context, tfa string) ([]APIKeyData, error) { params := url.Values{} if tfa != "" { params.Set("tfa", tfa) } var resp []APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, listAPIKeys, params, &resp) } // GetCustodyAccounts retrieves user custody accounts list. -func (d *Deribit) GetCustodyAccounts(ctx context.Context, ccy currency.Code) ([]CustodyAccount, error) { +func (e *Exchange) GetCustodyAccounts(ctx context.Context, ccy currency.Code) ([]CustodyAccount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp []CustodyAccount - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, listCustodyAccounts, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, listCustodyAccounts, params, &resp) } // RemoveAPIKey removes api key vid ID -func (d *Deribit) RemoveAPIKey(ctx context.Context, id int64) error { +func (e *Exchange) RemoveAPIKey(ctx context.Context, id int64) error { if id <= 0 { return fmt.Errorf("%w, invalid api key id", errInvalidID) } params := url.Values{} params.Set("id", strconv.FormatInt(id, 10)) var resp any - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, removeAPIKey, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, removeAPIKey, params, &resp) if err != nil { return err } @@ -1279,11 +1279,11 @@ func (d *Deribit) RemoveAPIKey(ctx context.Context, id int64) error { } // RemoveSubAccount removes a subaccount given its id -func (d *Deribit) RemoveSubAccount(ctx context.Context, subAccountID int64) error { +func (e *Exchange) RemoveSubAccount(ctx context.Context, subAccountID int64) error { params := url.Values{} params.Set("subaccount_id", strconv.FormatInt(subAccountID, 10)) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, removeSubAccount, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, removeSubAccount, params, &resp) if err != nil { return err } @@ -1294,26 +1294,26 @@ func (d *Deribit) RemoveSubAccount(ctx context.Context, subAccountID int64) erro } // ResetAPIKey resets the api key to its default settings -func (d *Deribit) ResetAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { +func (e *Exchange) ResetAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } params := url.Values{} params.Set("id", strconv.FormatInt(id, 10)) var resp *APIKeyData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, resetAPIKey, params, &resp) } // SetAnnouncementAsRead sets an announcement as read -func (d *Deribit) SetAnnouncementAsRead(ctx context.Context, id int64) error { +func (e *Exchange) SetAnnouncementAsRead(ctx context.Context, id int64) error { if id <= 0 { return fmt.Errorf("%w, invalid announcement id", errInvalidID) } params := url.Values{} params.Set("announcement_id", strconv.FormatInt(id, 10)) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setAnnouncementAsRead, params, &resp) if err != nil { return err @@ -1325,7 +1325,7 @@ func (d *Deribit) SetAnnouncementAsRead(ctx context.Context, id int64) error { } // SetEmailForSubAccount links an email given to the designated subaccount -func (d *Deribit) SetEmailForSubAccount(ctx context.Context, sid int64, email string) error { +func (e *Exchange) SetEmailForSubAccount(ctx context.Context, sid int64, email string) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1336,7 +1336,7 @@ func (d *Deribit) SetEmailForSubAccount(ctx context.Context, sid int64, email st params.Set("sid", strconv.FormatInt(sid, 10)) params.Set("email", email) var resp any - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setEmailForSubAccount, params, &resp) if err != nil { return err @@ -1348,14 +1348,14 @@ func (d *Deribit) SetEmailForSubAccount(ctx context.Context, sid int64, email st } // SetEmailLanguage sets a requested language for an email -func (d *Deribit) SetEmailLanguage(ctx context.Context, language string) error { +func (e *Exchange) SetEmailLanguage(ctx context.Context, language string) error { if language == "" { return errLanguageIsRequired } params := url.Values{} params.Set("language", language) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setEmailLanguage, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setEmailLanguage, params, &resp) if err != nil { return err } @@ -1368,7 +1368,7 @@ func (d *Deribit) SetEmailLanguage(ctx context.Context, language string) error { // SetSelfTradingConfig configure self trading behavior // mode: Self trading prevention behavior. Possible values: 'reject_taker', 'cancel_maker' // extended_to_subaccounts: If value is true trading is prevented between subaccounts of given account -func (d *Deribit) SetSelfTradingConfig(ctx context.Context, mode string, extendedToSubaccounts bool) (string, error) { +func (e *Exchange) SetSelfTradingConfig(ctx context.Context, mode string, extendedToSubaccounts bool) (string, error) { if mode == "" { return "", errTradeModeIsRequired } @@ -1380,11 +1380,11 @@ func (d *Deribit) SetSelfTradingConfig(ctx context.Context, mode string, extende params.Set("extended_to_subaccounts", "false") } var resp string - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setSelfTradingConfig, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setSelfTradingConfig, params, &resp) } // ToggleNotificationsFromSubAccount toggles the notifications from a subaccount specified -func (d *Deribit) ToggleNotificationsFromSubAccount(ctx context.Context, sid int64, state bool) error { +func (e *Exchange) ToggleNotificationsFromSubAccount(ctx context.Context, sid int64, state bool) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1392,7 +1392,7 @@ func (d *Deribit) ToggleNotificationsFromSubAccount(ctx context.Context, sid int params.Set("sid", strconv.FormatInt(sid, 10)) params.Set("state", strconv.FormatBool(state)) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, toggleNotificationsFromSubAccount, params, &resp) if err != nil { return err @@ -1404,7 +1404,7 @@ func (d *Deribit) ToggleNotificationsFromSubAccount(ctx context.Context, sid int } // TogglePortfolioMargining toggle between SM and PM models. -func (d *Deribit) TogglePortfolioMargining(ctx context.Context, userID int64, enabled, dryRun bool) ([]TogglePortfolioMarginResponse, error) { +func (e *Exchange) TogglePortfolioMargining(ctx context.Context, userID int64, enabled, dryRun bool) ([]TogglePortfolioMarginResponse, error) { if userID == 0 { return nil, errUserIDRequired } @@ -1415,11 +1415,11 @@ func (d *Deribit) TogglePortfolioMargining(ctx context.Context, userID int64, en params.Set("dry_run", "true") } var resp []TogglePortfolioMarginResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, togglePortfolioMargining, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, togglePortfolioMargining, params, &resp) } // ToggleSubAccountLogin toggles access for subaccount login -func (d *Deribit) ToggleSubAccountLogin(ctx context.Context, subAccountUserID int64, state bool) error { +func (e *Exchange) ToggleSubAccountLogin(ctx context.Context, subAccountUserID int64, state bool) error { if subAccountUserID <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1427,7 +1427,7 @@ func (d *Deribit) ToggleSubAccountLogin(ctx context.Context, subAccountUserID in params.Set("sid", strconv.FormatInt(subAccountUserID, 10)) params.Set("state", strconv.FormatBool(state)) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, toggleSubAccountLogin, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, toggleSubAccountLogin, params, &resp) if err != nil { return err } @@ -1438,7 +1438,7 @@ func (d *Deribit) ToggleSubAccountLogin(ctx context.Context, subAccountUserID in } // SubmitBuy submits a private buy request through the websocket connection. -func (d *Deribit) SubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) SubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w parameter is required", common.ErrNilPointer) } @@ -1484,12 +1484,12 @@ func (d *Deribit) SubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) (*P params.Set("advanced", arg.Advanced) } var resp *PrivateTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitBuy, params, &resp) } // SubmitSell submits a sell request with the parameters provided -func (d *Deribit) SubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) SubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w argument is required", common.ErrNilPointer) } @@ -1536,11 +1536,11 @@ func (d *Deribit) SubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) (* params.Set("advanced", arg.Advanced) } var resp *PrivateTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, matchingEPL, http.MethodGet, submitSell, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, matchingEPL, http.MethodGet, submitSell, params, &resp) } // SubmitEdit submits an edit order request -func (d *Deribit) SubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) SubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w parameter is required", common.ErrNilPointer) } @@ -1575,11 +1575,11 @@ func (d *Deribit) SubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) (* params.Set("price", strconv.FormatFloat(arg.Price, 'f', -1, 64)) } var resp *PrivateTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitEdit, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitEdit, params, &resp) } // EditOrderByLabel submits an edit order request sorted via label -func (d *Deribit) EditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) EditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w parameter is required", common.ErrNilPointer) } @@ -1613,36 +1613,36 @@ func (d *Deribit) EditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellPara params.Set("advanced", arg.Advanced) } var resp *PrivateTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, editByLabel, params, &resp) } // SubmitCancel sends a request to cancel the order via its orderID -func (d *Deribit) SubmitCancel(ctx context.Context, orderID string) (*PrivateCancelData, error) { +func (e *Exchange) SubmitCancel(ctx context.Context, orderID string) (*PrivateCancelData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } params := url.Values{} params.Set("order_id", orderID) var resp *PrivateCancelData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancel, params, &resp) } // SubmitCancelAll sends a request to cancel all user orders in all currencies and instruments -func (d *Deribit) SubmitCancelAll(ctx context.Context, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelAll(ctx context.Context, detailed bool) (*MultipleCancelResponse, error) { params := url.Values{} if detailed { params.Set("detailed", "true") } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelAll, params, &resp) } // SubmitCancelAllByCurrency sends a request to cancel all user orders for the specified currency // returns the total number of successfully cancelled orders -func (d *Deribit) SubmitCancelAllByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelAllByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1658,14 +1658,14 @@ func (d *Deribit) SubmitCancelAllByCurrency(ctx context.Context, ccy currency.Co params.Set("detailed", "true") } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelAllByCurrency, params, &resp) } // SubmitCancelAllByKind cancels all orders in currency(currencies), optionally filtered by instrument kind and/or order type. // 'kind' instrument kind . Possible values: 'future', 'option', 'spot', 'future_combo', 'option_combo', 'combo', 'any' // returns the total number of successfully cancelled orders -func (d *Deribit) SubmitCancelAllByKind(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelAllByKind(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1681,12 +1681,12 @@ func (d *Deribit) SubmitCancelAllByKind(ctx context.Context, ccy currency.Code, params.Set("detailed", "true") } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, matchingEPL, http.MethodGet, submitCancelAllByKind, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, matchingEPL, http.MethodGet, submitCancelAllByKind, params, &resp) } // SubmitCancelAllByInstrument sends a request to cancel all user orders for the specified instrument // returns the total number of successfully cancelled orders -func (d *Deribit) SubmitCancelAllByInstrument(ctx context.Context, instrument, orderType string, detailed, includeCombos bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelAllByInstrument(ctx context.Context, instrument, orderType string, detailed, includeCombos bool) (*MultipleCancelResponse, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -1701,13 +1701,13 @@ func (d *Deribit) SubmitCancelAllByInstrument(ctx context.Context, instrument, o params.Set("include_combos", "true") } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelAllByInstrument, params, &resp) } // SubmitCancelByLabel sends a request to cancel all user orders for the specified label // returns the total number of successfully cancelled orders -func (d *Deribit) SubmitCancelByLabel(ctx context.Context, label string, ccy currency.Code, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelByLabel(ctx context.Context, label string, ccy currency.Code, detailed bool) (*MultipleCancelResponse, error) { params := url.Values{} params.Set("label", label) if !ccy.IsEmpty() { @@ -1717,7 +1717,7 @@ func (d *Deribit) SubmitCancelByLabel(ctx context.Context, label string, ccy cur params.Set("detailed", "true") } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelByLabel, params, &resp) } @@ -1729,7 +1729,7 @@ func (d *Deribit) SubmitCancelByLabel(ctx context.Context, label string, ccy cur // // possible cancel_type values are delta, 'quote_set_id', 'instrument', 'instrument_kind', 'currency', and 'all' // possible kind values are future 'option', 'spot', 'future_combo', 'option_combo', 'combo', and 'any' -func (d *Deribit) SubmitCancelQuotes(ctx context.Context, ccy currency.Code, minDelta, maxDelta float64, cancelType, quoteSetID, instrumentName, kind string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) SubmitCancelQuotes(ctx context.Context, ccy currency.Code, minDelta, maxDelta float64, cancelType, quoteSetID, instrumentName, kind string, detailed bool) (*MultipleCancelResponse, error) { if cancelType == "" { return nil, errors.New("cancel type is required") } @@ -1758,11 +1758,11 @@ func (d *Deribit) SubmitCancelQuotes(ctx context.Context, ccy currency.Code, min params.Set("kind", kind) } var resp *MultipleCancelResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelQuotes, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitCancelQuotes, params, &resp) } // SubmitClosePosition sends a request to cancel all user orders for the specified label -func (d *Deribit) SubmitClosePosition(ctx context.Context, instrument, orderType string, price float64) (*PrivateTradeData, error) { +func (e *Exchange) SubmitClosePosition(ctx context.Context, instrument, orderType string, price float64) (*PrivateTradeData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -1772,12 +1772,12 @@ func (d *Deribit) SubmitClosePosition(ctx context.Context, instrument, orderType } params.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) var resp *PrivateTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, submitClosePosition, params, &resp) } // GetMargins sends a request to fetch account margins data -func (d *Deribit) GetMargins(ctx context.Context, instrument string, amount, price float64) (*MarginsData, error) { +func (e *Exchange) GetMargins(ctx context.Context, instrument string, amount, price float64) (*MarginsData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -1791,24 +1791,24 @@ func (d *Deribit) GetMargins(ctx context.Context, instrument string, amount, pri params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) params.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) var resp *MarginsData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getMargins, params, &resp) } // GetMMPConfig sends a request to fetch the config for MMP of the requested currency -func (d *Deribit) GetMMPConfig(ctx context.Context, ccy currency.Code) (*MMPConfigData, error) { +func (e *Exchange) GetMMPConfig(ctx context.Context, ccy currency.Code) (*MMPConfigData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp *MMPConfigData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getMMPConfig, params, &resp) } // GetOpenOrdersByCurrency retrieves open orders data sorted by requested params -func (d *Deribit) GetOpenOrdersByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string) ([]OrderData, error) { +func (e *Exchange) GetOpenOrdersByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1821,12 +1821,12 @@ func (d *Deribit) GetOpenOrdersByCurrency(ctx context.Context, ccy currency.Code params.Set("type", orderType) } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOpenOrdersByCurrency, params, &resp) } // GetOpenOrdersByLabel retrieves open orders using label and currency -func (d *Deribit) GetOpenOrdersByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { +func (e *Exchange) GetOpenOrdersByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1836,11 +1836,11 @@ func (d *Deribit) GetOpenOrdersByLabel(ctx context.Context, ccy currency.Code, l params.Set("label", label) } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOpenOrdersByLabel, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOpenOrdersByLabel, params, &resp) } // GetOpenOrdersByInstrument sends a request to fetch open orders data sorted by requested params -func (d *Deribit) GetOpenOrdersByInstrument(ctx context.Context, instrument, orderType string) ([]OrderData, error) { +func (e *Exchange) GetOpenOrdersByInstrument(ctx context.Context, instrument, orderType string) ([]OrderData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -1849,11 +1849,11 @@ func (d *Deribit) GetOpenOrdersByInstrument(ctx context.Context, instrument, ord params.Set("type", orderType) } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOpenOrdersByInstrument, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOpenOrdersByInstrument, params, &resp) } // GetOrderHistoryByCurrency sends a request to fetch order history according to given params and currency -func (d *Deribit) GetOrderHistoryByCurrency(ctx context.Context, ccy currency.Code, kind string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { +func (e *Exchange) GetOrderHistoryByCurrency(ctx context.Context, ccy currency.Code, kind string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1875,12 +1875,12 @@ func (d *Deribit) GetOrderHistoryByCurrency(ctx context.Context, ccy currency.Co params.Set("include_unfilled", "true") } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOrderHistoryByCurrency, params, &resp) } // GetOrderHistoryByInstrument sends a request to fetch order history according to given params and instrument -func (d *Deribit) GetOrderHistoryByInstrument(ctx context.Context, instrument string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { +func (e *Exchange) GetOrderHistoryByInstrument(ctx context.Context, instrument string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -1898,12 +1898,12 @@ func (d *Deribit) GetOrderHistoryByInstrument(ctx context.Context, instrument st params.Set("include_unfilled", "true") } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, getOrderHistoryByInstrument, params, &resp) } // GetOrderMarginsByID sends a request to fetch order margins data according to their ids -func (d *Deribit) GetOrderMarginsByID(ctx context.Context, ids []string) ([]InitialMarginInfo, error) { +func (e *Exchange) GetOrderMarginsByID(ctx context.Context, ids []string) ([]InitialMarginInfo, error) { if len(ids) == 0 { return nil, fmt.Errorf("%w, order ids cannot be empty", errInvalidID) } @@ -1912,24 +1912,24 @@ func (d *Deribit) GetOrderMarginsByID(ctx context.Context, ids []string) ([]Init params.Add("ids[]", ids[a]) } var resp []InitialMarginInfo - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, getOrderMarginByIDs, params, &resp) } // GetOrderState sends a request to fetch order state of the order id provided -func (d *Deribit) GetOrderState(ctx context.Context, orderID string) (*OrderData, error) { +func (e *Exchange) GetOrderState(ctx context.Context, orderID string) (*OrderData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } params := url.Values{} params.Set("order_id", orderID) var resp *OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOrderState, params, &resp) } // GetOrderStateByLabel retrieves an order state by label and currency -func (d *Deribit) GetOrderStateByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { +func (e *Exchange) GetOrderStateByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1939,11 +1939,11 @@ func (d *Deribit) GetOrderStateByLabel(ctx context.Context, ccy currency.Code, l params.Set("label", label) } var resp []OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOrderStateByLabel, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getOrderStateByLabel, params, &resp) } // GetTriggerOrderHistory sends a request to fetch order state of the order id provided -func (d *Deribit) GetTriggerOrderHistory(ctx context.Context, ccy currency.Code, instrumentName, continuation string, count int64) (*OrderData, error) { +func (e *Exchange) GetTriggerOrderHistory(ctx context.Context, ccy currency.Code, instrumentName, continuation string, count int64) (*OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1959,12 +1959,12 @@ func (d *Deribit) GetTriggerOrderHistory(ctx context.Context, ccy currency.Code, params.Set("count", strconv.FormatInt(count, 10)) } var resp *OrderData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getTriggerOrderHistory, params, &resp) } // GetUserTradesByCurrency sends a request to fetch user trades sorted by currency -func (d *Deribit) GetUserTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*UserTradesData, error) { +func (e *Exchange) GetUserTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*UserTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1989,12 +1989,12 @@ func (d *Deribit) GetUserTradesByCurrency(ctx context.Context, ccy currency.Code params.Set("include_old", "true") } var resp *UserTradesData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByCurrency, params, &resp) } // GetUserTradesByCurrencyAndTime sends a request to fetch user trades sorted by currency and time -func (d *Deribit) GetUserTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { +func (e *Exchange) GetUserTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2016,11 +2016,11 @@ func (d *Deribit) GetUserTradesByCurrencyAndTime(ctx context.Context, ccy curren params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) } var resp *UserTradesData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByCurrencyAndTime, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByCurrencyAndTime, params, &resp) } // GetUserTradesByInstrument sends a request to fetch user trades sorted by instrument -func (d *Deribit) GetUserTradesByInstrument(ctx context.Context, instrument, sorting string, startSeq, endSeq, count int64, includeOld bool) (*UserTradesData, error) { +func (e *Exchange) GetUserTradesByInstrument(ctx context.Context, instrument, sorting string, startSeq, endSeq, count int64, includeOld bool) (*UserTradesData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -2041,12 +2041,12 @@ func (d *Deribit) GetUserTradesByInstrument(ctx context.Context, instrument, sor params.Set("include_old", "true") } var resp *UserTradesData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByInstrument, params, &resp) } // GetUserTradesByInstrumentAndTime sends a request to fetch user trades sorted by instrument and time -func (d *Deribit) GetUserTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { +func (e *Exchange) GetUserTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -2064,12 +2064,12 @@ func (d *Deribit) GetUserTradesByInstrumentAndTime(ctx context.Context, instrume params.Set("start_timestamp", strconv.FormatInt(startTime.UnixMilli(), 10)) params.Set("end_timestamp", strconv.FormatInt(endTime.UnixMilli(), 10)) var resp *UserTradesData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByInstrumentAndTime, params, &resp) } // GetUserTradesByOrder sends a request to get user trades fetched by orderID -func (d *Deribit) GetUserTradesByOrder(ctx context.Context, orderID, sorting string) (*UserTradesData, error) { +func (e *Exchange) GetUserTradesByOrder(ctx context.Context, orderID, sorting string) (*UserTradesData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } @@ -2079,19 +2079,19 @@ func (d *Deribit) GetUserTradesByOrder(ctx context.Context, orderID, sorting str params.Set("sorting", sorting) } var resp *UserTradesData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getUserTradesByOrder, params, &resp) } // ResetMMP sends a request to reset MMP for a currency provided -func (d *Deribit) ResetMMP(ctx context.Context, ccy currency.Code) error { +func (e *Exchange) ResetMMP(ctx context.Context, ccy currency.Code) error { if ccy.IsEmpty() { return currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, resetMMP, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, resetMMP, params, &resp) if err != nil { return err } @@ -2102,7 +2102,7 @@ func (d *Deribit) ResetMMP(ctx context.Context, ccy currency.Code) error { } // SendRequestForQuote sends RFQ on a given instrument. -func (d *Deribit) SendRequestForQuote(ctx context.Context, instrumentName string, amount float64, side order.Side) error { +func (e *Exchange) SendRequestForQuote(ctx context.Context, instrumentName string, amount float64, side order.Side) error { params, err := checkInstrument(instrumentName) if err != nil { return err @@ -2114,7 +2114,7 @@ func (d *Deribit) SendRequestForQuote(ctx context.Context, instrumentName string params.Set("side", side.String()) } var resp string - err = d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, sendRFQ, params, &resp) + err = e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, sendRFQ, params, &resp) if err != nil { return err } @@ -2125,13 +2125,13 @@ func (d *Deribit) SendRequestForQuote(ctx context.Context, instrumentName string } // SetMMPConfig sends a request to set the given parameter values to the mmp config for the provided currency -func (d *Deribit) SetMMPConfig(ctx context.Context, ccy currency.Code, interval kline.Interval, frozenTime int64, quantityLimit, deltaLimit float64) error { +func (e *Exchange) SetMMPConfig(ctx context.Context, ccy currency.Code, interval kline.Interval, frozenTime int64, quantityLimit, deltaLimit float64) error { if ccy.IsEmpty() { return currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) - intervalString, err := d.GetResolutionFromInterval(interval) + intervalString, err := e.GetResolutionFromInterval(interval) if err != nil { return err } @@ -2144,7 +2144,7 @@ func (d *Deribit) SetMMPConfig(ctx context.Context, ccy currency.Code, interval params.Set("delta_limit", strconv.FormatFloat(deltaLimit, 'f', -1, 64)) } var resp string - err = d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + err = e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, setMMPConfig, params, &resp) if err != nil { return err @@ -2156,7 +2156,7 @@ func (d *Deribit) SetMMPConfig(ctx context.Context, ccy currency.Code, interval } // GetSettlementHistoryByInstrument sends a request to fetch settlement history data sorted by instrument -func (d *Deribit) GetSettlementHistoryByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { +func (e *Exchange) GetSettlementHistoryByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { params, err := checkInstrument(instrument) if err != nil { return nil, err @@ -2174,12 +2174,12 @@ func (d *Deribit) GetSettlementHistoryByInstrument(ctx context.Context, instrume params.Set("search_start_timestamp", strconv.FormatInt(searchStartTimeStamp.UnixMilli(), 10)) } var resp *PrivateSettlementsHistoryData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getSettlementHistoryByInstrument, params, &resp) } // GetSettlementHistoryByCurency sends a request to fetch settlement history data sorted by currency -func (d *Deribit) GetSettlementHistoryByCurency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { +func (e *Exchange) GetSettlementHistoryByCurency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2198,22 +2198,22 @@ func (d *Deribit) GetSettlementHistoryByCurency(ctx context.Context, ccy currenc params.Set("search_start_timestamp", strconv.FormatInt(searchStartTimeStamp.UnixMilli(), 10)) } var resp *PrivateSettlementsHistoryData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getSettlementHistoryByCurrency, params, &resp) } // SendHTTPAuthRequest sends an authenticated request to deribit api -func (d *Deribit) SendHTTPAuthRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, method, path string, params url.Values, result any) error { - endpoint, err := d.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPAuthRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, method, path string, params url.Values, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } - creds, err := d.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return fmt.Errorf("%w, %v", request.ErrAuthRequestFailed, err) } req := method + "\n" + deribitAPIVersion + "/" + common.EncodeURLValues(path, params) + "\n\n" - n := d.Requester.GetNonce(nonce.UnixNano).String() + n := e.Requester.GetNonce(nonce.UnixNano).String() ts := strconv.FormatInt(time.Now().UnixMilli(), 10) tsReq := []byte(ts + "\n" + n + "\n" + req) hmac, err := crypto.GetHMAC(crypto.HashSHA256, tsReq, []byte(creds.Secret)) @@ -2230,15 +2230,15 @@ func (d *Deribit) SendHTTPAuthRequest(ctx context.Context, ep exchange.URL, epl Data json.RawMessage `json:"result"` Error ErrInfo `json:"error"` } - err = d.SendPayload(ctx, epl, func() (*request.Item, error) { + err = e.SendPayload(ctx, epl, func() (*request.Item, error) { return &request.Item{ Method: method, Path: endpoint + deribitAPIVersion + "/" + common.EncodeURLValues(path, params), Headers: headers, Result: &tempData, - Verbose: d.Verbose, - HTTPDebugging: d.HTTPDebugging, - HTTPRecording: d.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -2258,7 +2258,7 @@ func (d *Deribit) SendHTTPAuthRequest(ctx context.Context, ep exchange.URL, epl // GetComboIDs Retrieves available combos. // This method can be used to get the list of all combos, or only the list of combos in the given state. -func (d *Deribit) GetComboIDs(ctx context.Context, ccy currency.Code, state string) ([]string, error) { +func (e *Exchange) GetComboIDs(ctx context.Context, ccy currency.Code, state string) ([]string, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2268,33 +2268,33 @@ func (d *Deribit) GetComboIDs(ctx context.Context, ccy currency.Code, state stri params.Set("state", state) } var resp []string - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getComboIDs, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getComboIDs, params), &resp) } // GetComboDetails retrieves information about a combo -func (d *Deribit) GetComboDetails(ctx context.Context, comboID string) (*ComboDetail, error) { +func (e *Exchange) GetComboDetails(ctx context.Context, comboID string) (*ComboDetail, error) { if comboID == "" { return nil, errInvalidComboID } params := url.Values{} params.Set("combo_id", comboID) var resp *ComboDetail - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getComboDetails, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getComboDetails, params), &resp) } // GetCombos retrieves information about active combos -func (d *Deribit) GetCombos(ctx context.Context, ccy currency.Code) ([]ComboDetail, error) { +func (e *Exchange) GetCombos(ctx context.Context, ccy currency.Code) ([]ComboDetail, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp []ComboDetail - return resp, d.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getCombos, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, nonMatchingEPL, common.EncodeURLValues(getCombos, params), &resp) } // CreateCombo verifies and creates a combo book or returns an existing combo matching given trades -func (d *Deribit) CreateCombo(ctx context.Context, args []ComboParam) (*ComboDetail, error) { +func (e *Exchange) CreateCombo(ctx context.Context, args []ComboParam) (*ComboDetail, error) { if len(args) == 0 { return nil, errNoArgumentPassed } @@ -2320,13 +2320,13 @@ func (d *Deribit) CreateCombo(ctx context.Context, args []ComboParam) (*ComboDet params := url.Values{} params.Set("trades", string(argsByte)) var resp *ComboDetail - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, createCombos, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, createCombos, params, &resp) } // ExecuteBlockTrade executes a block trade request // The whole request have to be exact the same as in private/verify_block_trade, only role field should be set appropriately - it basically means that both sides have to agree on the same timestamp, nonce, trades fields and server will assure that role field is different between sides (each party accepted own role). // Using the same timestamp and nonce by both sides in private/verify_block_trade assures that even if unintentionally both sides execute given block trade with valid counterparty_signature, the given block trade will be executed only once -func (d *Deribit) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { +func (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { if nonce == "" { return nil, errMissingNonce } @@ -2351,7 +2351,7 @@ func (d *Deribit) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, return nil, fmt.Errorf("%w, trade price can't be negative", errInvalidPrice) } } - signature, err := d.VerifyBlockTrade(ctx, timestampMS, nonce, role, ccy, trades) + signature, err := e.VerifyBlockTrade(ctx, timestampMS, nonce, role, ccy, trades) if err != nil { return nil, err } @@ -2369,11 +2369,11 @@ func (d *Deribit) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, params.Set("counterparty_signature", signature) params.Set("timestamp", strconv.FormatInt(timestampMS.UnixMilli(), 10)) var resp []BlockTradeResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, executeBlockTrades, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, executeBlockTrades, params, &resp) } // VerifyBlockTrade verifies and creates block trade signature -func (d *Deribit) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { +func (e *Exchange) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { if nonce == "" { return "", errMissingNonce } @@ -2416,18 +2416,18 @@ func (d *Deribit) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, n resp := &struct { Signature string `json:"signature"` }{} - return resp.Signature, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, verifyBlockTrades, params, resp) + return resp.Signature, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, verifyBlockTrades, params, resp) } // InvalidateBlockTradeSignature user at any time (before the private/execute_block_trade is called) can invalidate its own signature effectively cancelling block trade -func (d *Deribit) InvalidateBlockTradeSignature(ctx context.Context, signature string) error { +func (e *Exchange) InvalidateBlockTradeSignature(ctx context.Context, signature string) error { if signature == "" { return errMissingSignature } params := url.Values{} params.Set("signature", signature) var resp string - err := d.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, invalidateBlockTradesSignature, params, &resp) + err := e.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, invalidateBlockTradesSignature, params, &resp) if err != nil { return err } @@ -2438,27 +2438,27 @@ func (d *Deribit) InvalidateBlockTradeSignature(ctx context.Context, signature s } // GetUserBlockTrade returns information about users block trade -func (d *Deribit) GetUserBlockTrade(ctx context.Context, id string) ([]BlockTradeData, error) { +func (e *Exchange) GetUserBlockTrade(ctx context.Context, id string) ([]BlockTradeData, error) { if id == "" { return nil, errMissingBlockTradeID } params := url.Values{} params.Set("id", id) var resp []BlockTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getBlockTrades, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getBlockTrades, params, &resp) } // GetTime retrieves the current time (in milliseconds). This API endpoint can be used to check the clock skew between your software and Deribit's systems. -func (d *Deribit) GetTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetTime(ctx context.Context) (time.Time, error) { var timestamp types.Time - if err := d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, "public/get_time", ×tamp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, "public/get_time", ×tamp); err != nil { return time.Time{}, err } return timestamp.Time(), nil } // GetLastBlockTradesByCurrency returns list of last users block trades -func (d *Deribit) GetLastBlockTradesByCurrency(ctx context.Context, ccy currency.Code, startID, endID string, count int64) ([]BlockTradeData, error) { +func (e *Exchange) GetLastBlockTradesByCurrency(ctx context.Context, ccy currency.Code, startID, endID string, count int64) ([]BlockTradeData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2474,11 +2474,11 @@ func (d *Deribit) GetLastBlockTradesByCurrency(ctx context.Context, ccy currency params.Set("count", strconv.FormatInt(count, 10)) } var resp []BlockTradeData - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getLastBlockTradesByCurrency, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, getLastBlockTradesByCurrency, params, &resp) } // MovePositions moves positions from source subaccount to target subaccount -func (d *Deribit) MovePositions(ctx context.Context, ccy currency.Code, sourceSubAccountUID, targetSubAccountUID int64, trades []BlockTradeParam) ([]BlockTradeMoveResponse, error) { +func (e *Exchange) MovePositions(ctx context.Context, ccy currency.Code, sourceSubAccountUID, targetSubAccountUID int64, trades []BlockTradeParam) ([]BlockTradeMoveResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2509,11 +2509,11 @@ func (d *Deribit) MovePositions(ctx context.Context, ccy currency.Code, sourceSu params.Set("target_uid", strconv.FormatInt(targetSubAccountUID, 10)) params.Set("trades", string(values)) var resp []BlockTradeMoveResponse - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, movePositions, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, nonMatchingEPL, http.MethodGet, movePositions, params, &resp) } // SimulateBlockTrade checks if a block trade can be executed -func (d *Deribit) SimulateBlockTrade(ctx context.Context, role string, trades []BlockTradeParam) (bool, error) { +func (e *Exchange) SimulateBlockTrade(ctx context.Context, role string, trades []BlockTradeParam) (bool, error) { if role != roleMaker && role != roleTaker { return false, errInvalidTradeRole } @@ -2543,28 +2543,28 @@ func (d *Deribit) SimulateBlockTrade(ctx context.Context, role string, trades [] params.Set("role", role) params.Set("trades", string(values)) var resp bool - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, simulateBlockPosition, params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestFutures, matchingEPL, http.MethodGet, simulateBlockPosition, params, &resp) } // GetLockedStatus retrieves information about locked currencies -func (d *Deribit) GetLockedStatus(ctx context.Context) (*LockedCurrenciesStatus, error) { +func (e *Exchange) GetLockedStatus(ctx context.Context) (*LockedCurrenciesStatus, error) { var resp *LockedCurrenciesStatus - return resp, d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, "public/status", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, "public/status", &resp) } // EnableCancelOnDisconnect enable Cancel On Disconnect for the connection. // After enabling Cancel On Disconnect all orders created by the connection will be removed when the connection is closed. -func (d *Deribit) EnableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { +func (e *Exchange) EnableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { params := url.Values{} if scope != "" { params.Set("scope", scope) } var resp string - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, "private/enable_cancel_on_disconnect", params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, "private/enable_cancel_on_disconnect", params, &resp) } // ExchangeToken generates a token for a new subject id. This method can be used to switch between subaccounts. -func (d *Deribit) ExchangeToken(ctx context.Context, refreshToken string, subjectID int64) (*RefreshTokenInfo, error) { +func (e *Exchange) ExchangeToken(ctx context.Context, refreshToken string, subjectID int64) (*RefreshTokenInfo, error) { if refreshToken == "" { return nil, errRefreshTokenRequired } @@ -2575,11 +2575,11 @@ func (d *Deribit) ExchangeToken(ctx context.Context, refreshToken string, subjec params.Set("refresh_token", refreshToken) params.Set("subject_id", strconv.FormatInt(subjectID, 10)) var resp *RefreshTokenInfo - return resp, d.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, "public/exchange_token", params, &resp) + return resp, e.SendHTTPAuthRequest(ctx, exchange.RestSpot, nonMatchingEPL, http.MethodGet, "public/exchange_token", params, &resp) } // ForkToken generates a token for a new named session. This method can be used only with session scoped tokens. -func (d *Deribit) ForkToken(ctx context.Context, refreshToken, sessionName string) (*RefreshTokenInfo, error) { +func (e *Exchange) ForkToken(ctx context.Context, refreshToken, sessionName string) (*RefreshTokenInfo, error) { if refreshToken == "" { return nil, errRefreshTokenRequired } @@ -2590,11 +2590,11 @@ func (d *Deribit) ForkToken(ctx context.Context, refreshToken, sessionName strin params.Set("refresh_token", refreshToken) params.Set("session_name", sessionName) var resp *RefreshTokenInfo - return resp, d.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues("public/fork_token", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, nonMatchingEPL, common.EncodeURLValues("public/fork_token", params), &resp) } // GetAssetKind returns the asset type (kind) string representation. -func (d *Deribit) GetAssetKind(assetType asset.Item) string { +func (e *Exchange) GetAssetKind(assetType asset.Item) string { switch assetType { case asset.Options: return "option" @@ -2608,7 +2608,7 @@ func (d *Deribit) GetAssetKind(assetType asset.Item) string { } // StringToAssetKind returns the asset type (kind) from a string representation. -func (d *Deribit) StringToAssetKind(assetType string) (asset.Item, error) { +func (e *Exchange) StringToAssetKind(assetType string) (asset.Item, error) { assetType = strings.ToLower(assetType) switch assetType { case "option": @@ -2626,7 +2626,7 @@ func (d *Deribit) StringToAssetKind(assetType string) (asset.Item, error) { // getAssetPairByInstrument is able to determine the asset type and currency pair // based on the received instrument ID -func (d *Deribit) getAssetPairByInstrument(instrument string) (currency.Pair, asset.Item, error) { +func (e *Exchange) getAssetPairByInstrument(instrument string) (currency.Pair, asset.Item, error) { if instrument == "" { return currency.EMPTYPAIR, asset.Empty, errInvalidInstrumentName } @@ -2755,7 +2755,7 @@ func getOfflineTradeFee(price, amount float64) float64 { return 0.0003 * price * amount } -func (d *Deribit) formatFuturesTradablePair(pair currency.Pair) string { +func (e *Exchange) formatFuturesTradablePair(pair currency.Pair) string { var instrumentID string if result := strings.Split(pair.String(), currency.DashDelimiter); len(result) == 3 { instrumentID = strings.Join(result[:2], currency.UnderscoreDelimiter) + currency.DashDelimiter + result[2] @@ -2770,7 +2770,7 @@ func (d *Deribit) formatFuturesTradablePair(pair currency.Pair) string { // EXPIRE is DDMMMYY // STRIKE may include a d for decimal point in linear options // TYPE is Call or Put -func (d *Deribit) optionPairToString(pair currency.Pair) string { +func (e *Exchange) optionPairToString(pair currency.Pair) string { initialDelimiter := currency.DashDelimiter q := pair.Quote.String() if strings.HasPrefix(q, "USDC") && len(q) > 11 { // Linear option diff --git a/exchanges/deribit/deribit_test.go b/exchanges/deribit/deribit_test.go index 7d69a7d140e..d8ab6685bc1 100644 --- a/exchanges/deribit/deribit_test.go +++ b/exchanges/deribit/deribit_test.go @@ -44,7 +44,7 @@ const ( ) var ( - d = &Deribit{} + e *Exchange optionsTradablePair, optionComboTradablePair, futureComboTradablePair currency.Pair spotTradablePair = currency.NewPairWithDelimiter(currencyBTC, "USDC", "_") futuresTradablePair = currency.NewPairWithDelimiter(currencyBTC, perpString, "-") @@ -52,24 +52,25 @@ var ( ) func TestMain(m *testing.M) { - if err := testexch.Setup(d); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Deribit Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - d.API.AuthenticatedSupport = true - d.API.AuthenticatedWebsocketSupport = true - d.SetCredentials(apiKey, apiSecret, "", "", "", "") - d.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) } if useTestNet { deribitWebsocketAddress = "wss://test.deribit.com/ws" + deribitAPIVersion - if err := d.Websocket.SetWebsocketURL(deribitWebsocketAddress, false, true); err != nil { + if err := e.Websocket.SetWebsocketURL(deribitWebsocketAddress, false, true); err != nil { log.Fatalf("Deribit SetWebsocketURL error: %s", err) } - for k, v := range d.API.Endpoints.GetURLMap() { + for k, v := range e.API.Endpoints.GetURLMap() { v = strings.Replace(v, "www.deribit.com", "test.deribit.com", 1) - if err := d.API.Endpoints.SetRunningURL(k, v); err != nil { + if err := e.API.Endpoints.SetRunningURL(k, v); err != nil { log.Fatalf("Deribit SetRunningURL error: %s", err) } } @@ -88,7 +89,7 @@ func TestMain(m *testing.M) { } func instantiateTradablePairs() { - if err := d.UpdateTradablePairs(context.Background(), true); err != nil { + if err := e.UpdateTradablePairs(context.Background(), true); err != nil { log.Fatalf("Failed to update tradable pairs. Error: %v", err) } @@ -99,8 +100,8 @@ func instantiateTradablePairs() { } updateTradablePair := func(assetType asset.Item, tradablePair *currency.Pair) { - if d.CurrencyPairs.IsAssetEnabled(assetType) == nil { - pairs, err := d.GetEnabledPairs(assetType) + if e.CurrencyPairs.IsAssetEnabled(assetType) == nil { + pairs, err := e.GetEnabledPairs(assetType) handleError(err, fmt.Sprintf("Failed to get enabled pairs for asset type %v", assetType)) if len(pairs) == 0 { @@ -108,7 +109,7 @@ func instantiateTradablePairs() { } if assetType == asset.Options { - *tradablePair, err = d.FormatExchangeCurrency(pairs[0], assetType) + *tradablePair, err = e.FormatExchangeCurrency(pairs[0], assetType) handleError(err, "Failed to format exchange currency for options pair") } else { *tradablePair = pairs[0] @@ -122,11 +123,11 @@ func instantiateTradablePairs() { func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := d.UpdateTicker(t.Context(), currency.Pair{}, asset.Margin) + _, err := e.UpdateTicker(t.Context(), currency.Pair{}, asset.Margin) require.ErrorIs(t, err, asset.ErrNotSupported) for assetType, cp := range assetTypeToPairsMap { - result, err := d.UpdateTicker(t.Context(), cp, assetType) + result, err := e.UpdateTicker(t.Context(), cp, assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -135,7 +136,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() for assetType, cp := range assetTypeToPairsMap { - result, err := d.UpdateOrderbook(t.Context(), cp, assetType) + result, err := e.UpdateOrderbook(t.Context(), cp, assetType) require.NoErrorf(t, err, "asset type: %v", assetType) require.NotNil(t, result) } @@ -143,10 +144,10 @@ func TestUpdateOrderbook(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := d.GetHistoricTrades(t.Context(), futureComboTradablePair, asset.FutureCombo, time.Now().Add(-time.Minute*10), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), futureComboTradablePair, asset.FutureCombo, time.Now().Add(-time.Minute*10), time.Now()) require.ErrorIs(t, err, asset.ErrNotSupported) for assetType, cp := range map[asset.Item]currency.Pair{asset.Spot: spotTradablePair, asset.Futures: futuresTradablePair} { - _, err = d.GetHistoricTrades(t.Context(), cp, assetType, time.Now().Add(-time.Minute*10), time.Now()) + _, err = e.GetHistoricTrades(t.Context(), cp, assetType, time.Now().Add(-time.Minute*10), time.Now()) require.NoErrorf(t, err, "asset type: %v", assetType) } } @@ -154,7 +155,7 @@ func TestGetHistoricTrades(t *testing.T) { func TestFetchRecentTrades(t *testing.T) { t.Parallel() for assetType, cp := range assetTypeToPairsMap { - result, err := d.GetRecentTrades(t.Context(), cp, assetType) + result, err := e.GetRecentTrades(t.Context(), cp, assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -175,7 +176,7 @@ func TestGetHistoricCandles(t *testing.T) { asset.OptionCombo: {Pair: optionComboTradablePair, Error: asset.ErrNotSupported}, } for assetType, info := range assetTypesToPairMap { - resp, err := d.GetHistoricCandles(t.Context(), info.Pair, assetType, kline.FifteenMin, start, end) + resp, err := e.GetHistoricCandles(t.Context(), info.Pair, assetType, kline.FifteenMin, start, end) require.ErrorIs(t, err, info.Error) if info.Error == nil { require.NotEmpty(t, resp) @@ -198,7 +199,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { asset.OptionCombo: {Pair: optionComboTradablePair, Error: asset.ErrNotSupported}, } for assetType, instance := range assetsToPairsMap { - resp, err := d.GetHistoricCandlesExtended(t.Context(), instance.Pair, assetType, kline.OneDay, start, end) + resp, err := e.GetHistoricCandlesExtended(t.Context(), instance.Pair, assetType, kline.OneDay, start, end) require.ErrorIs(t, err, instance.Error) if instance.Error == nil { require.NotEmpty(t, resp) @@ -208,7 +209,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) assetToPairStringMap := map[asset.Item]currency.Pair{ asset.Options: optionsTradablePair, asset.FutureCombo: futureComboTradablePair, @@ -218,14 +219,14 @@ func TestSubmitOrder(t *testing.T) { var err error var info *InstrumentData for assetType, cp := range assetToPairStringMap { - info, err = d.GetInstrument(t.Context(), d.formatPairString(assetType, cp)) + info, err = e.GetInstrument(t.Context(), e.formatPairString(assetType, cp)) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) - result, err = d.SubmitOrder( + result, err = e.SubmitOrder( t.Context(), &order.Submit{ - Exchange: d.Name, + Exchange: e.Name, Price: 10, Amount: info.ContractSize * 3, Type: order.Limit, @@ -246,17 +247,17 @@ func TestGetMarkPriceHistory(t *testing.T) { require.NoError(t, err) assert.Len(t, resp, 3) - _, err = d.GetMarkPriceHistory(t.Context(), "", time.Now().Add(-5*time.Minute), time.Now()) + _, err = e.GetMarkPriceHistory(t.Context(), "", time.Now().Add(-5*time.Minute), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) var result []MarkPriceHistory for _, ps := range []string{ - d.optionPairToString(optionsTradablePair), + e.optionPairToString(optionsTradablePair), spotTradablePair.String(), btcPerpInstrument, futureComboTradablePair.String(), } { - result, err = d.GetMarkPriceHistory(t.Context(), ps, time.Now().Add(-5*time.Minute), time.Now()) + result, err = e.GetMarkPriceHistory(t.Context(), ps, time.Now().Add(-5*time.Minute), time.Now()) require.NoErrorf(t, err, "expected nil, got %v for pair %s", err, ps) require.NotNilf(t, result, "expected result not to be nil for pair %s", ps) } @@ -264,17 +265,17 @@ func TestGetMarkPriceHistory(t *testing.T) { func TestWSRetrieveMarkPriceHistory(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveMarkPriceHistory(t.Context(), "", time.Now().Add(-4*time.Hour), time.Now()) + _, err := e.WSRetrieveMarkPriceHistory(t.Context(), "", time.Now().Add(-4*time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) var result []MarkPriceHistory for _, ps := range []string{ - d.optionPairToString(optionsTradablePair), + e.optionPairToString(optionsTradablePair), spotTradablePair.String(), btcPerpInstrument, futureComboTradablePair.String(), } { - result, err = d.WSRetrieveMarkPriceHistory(t.Context(), ps, time.Now().Add(-4*time.Hour), time.Now()) + result, err = e.WSRetrieveMarkPriceHistory(t.Context(), ps, time.Now().Add(-4*time.Hour), time.Now()) require.NoErrorf(t, err, "expected %v, got %v currency pair %v", nil, err, ps) require.NotNilf(t, result, "expected value not to be nil for pair: %v", ps) } @@ -288,26 +289,26 @@ func TestGetBookSummaryByCurrency(t *testing.T) { "last": null, "instrument_name": "BTC-22FEB19", "high": null, "estimated_delivery_price": 3579.73, "creation_timestamp": 1550230036440, "bid_price": null, "base_currency": "BTC", "ask_price": null}`), &response) require.NoError(t, err) - _, err = d.GetBookSummaryByCurrency(t.Context(), currency.EMPTYCODE, "future") + _, err = e.GetBookSummaryByCurrency(t.Context(), currency.EMPTYCODE, "future") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetBookSummaryByCurrency(t.Context(), currency.BTC, "option") + result, err := e.GetBookSummaryByCurrency(t.Context(), currency.BTC, "option") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveBookBySummary(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveBookBySummary(t.Context(), currency.EMPTYCODE, "") + _, err := e.WSRetrieveBookBySummary(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveBookBySummary(t.Context(), currency.SOL, "") + result, err := e.WSRetrieveBookBySummary(t.Context(), currency.SOL, "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetBookSummaryByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetBookSummaryByInstrument(t.Context(), "") + _, err := e.GetBookSummaryByInstrument(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) var result []BookSummaryData @@ -315,10 +316,10 @@ func TestGetBookSummaryByInstrument(t *testing.T) { btcPerpInstrument, spotTradablePair.String(), futureComboTradablePair.String(), - d.optionPairToString(optionsTradablePair), + e.optionPairToString(optionsTradablePair), optionComboTradablePair.String(), } { - result, err = d.GetBookSummaryByInstrument(t.Context(), ps) + result, err = e.GetBookSummaryByInstrument(t.Context(), ps) require.NoErrorf(t, err, "expected nil, got %v for pair %s", err, ps) require.NotNilf(t, result, "expected result not to be nil for pair %s", ps) } @@ -326,17 +327,17 @@ func TestGetBookSummaryByInstrument(t *testing.T) { func TestWSRetrieveBookSummaryByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveBookSummaryByInstrument(t.Context(), "") + _, err := e.WSRetrieveBookSummaryByInstrument(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) var result []BookSummaryData for _, ps := range []string{ btcPerpInstrument, spotTradablePair.String(), futureComboTradablePair.String(), - d.optionPairToString(optionsTradablePair), + e.optionPairToString(optionsTradablePair), optionComboTradablePair.String(), } { - result, err = d.WSRetrieveBookSummaryByInstrument(t.Context(), ps) + result, err = e.WSRetrieveBookSummaryByInstrument(t.Context(), ps) require.NoErrorf(t, err, "expected nil, got %v for pair %s", err, ps) require.NotNilf(t, result, "expected result not to be nil for pair %s", ps) } @@ -344,53 +345,53 @@ func TestWSRetrieveBookSummaryByInstrument(t *testing.T) { func TestGetContractSize(t *testing.T) { t.Parallel() - _, err := d.GetContractSize(t.Context(), "") + _, err := e.GetContractSize(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetContractSize(t.Context(), btcPerpInstrument) + result, err := e.GetContractSize(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveContractSize(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveContractSize(t.Context(), "") + _, err := e.WSRetrieveContractSize(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrieveContractSize(t.Context(), btcPerpInstrument) + result, err := e.WSRetrieveContractSize(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrencies(t *testing.T) { t.Parallel() - result, err := d.GetCurrencies(t.Context()) + result, err := e.GetCurrencies(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveCurrencies(t *testing.T) { t.Parallel() - result, err := d.WSRetrieveCurrencies(t.Context()) + result, err := e.WSRetrieveCurrencies(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetDeliveryPrices(t *testing.T) { t.Parallel() - _, err := d.GetDeliveryPrices(t.Context(), "", 0, 5) + _, err := e.GetDeliveryPrices(t.Context(), "", 0, 5) require.ErrorIs(t, err, errUnsupportedIndexName) - result, err := d.GetDeliveryPrices(t.Context(), "btc_usd", 0, 5) + result, err := e.GetDeliveryPrices(t.Context(), "btc_usd", 0, 5) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveDeliveryPrices(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveDeliveryPrices(t.Context(), "", 0, 5) + _, err := e.WSRetrieveDeliveryPrices(t.Context(), "", 0, 5) require.ErrorIs(t, err, errUnsupportedIndexName) - result, err := d.WSRetrieveDeliveryPrices(t.Context(), "btc_usd", 0, 5) + result, err := e.WSRetrieveDeliveryPrices(t.Context(), "btc_usd", 0, 5) require.NoError(t, err) assert.NotNil(t, result) } @@ -398,61 +399,61 @@ func TestWSRetrieveDeliveryPrices(t *testing.T) { func TestGetFundingChartData(t *testing.T) { t.Parallel() // only for perpetual instruments - _, err := d.GetFundingChartData(t.Context(), "", "8h") + _, err := e.GetFundingChartData(t.Context(), "", "8h") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetFundingChartData(t.Context(), btcPerpInstrument, "8h") + result, err := e.GetFundingChartData(t.Context(), btcPerpInstrument, "8h") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveFundingChartData(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveFundingChartData(t.Context(), "", "8h") + _, err := e.WSRetrieveFundingChartData(t.Context(), "", "8h") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrieveFundingChartData(t.Context(), btcPerpInstrument, "8h") + result, err := e.WSRetrieveFundingChartData(t.Context(), btcPerpInstrument, "8h") require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingRateHistory(t *testing.T) { t.Parallel() - _, err := d.GetFundingRateHistory(t.Context(), "", time.Now().Add(-time.Hour), time.Now()) + _, err := e.GetFundingRateHistory(t.Context(), "", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetFundingRateHistory(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour), time.Now()) + result, err := e.GetFundingRateHistory(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveFundingRateHistory(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveFundingRateHistory(t.Context(), "", time.Now().Add(-time.Hour), time.Now()) + _, err := e.WSRetrieveFundingRateHistory(t.Context(), "", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrieveFundingRateHistory(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour), time.Now()) + result, err := e.WSRetrieveFundingRateHistory(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingRateValue(t *testing.T) { t.Parallel() - _, err := d.GetFundingRateValue(t.Context(), "", time.Time{}, time.Time{}) + _, err := e.GetFundingRateValue(t.Context(), "", time.Time{}, time.Time{}) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.GetFundingRateValue(t.Context(), btcPerpInstrument, time.Now(), time.Now().Add(-time.Hour*8)) + _, err = e.GetFundingRateValue(t.Context(), btcPerpInstrument, time.Now(), time.Now().Add(-time.Hour*8)) require.ErrorIs(t, err, common.ErrStartAfterEnd) - result, err := d.GetFundingRateValue(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour*8), time.Now()) + result, err := e.GetFundingRateValue(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour*8), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveFundingRateValue(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveFundingRateValue(t.Context(), btcPerpInstrument, time.Now(), time.Now().Add(-time.Hour*8)) + _, err := e.WSRetrieveFundingRateValue(t.Context(), btcPerpInstrument, time.Now(), time.Now().Add(-time.Hour*8)) require.ErrorIs(t, err, common.ErrStartAfterEnd) - result, err := d.WSRetrieveFundingRateValue(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour*8), time.Now()) + result, err := e.WSRetrieveFundingRateValue(t.Context(), btcPerpInstrument, time.Now().Add(-time.Hour*8), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } @@ -472,82 +473,82 @@ func TestHistoricalVolatilityDataUnmarshalJSON(t *testing.T) { func TestGetHistoricalVolatility(t *testing.T) { t.Parallel() - _, err := d.GetHistoricalVolatility(t.Context(), currency.EMPTYCODE) + _, err := e.GetHistoricalVolatility(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetHistoricalVolatility(t.Context(), currency.BTC) + result, err := e.GetHistoricalVolatility(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveHistoricalVolatility(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveHistoricalVolatility(t.Context(), currency.EMPTYCODE) + _, err := e.WSRetrieveHistoricalVolatility(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveHistoricalVolatility(t.Context(), currency.SOL) + result, err := e.WSRetrieveHistoricalVolatility(t.Context(), currency.SOL) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrencyIndexPrice(t *testing.T) { t.Parallel() - _, err := d.GetCurrencyIndexPrice(t.Context(), currency.EMPTYCODE) + _, err := e.GetCurrencyIndexPrice(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetCurrencyIndexPrice(t.Context(), currency.BTC) + result, err := e.GetCurrencyIndexPrice(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveCurrencyIndexPrice(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveCurrencyIndexPrice(t.Context(), currency.EMPTYCODE) + _, err := e.WSRetrieveCurrencyIndexPrice(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveCurrencyIndexPrice(t.Context(), currency.BTC) + result, err := e.WSRetrieveCurrencyIndexPrice(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetIndexPrice(t *testing.T) { t.Parallel() - _, err := d.GetIndexPrice(t.Context(), "") + _, err := e.GetIndexPrice(t.Context(), "") require.ErrorIs(t, err, errUnsupportedIndexName) - result, err := d.GetIndexPrice(t.Context(), "ada_usd") + result, err := e.GetIndexPrice(t.Context(), "ada_usd") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveIndexPrice(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveIndexPrice(t.Context(), "") + _, err := e.WSRetrieveIndexPrice(t.Context(), "") require.ErrorIs(t, err, errUnsupportedIndexName) - result, err := d.WSRetrieveIndexPrice(t.Context(), "ada_usd") + result, err := e.WSRetrieveIndexPrice(t.Context(), "ada_usd") require.NoError(t, err) assert.NotNil(t, result) } func TestGetIndexPriceNames(t *testing.T) { t.Parallel() - result, err := d.GetIndexPriceNames(t.Context()) + result, err := e.GetIndexPriceNames(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveIndexPriceNames(t *testing.T) { t.Parallel() - result, err := d.WSRetrieveIndexPriceNames(t.Context()) + result, err := e.WSRetrieveIndexPriceNames(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetInstrumentData(t *testing.T) { t.Parallel() - _, err := d.GetInstrument(t.Context(), "") + _, err := e.GetInstrument(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) var result *InstrumentData for assetType, cp := range assetTypeToPairsMap { - result, err = d.GetInstrument(t.Context(), d.formatPairString(assetType, cp)) + result, err = e.GetInstrument(t.Context(), e.formatPairString(assetType, cp)) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -555,12 +556,12 @@ func TestGetInstrumentData(t *testing.T) { func TestWSRetrieveInstrumentData(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveInstrumentData(t.Context(), "") + _, err := e.WSRetrieveInstrumentData(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) var result *InstrumentData for assetType, cp := range assetTypeToPairsMap { - result, err = d.WSRetrieveInstrumentData(t.Context(), d.formatPairString(assetType, cp)) + result, err = e.WSRetrieveInstrumentData(t.Context(), e.formatPairString(assetType, cp)) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -568,13 +569,13 @@ func TestWSRetrieveInstrumentData(t *testing.T) { func TestGetInstruments(t *testing.T) { t.Parallel() - result, err := d.GetInstruments(t.Context(), currency.EMPTYCODE, "future", false) + result, err := e.GetInstruments(t.Context(), currency.EMPTYCODE, "future", false) require.NoError(t, err) require.NotNil(t, result) - result, err = d.GetInstruments(t.Context(), currency.BTC, "", false) + result, err = e.GetInstruments(t.Context(), currency.BTC, "", false) require.NoError(t, err) require.NotNil(t, result) - result, err = d.GetInstruments(t.Context(), currency.BTC, "", true) + result, err = e.GetInstruments(t.Context(), currency.BTC, "", true) require.NoError(t, err) for a := range result { require.Falsef(t, result[a].IsActive, "expected expired instrument, but got active instrument %s", result[a].InstrumentName) @@ -583,107 +584,107 @@ func TestGetInstruments(t *testing.T) { func TestWSRetrieveInstrumentsData(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveInstrumentsData(t.Context(), currency.EMPTYCODE, "", false) + _, err := e.WSRetrieveInstrumentsData(t.Context(), currency.EMPTYCODE, "", false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveInstrumentsData(t.Context(), currency.BTC, "", false) + result, err := e.WSRetrieveInstrumentsData(t.Context(), currency.BTC, "", false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastSettlementsByCurrency(t *testing.T) { t.Parallel() - _, err := d.GetLastSettlementsByCurrency(t.Context(), currency.EMPTYCODE, "delivery", "5", 0, time.Now().Add(-time.Hour)) + _, err := e.GetLastSettlementsByCurrency(t.Context(), currency.EMPTYCODE, "delivery", "5", 0, time.Now().Add(-time.Hour)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetLastSettlementsByCurrency(t.Context(), currency.BTC, "delivery", "5", 0, time.Now().Add(-time.Hour)) + result, err := e.GetLastSettlementsByCurrency(t.Context(), currency.BTC, "delivery", "5", 0, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveLastSettlementsByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastSettlementsByCurrency(t.Context(), currency.EMPTYCODE, "delivery", "5", 0, time.Now().Add(-time.Hour)) + _, err := e.WSRetrieveLastSettlementsByCurrency(t.Context(), currency.EMPTYCODE, "delivery", "5", 0, time.Now().Add(-time.Hour)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveLastSettlementsByCurrency(t.Context(), currency.BTC, "delivery", "5", 0, time.Now().Add(-time.Hour)) + result, err := e.WSRetrieveLastSettlementsByCurrency(t.Context(), currency.BTC, "delivery", "5", 0, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveLastSettlementsByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastSettlementsByInstrument(t.Context(), "", "settlement", "5", 0, time.Now().Add(-2*time.Hour)) + _, err := e.WSRetrieveLastSettlementsByInstrument(t.Context(), "", "settlement", "5", 0, time.Now().Add(-2*time.Hour)) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrieveLastSettlementsByInstrument(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), "settlement", "5", 0, time.Now().Add(-2*time.Hour)) + result, err := e.WSRetrieveLastSettlementsByInstrument(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), "settlement", "5", 0, time.Now().Add(-2*time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastSettlementsByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetLastSettlementsByInstrument(t.Context(), "", "settlement", "5", 0, time.Now().Add(-2*time.Hour)) + _, err := e.GetLastSettlementsByInstrument(t.Context(), "", "settlement", "5", 0, time.Now().Add(-2*time.Hour)) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetLastSettlementsByInstrument(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), "settlement", "5", 0, time.Now().Add(-2*time.Hour)) + result, err := e.GetLastSettlementsByInstrument(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), "settlement", "5", 0, time.Now().Add(-2*time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastTradesByCurrency(t *testing.T) { t.Parallel() - _, err := d.GetLastTradesByCurrency(t.Context(), currency.EMPTYCODE, "option", "36798", "36799", "asc", 0, true) + _, err := e.GetLastTradesByCurrency(t.Context(), currency.EMPTYCODE, "option", "36798", "36799", "asc", 0, true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetLastTradesByCurrency(t.Context(), currency.BTC, "option", "36798", "36799", "asc", 0, true) + result, err := e.GetLastTradesByCurrency(t.Context(), currency.BTC, "option", "36798", "36799", "asc", 0, true) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveLastTradesByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastTradesByCurrency(t.Context(), currency.EMPTYCODE, "option", "36798", "36799", "asc", 0, true) + _, err := e.WSRetrieveLastTradesByCurrency(t.Context(), currency.EMPTYCODE, "option", "36798", "36799", "asc", 0, true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveLastTradesByCurrency(t.Context(), currency.BTC, "option", "36798", "36799", "asc", 0, true) + result, err := e.WSRetrieveLastTradesByCurrency(t.Context(), currency.BTC, "option", "36798", "36799", "asc", 0, true) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastTradesByCurrencyAndTime(t *testing.T) { t.Parallel() - _, err := d.GetLastTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) + _, err := e.GetLastTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) + result, err := e.GetLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) require.NoError(t, err) require.NotNil(t, result) - result, err = d.GetLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "option", "asc", 25, time.Now().Add(-8*time.Hour), time.Now()) + result, err = e.GetLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "option", "asc", 25, time.Now().Add(-8*time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveLastTradesByCurrencyAndTime(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) + _, err := e.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) + result, err := e.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) require.NoError(t, err) require.NotNil(t, result) - result, err = d.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "option", "asc", 25, false, time.Now().Add(-8*time.Hour), time.Now()) + result, err = e.WSRetrieveLastTradesByCurrencyAndTime(t.Context(), currency.BTC, "option", "asc", 25, false, time.Now().Add(-8*time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastTradesByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetLastTradesByInstrument(t.Context(), "", "", "", "", 0, false) + _, err := e.GetLastTradesByInstrument(t.Context(), "", "", "", "", 0, false) require.ErrorIs(t, err, errInvalidInstrumentName) for assetType, cp := range assetTypeToPairsMap { - result, err := d.GetLastTradesByInstrument(t.Context(), d.formatPairString(assetType, cp), "30500", "31500", "desc", 0, true) + result, err := e.GetLastTradesByInstrument(t.Context(), e.formatPairString(assetType, cp), "30500", "31500", "desc", 0, true) require.NoErrorf(t, err, "expected %v, got %v currency asset %v pair %v", nil, err, assetType, cp) require.NotNilf(t, result, "expected value not to be nil for asset %v pair: %v", assetType, cp) } @@ -691,11 +692,11 @@ func TestGetLastTradesByInstrument(t *testing.T) { func TestWSRetrieveLastTradesByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastTradesByInstrument(t.Context(), "", "", "", "", 0, false) + _, err := e.WSRetrieveLastTradesByInstrument(t.Context(), "", "", "", "", 0, false) require.ErrorIs(t, err, errInvalidInstrumentName) for assetType, cp := range assetTypeToPairsMap { - result, err := d.WSRetrieveLastTradesByInstrument(t.Context(), d.formatPairString(assetType, cp), "30500", "31500", "desc", 0, true) + result, err := e.WSRetrieveLastTradesByInstrument(t.Context(), e.formatPairString(assetType, cp), "30500", "31500", "desc", 0, true) require.NoErrorf(t, err, "expected %v, got %v currency asset %v pair %v", nil, err, assetType, cp) require.NotNilf(t, result, "expected value not to be nil for asset %v pair: %v", assetType, cp) } @@ -703,11 +704,11 @@ func TestWSRetrieveLastTradesByInstrument(t *testing.T) { func TestGetLastTradesByInstrumentAndTime(t *testing.T) { t.Parallel() - _, err := d.GetLastTradesByInstrumentAndTime(t.Context(), "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) + _, err := e.GetLastTradesByInstrumentAndTime(t.Context(), "", "", 0, time.Now().Add(-8*time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) for assetType, cp := range assetTypeToPairsMap { - result, err := d.GetLastTradesByInstrumentAndTime(t.Context(), d.formatPairString(assetType, cp), "", 0, time.Now().Add(-8*time.Hour), time.Now()) + result, err := e.GetLastTradesByInstrumentAndTime(t.Context(), e.formatPairString(assetType, cp), "", 0, time.Now().Add(-8*time.Hour), time.Now()) require.NoErrorf(t, err, "expected %v, got %v currency pair %v", nil, err, cp) require.NotNilf(t, result, "expected value not to be nil for pair: %v", cp) } @@ -715,11 +716,11 @@ func TestGetLastTradesByInstrumentAndTime(t *testing.T) { func TestWSRetrieveLastTradesByInstrumentAndTime(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastTradesByInstrumentAndTime(t.Context(), "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) + _, err := e.WSRetrieveLastTradesByInstrumentAndTime(t.Context(), "", "", 0, false, time.Now().Add(-8*time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) for assetType, cp := range assetTypeToPairsMap { - result, err := d.WSRetrieveLastTradesByInstrumentAndTime(t.Context(), d.formatPairString(assetType, cp), "", 0, true, time.Now().Add(-8*time.Hour), time.Now()) + result, err := e.WSRetrieveLastTradesByInstrumentAndTime(t.Context(), e.formatPairString(assetType, cp), "", 0, true, time.Now().Add(-8*time.Hour), time.Now()) require.NoErrorf(t, err, "expected %v, got %v currency pair %v", nil, err, cp) require.NotNilf(t, result, "expected value not to be nil for pair: %v", cp) } @@ -728,17 +729,17 @@ func TestWSRetrieveLastTradesByInstrumentAndTime(t *testing.T) { func TestWSProcessTrades(t *testing.T) { t.Parallel() - d := new(Deribit) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(d), "Setup instance must not error") - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", d.wsHandleData) - close(d.Websocket.DataHandler) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup instance must not error") + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) - p, a, err := d.getAssetPairByInstrument("BTC-PERPETUAL") + p, a, err := e.getAssetPairByInstrument("BTC-PERPETUAL") require.NoError(t, err, "getAssetPairByInstrument must not error") exp := []trade.Data{ { - Exchange: d.Name, + Exchange: e.Name, CurrencyPair: p, Timestamp: time.UnixMilli(1742627465811).UTC(), Price: 84295.5, @@ -748,7 +749,7 @@ func TestWSProcessTrades(t *testing.T) { AssetType: a, }, { - Exchange: d.Name, + Exchange: e.Name, CurrencyPair: p, Timestamp: time.UnixMilli(1742627361899).UTC(), Price: 84319.0, @@ -758,11 +759,11 @@ func TestWSProcessTrades(t *testing.T) { AssetType: a, }, } - require.Len(t, d.Websocket.DataHandler, len(exp), "Must see the correct number of trades") - for resp := range d.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, len(exp), "Must see the correct number of trades") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 1 - len(d.Websocket.DataHandler) + i := 1 - len(e.Websocket.DataHandler) require.Equalf(t, exp[i], v, "Trade [%d] must be correct", i) case error: t.Error(v) @@ -774,12 +775,12 @@ func TestWSProcessTrades(t *testing.T) { func TestGetOrderbookData(t *testing.T) { t.Parallel() - _, err := d.GetOrderbook(t.Context(), "", 0) + _, err := e.GetOrderbook(t.Context(), "", 0) require.ErrorIs(t, err, errInvalidInstrumentName) var result *Orderbook for assetType, cp := range assetTypeToPairsMap { - result, err = d.GetOrderbook(t.Context(), d.formatPairString(assetType, cp), 0) + result, err = e.GetOrderbook(t.Context(), e.formatPairString(assetType, cp), 0) require.NoErrorf(t, err, "expected %v, got %v currency pair %v", nil, err, cp) require.NotNilf(t, result, "expected value not to be nil for pair: %v", cp) } @@ -787,15 +788,15 @@ func TestGetOrderbookData(t *testing.T) { func TestWSRetrieveOrderbookData(t *testing.T) { t.Parallel() - if !d.Websocket.IsConnected() { + if !e.Websocket.IsConnected() { t.Skip("websocket is not connected") } - _, err := d.WSRetrieveOrderbookData(t.Context(), "", 0) + _, err := e.WSRetrieveOrderbookData(t.Context(), "", 0) require.ErrorIs(t, err, errInvalidInstrumentName) var result *Orderbook for assetType, cp := range assetTypeToPairsMap { - result, err = d.WSRetrieveOrderbookData(t.Context(), d.formatPairString(assetType, cp), 0) + result, err = e.WSRetrieveOrderbookData(t.Context(), e.formatPairString(assetType, cp), 0) require.NoErrorf(t, err, "expected %v, got %v currency pair %v", nil, err, cp) require.NotNilf(t, result, "expected value not to be nil for pair: %v", cp) } @@ -803,204 +804,204 @@ func TestWSRetrieveOrderbookData(t *testing.T) { func TestGetOrderbookByInstrumentID(t *testing.T) { t.Parallel() - combos, err := d.GetComboIDs(t.Context(), currency.BTC, "") + combos, err := e.GetComboIDs(t.Context(), currency.BTC, "") require.NoError(t, err) if len(combos) == 0 { t.Skip("no combo instance found for currency BTC") } - _, err = d.GetOrderbookByInstrumentID(t.Context(), 0, 50) + _, err = e.GetOrderbookByInstrumentID(t.Context(), 0, 50) require.ErrorIs(t, err, errInvalidInstrumentID) - comboD, err := d.GetComboDetails(t.Context(), combos[0]) + comboD, err := e.GetComboDetails(t.Context(), combos[0]) require.NoError(t, err) require.NotNil(t, comboD) - result, err := d.GetOrderbookByInstrumentID(t.Context(), comboD.InstrumentID, 50) + result, err := e.GetOrderbookByInstrumentID(t.Context(), comboD.InstrumentID, 50) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOrderbookByInstrumentID(t *testing.T) { t.Parallel() - combos, err := d.WSRetrieveComboIDs(t.Context(), currency.BTC, "") + combos, err := e.WSRetrieveComboIDs(t.Context(), currency.BTC, "") require.NoError(t, err) if len(combos) == 0 { t.Skip("no combo instance found for currency BTC") } - _, err = d.WSRetrieveOrderbookByInstrumentID(t.Context(), 0, 50) + _, err = e.WSRetrieveOrderbookByInstrumentID(t.Context(), 0, 50) require.ErrorIs(t, err, errInvalidInstrumentID) - comboD, err := d.WSRetrieveComboDetails(t.Context(), combos[0]) + comboD, err := e.WSRetrieveComboDetails(t.Context(), combos[0]) require.NoError(t, err) require.NotNil(t, comboD) - result, err := d.WSRetrieveOrderbookByInstrumentID(t.Context(), comboD.InstrumentID, 50) + result, err := e.WSRetrieveOrderbookByInstrumentID(t.Context(), comboD.InstrumentID, 50) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSupportedIndexNames(t *testing.T) { t.Parallel() - result, err := d.GetSupportedIndexNames(t.Context(), "derivative") + result, err := e.GetSupportedIndexNames(t.Context(), "derivative") require.NoError(t, err) assert.NotNil(t, result) } func TestWsRetrieveSupportedIndexNames(t *testing.T) { t.Parallel() - result, err := d.WsRetrieveSupportedIndexNames(t.Context(), "derivative") + result, err := e.WsRetrieveSupportedIndexNames(t.Context(), "derivative") require.NoError(t, err) assert.NotNil(t, result) } func TestGetRequestForQuote(t *testing.T) { t.Parallel() - _, err := d.GetRequestForQuote(t.Context(), currency.EMPTYCODE, d.GetAssetKind(asset.Futures)) + _, err := e.GetRequestForQuote(t.Context(), currency.EMPTYCODE, e.GetAssetKind(asset.Futures)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetRequestForQuote(t.Context(), currency.BTC, d.GetAssetKind(asset.Futures)) + result, err := e.GetRequestForQuote(t.Context(), currency.BTC, e.GetAssetKind(asset.Futures)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveRequestForQuote(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveRequestForQuote(t.Context(), currency.EMPTYCODE, d.GetAssetKind(asset.Futures)) + _, err := e.WSRetrieveRequestForQuote(t.Context(), currency.EMPTYCODE, e.GetAssetKind(asset.Futures)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveRequestForQuote(t.Context(), currency.BTC, d.GetAssetKind(asset.Futures)) + result, err := e.WSRetrieveRequestForQuote(t.Context(), currency.BTC, e.GetAssetKind(asset.Futures)) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTradeVolumes(t *testing.T) { t.Parallel() - result, err := d.GetTradeVolumes(t.Context(), false) + result, err := e.GetTradeVolumes(t.Context(), false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveTradeVolumes(t *testing.T) { t.Parallel() - result, err := d.WSRetrieveTradeVolumes(t.Context(), false) + result, err := e.WSRetrieveTradeVolumes(t.Context(), false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTradingViewChartData(t *testing.T) { t.Parallel() - _, err := d.GetTradingViewChart(t.Context(), "", "60", time.Now().Add(-time.Hour), time.Now()) + _, err := e.GetTradingViewChart(t.Context(), "", "60", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetTradingViewChart(t.Context(), btcPerpInstrument, "60", time.Now().Add(-time.Hour), time.Now()) + result, err := e.GetTradingViewChart(t.Context(), btcPerpInstrument, "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) require.NotNil(t, result) - result, err = d.GetTradingViewChart(t.Context(), spotTradablePair.String(), "60", time.Now().Add(-time.Hour), time.Now()) + result, err = e.GetTradingViewChart(t.Context(), spotTradablePair.String(), "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrievesTradingViewChartData(t *testing.T) { t.Parallel() - _, err := d.WSRetrievesTradingViewChartData(t.Context(), "", "60", time.Now().Add(-time.Hour), time.Now()) + _, err := e.WSRetrievesTradingViewChartData(t.Context(), "", "60", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrievesTradingViewChartData(t.Context(), btcPerpInstrument, "60", time.Now().Add(-time.Hour), time.Now()) + result, err := e.WSRetrievesTradingViewChartData(t.Context(), btcPerpInstrument, "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) require.NotNil(t, result) - result, err = d.WSRetrievesTradingViewChartData(t.Context(), spotTradablePair.String(), "60", time.Now().Add(-time.Hour), time.Now()) + result, err = e.WSRetrievesTradingViewChartData(t.Context(), spotTradablePair.String(), "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetVolatilityIndexData(t *testing.T) { t.Parallel() - _, err := d.GetVolatilityIndex(t.Context(), currency.EMPTYCODE, "60", time.Now().Add(-time.Hour), time.Now()) + _, err := e.GetVolatilityIndex(t.Context(), currency.EMPTYCODE, "60", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.GetVolatilityIndex(t.Context(), currency.BTC, "", time.Now().Add(-time.Hour), time.Now()) + _, err = e.GetVolatilityIndex(t.Context(), currency.BTC, "", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errResolutionNotSet) - _, err = d.GetVolatilityIndex(t.Context(), currency.BTC, "60", time.Now(), time.Now().Add(-time.Hour)) + _, err = e.GetVolatilityIndex(t.Context(), currency.BTC, "60", time.Now(), time.Now().Add(-time.Hour)) require.ErrorIs(t, err, common.ErrStartAfterEnd) - result, err := d.GetVolatilityIndex(t.Context(), currency.BTC, "60", time.Now().Add(-time.Hour), time.Now()) + result, err := e.GetVolatilityIndex(t.Context(), currency.BTC, "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveVolatilityIndexData(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveVolatilityIndexData(t.Context(), currency.EMPTYCODE, "60", time.Now().Add(-time.Hour), time.Now()) + _, err := e.WSRetrieveVolatilityIndexData(t.Context(), currency.EMPTYCODE, "60", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "", time.Now().Add(-time.Hour), time.Now()) + _, err = e.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "", time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errResolutionNotSet) - _, err = d.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "60", time.Now(), time.Now().Add(-time.Hour)) + _, err = e.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "60", time.Now(), time.Now().Add(-time.Hour)) require.ErrorIs(t, err, common.ErrStartAfterEnd) - result, err := d.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "60", time.Now().Add(-time.Hour), time.Now()) + result, err := e.WSRetrieveVolatilityIndexData(t.Context(), currency.BTC, "60", time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicTicker(t *testing.T) { t.Parallel() - _, err := d.GetPublicTicker(t.Context(), "") + _, err := e.GetPublicTicker(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.GetPublicTicker(t.Context(), btcPerpInstrument) + result, err := e.GetPublicTicker(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrievePublicTicker(t *testing.T) { t.Parallel() - _, err := d.WSRetrievePublicTicker(t.Context(), "") + _, err := e.WSRetrievePublicTicker(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - result, err := d.WSRetrievePublicTicker(t.Context(), btcPerpInstrument) + result, err := e.WSRetrievePublicTicker(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountSummary(t *testing.T) { t.Parallel() - _, err := d.GetAccountSummary(t.Context(), currency.EMPTYCODE, false) + _, err := e.GetAccountSummary(t.Context(), currency.EMPTYCODE, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetAccountSummary(t.Context(), currency.BTC, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountSummary(t.Context(), currency.BTC, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveAccountSummary(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveAccountSummary(t.Context(), currency.EMPTYCODE, false) + _, err := e.WSRetrieveAccountSummary(t.Context(), currency.EMPTYCODE, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveAccountSummary(t.Context(), currency.BTC, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveAccountSummary(t.Context(), currency.BTC, false) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelTransferByID(t *testing.T) { t.Parallel() - _, err := d.CancelTransferByID(t.Context(), currency.EMPTYCODE, "", 23487) + _, err := e.CancelTransferByID(t.Context(), currency.EMPTYCODE, "", 23487) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.CancelTransferByID(t.Context(), currency.BTC, "", 0) + _, err = e.CancelTransferByID(t.Context(), currency.BTC, "", 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.CancelTransferByID(t.Context(), currency.BTC, "", 23487) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelTransferByID(t.Context(), currency.BTC, "", 23487) require.NoError(t, err) assert.NotNil(t, result) } func TestWSCancelTransferByID(t *testing.T) { t.Parallel() - _, err := d.WSCancelTransferByID(t.Context(), currency.EMPTYCODE, "", 23487) + _, err := e.WSCancelTransferByID(t.Context(), currency.EMPTYCODE, "", 23487) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSCancelTransferByID(t.Context(), currency.BTC, "", 0) + _, err = e.WSCancelTransferByID(t.Context(), currency.BTC, "", 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSCancelTransferByID(t.Context(), currency.BTC, "", 23487) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSCancelTransferByID(t.Context(), currency.BTC, "", 23487) require.NoError(t, err) assert.NotNil(t, result) } @@ -1012,22 +1013,22 @@ func TestGetTransfers(t *testing.T) { var resp *TransfersData err := json.Unmarshal([]byte(getTransferResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetTransfers(t.Context(), currency.EMPTYCODE, 0, 0) + _, err = e.GetTransfers(t.Context(), currency.EMPTYCODE, 0, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetTransfers(t.Context(), currency.BTC, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTransfers(t.Context(), currency.BTC, 0, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveTransfers(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveTransfers(t.Context(), currency.EMPTYCODE, 0, 0) + _, err := e.WSRetrieveTransfers(t.Context(), currency.EMPTYCODE, 0, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveTransfers(t.Context(), currency.BTC, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveTransfers(t.Context(), currency.BTC, 0, 0) require.NoError(t, err) assert.NotNil(t, result) } @@ -1039,70 +1040,70 @@ func TestCancelWithdrawal(t *testing.T) { var resp *CancelWithdrawalData err := json.Unmarshal([]byte(cancelWithdrawlPushDataJSON), &resp) require.NoError(t, err) - _, err = d.CancelWithdrawal(t.Context(), currency.EMPTYCODE, 123844) + _, err = e.CancelWithdrawal(t.Context(), currency.EMPTYCODE, 123844) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.CancelWithdrawal(t.Context(), currency.BTC, 0) + _, err = e.CancelWithdrawal(t.Context(), currency.BTC, 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.CancelWithdrawal(t.Context(), currency.BTC, 123844) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelWithdrawal(t.Context(), currency.BTC, 123844) require.NoError(t, err) assert.NotNil(t, result) } func TestWSCancelWithdrawal(t *testing.T) { t.Parallel() - _, err := d.WSCancelWithdrawal(t.Context(), currency.EMPTYCODE, 123844) + _, err := e.WSCancelWithdrawal(t.Context(), currency.EMPTYCODE, 123844) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSCancelWithdrawal(t.Context(), currency.BTC, 0) + _, err = e.WSCancelWithdrawal(t.Context(), currency.BTC, 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSCancelWithdrawal(t.Context(), currency.BTC, 123844) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSCancelWithdrawal(t.Context(), currency.BTC, 123844) require.NoError(t, err) assert.NotNil(t, result) } func TestCreateDepositAddress(t *testing.T) { t.Parallel() - _, err := d.CreateDepositAddress(t.Context(), currency.EMPTYCODE) + _, err := e.CreateDepositAddress(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.CreateDepositAddress(t.Context(), currency.SOL) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateDepositAddress(t.Context(), currency.SOL) require.NoError(t, err) assert.NotNil(t, result) } func TestWSCreateDepositAddress(t *testing.T) { t.Parallel() - _, err := d.WSCreateDepositAddress(t.Context(), currency.EMPTYCODE) + _, err := e.WSCreateDepositAddress(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSCreateDepositAddress(t.Context(), currency.SOL) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSCreateDepositAddress(t.Context(), currency.SOL) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrentDepositAddress(t *testing.T) { t.Parallel() - _, err := d.GetCurrentDepositAddress(t.Context(), currency.EMPTYCODE) + _, err := e.GetCurrentDepositAddress(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetCurrentDepositAddress(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCurrentDepositAddress(t.Context(), currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveCurrentDepositAddress(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveCurrentDepositAddress(t.Context(), currency.EMPTYCODE) + _, err := e.WSRetrieveCurrentDepositAddress(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveCurrentDepositAddress(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveCurrentDepositAddress(t.Context(), currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } @@ -1114,22 +1115,22 @@ func TestGetDeposits(t *testing.T) { var resp *DepositsData err := json.Unmarshal([]byte(getDepositPushDataJSON), &resp) require.NoError(t, err) - _, err = d.GetDeposits(t.Context(), currency.EMPTYCODE, 25, 0) + _, err = e.GetDeposits(t.Context(), currency.EMPTYCODE, 25, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetDeposits(t.Context(), currency.BTC, 25, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDeposits(t.Context(), currency.BTC, 25, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveDeposits(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveDeposits(t.Context(), currency.EMPTYCODE, 25, 0) + _, err := e.WSRetrieveDeposits(t.Context(), currency.EMPTYCODE, 25, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveDeposits(t.Context(), currency.BTC, 25, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveDeposits(t.Context(), currency.BTC, 25, 0) require.NoError(t, err) assert.NotNil(t, result) } @@ -1141,112 +1142,112 @@ func TestGetWithdrawals(t *testing.T) { var resp *WithdrawalsData err := json.Unmarshal([]byte(getWithdrawalResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetWithdrawals(t.Context(), currency.EMPTYCODE, 25, 0) + _, err = e.GetWithdrawals(t.Context(), currency.EMPTYCODE, 25, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetWithdrawals(t.Context(), currency.BTC, 25, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawals(t.Context(), currency.BTC, 25, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveWithdrawals(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveWithdrawals(t.Context(), currency.EMPTYCODE, 25, 0) + _, err := e.WSRetrieveWithdrawals(t.Context(), currency.EMPTYCODE, 25, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveWithdrawals(t.Context(), currency.BTC, 25, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveWithdrawals(t.Context(), currency.BTC, 25, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitTransferBetweenSubAccounts(t *testing.T) { t.Parallel() - _, err := d.SubmitTransferBetweenSubAccounts(t.Context(), currency.EMPTYCODE, 12345, 2, "") + _, err := e.SubmitTransferBetweenSubAccounts(t.Context(), currency.EMPTYCODE, 12345, 2, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 0, 2, "") + _, err = e.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 0, 2, "") require.ErrorIs(t, err, errInvalidAmount) - _, err = d.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, -1, "") + _, err = e.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, -1, "") require.ErrorIs(t, err, errInvalidDestinationID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, 4, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, 4, "") require.NoError(t, err) assert.NotNil(t, result) } func TestWsSubmitTransferBetweenSubAccounts(t *testing.T) { t.Parallel() - _, err := d.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EMPTYCODE, 12345, 2, "") + _, err := e.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EMPTYCODE, 12345, 2, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 0, 2, "") + _, err = e.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 0, 2, "") require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, -1, "") + _, err = e.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, -1, "") require.ErrorIs(t, err, errInvalidDestinationID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, 2, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WsSubmitTransferBetweenSubAccounts(t.Context(), currency.EURR, 12345, 2, "") require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitTransferToSubAccount(t *testing.T) { t.Parallel() - _, err := d.SubmitTransferToSubAccount(t.Context(), currency.EMPTYCODE, 0.01, 13434) + _, err := e.SubmitTransferToSubAccount(t.Context(), currency.EMPTYCODE, 0.01, 13434) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0, 13434) + _, err = e.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0, 13434) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 0) + _, err = e.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 0) require.ErrorIs(t, err, errInvalidDestinationID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 13434) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 13434) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitTransferToSubAccount(t *testing.T) { t.Parallel() - _, err := d.WSSubmitTransferToSubAccount(t.Context(), currency.EMPTYCODE, 0.01, 13434) + _, err := e.WSSubmitTransferToSubAccount(t.Context(), currency.EMPTYCODE, 0.01, 13434) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0, 13434) + _, err = e.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0, 13434) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 0) + _, err = e.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 0) require.ErrorIs(t, err, errInvalidDestinationID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 13434) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitTransferToSubAccount(t.Context(), currency.BTC, 0.01, 13434) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitTransferToUser(t *testing.T) { t.Parallel() - _, err := d.SubmitTransferToUser(t.Context(), currency.EMPTYCODE, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0.001) + _, err := e.SubmitTransferToUser(t.Context(), currency.EMPTYCODE, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0.001) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.SubmitTransferToUser(t.Context(), currency.BTC, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0) + _, err = e.SubmitTransferToUser(t.Context(), currency.BTC, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.SubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) + _, err = e.SubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) require.ErrorIs(t, err, errInvalidCryptoAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitTransferToUser(t.Context(), currency.BTC, "", "13434", 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitTransferToUser(t.Context(), currency.BTC, "", "13434", 0.001) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitTransferToUser(t *testing.T) { t.Parallel() - _, err := d.WSSubmitTransferToUser(t.Context(), currency.EMPTYCODE, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0.001) + _, err := e.WSSubmitTransferToUser(t.Context(), currency.EMPTYCODE, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0.001) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0) + _, err = e.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "0x4aa0753d798d668056920094d65321a8e8913e26", 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) + _, err = e.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) require.ErrorIs(t, err, errInvalidCryptoAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitTransferToUser(t.Context(), currency.BTC, "", "", 0.001) require.NoError(t, err) assert.NotNil(t, result) } @@ -1258,397 +1259,397 @@ func TestSubmitWithdraw(t *testing.T) { var resp *WithdrawData err := json.Unmarshal([]byte(submitWithdrawalResponseJSON), &resp) require.NoError(t, err) - _, err = d.SubmitWithdraw(t.Context(), currency.EMPTYCODE, core.BitcoinDonationAddress, "", 0.001) + _, err = e.SubmitWithdraw(t.Context(), currency.EMPTYCODE, core.BitcoinDonationAddress, "", 0.001) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.SubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0) + _, err = e.SubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.SubmitWithdraw(t.Context(), currency.BTC, "", "", 0.001) + _, err = e.SubmitWithdraw(t.Context(), currency.BTC, "", "", 0.001) require.ErrorIs(t, err, errInvalidCryptoAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0.001) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitWithdraw(t *testing.T) { - _, err := d.WSSubmitWithdraw(t.Context(), currency.EMPTYCODE, core.BitcoinDonationAddress, "", 0.001) + _, err := e.WSSubmitWithdraw(t.Context(), currency.EMPTYCODE, core.BitcoinDonationAddress, "", 0.001) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSSubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0) + _, err = e.WSSubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WSSubmitWithdraw(t.Context(), currency.BTC, "", "", 0.001) + _, err = e.WSSubmitWithdraw(t.Context(), currency.BTC, "", "", 0.001) require.ErrorIs(t, err, errInvalidCryptoAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitWithdraw(t.Context(), currency.BTC, core.BitcoinDonationAddress, "", 0.001) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAnnouncements(t *testing.T) { t.Parallel() - result, err := d.GetAnnouncements(t.Context(), time.Now(), 5) + result, err := e.GetAnnouncements(t.Context(), time.Now(), 5) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveAnnouncements(t *testing.T) { t.Parallel() - result, err := d.WSRetrieveAnnouncements(t.Context(), time.Now(), 5) + result, err := e.WSRetrieveAnnouncements(t.Context(), time.Now(), 5) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccessLog(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetAccessLog(t.Context(), 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccessLog(t.Context(), 0, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveAccessLog(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveAccessLog(t.Context(), 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveAccessLog(t.Context(), 0, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestChangeAPIKeyName(t *testing.T) { t.Parallel() - _, err := d.ChangeAPIKeyName(t.Context(), 0, "TestKey123") + _, err := e.ChangeAPIKeyName(t.Context(), 0, "TestKey123") require.ErrorIs(t, err, errInvalidID) - _, err = d.ChangeAPIKeyName(t.Context(), 2, "TestKey123$") + _, err = e.ChangeAPIKeyName(t.Context(), 2, "TestKey123$") require.ErrorIs(t, err, errUnacceptableAPIKey) - _, err = d.ChangeAPIKeyName(t.Context(), 2, "#$#") + _, err = e.ChangeAPIKeyName(t.Context(), 2, "#$#") require.ErrorIs(t, err, errUnacceptableAPIKey) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.ChangeAPIKeyName(t.Context(), 1, "TestKey123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.ChangeAPIKeyName(t.Context(), 1, "TestKey123") require.NoError(t, err) assert.NotNil(t, result) } func TestWSChangeAPIKeyName(t *testing.T) { t.Parallel() - _, err := d.WSChangeAPIKeyName(t.Context(), 0, "TestKey123") + _, err := e.WSChangeAPIKeyName(t.Context(), 0, "TestKey123") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WSChangeAPIKeyName(t.Context(), 1, "TestKey123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WSChangeAPIKeyName(t.Context(), 1, "TestKey123") require.NoError(t, err) assert.NotNil(t, result) } func TestChangeMarginModel(t *testing.T) { t.Parallel() - _, err := d.ChangeMarginModel(t.Context(), 2, "", false) + _, err := e.ChangeMarginModel(t.Context(), 2, "", false) require.ErrorIs(t, err, errInvalidMarginModel) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.ChangeMarginModel(t.Context(), 2, "segregated_pm", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ChangeMarginModel(t.Context(), 2, "segregated_pm", false) require.NoError(t, err) assert.NotNil(t, result) } func TestWsChangeMarginModel(t *testing.T) { t.Parallel() - _, err := d.WsChangeMarginModel(t.Context(), 2, "", false) + _, err := e.WsChangeMarginModel(t.Context(), 2, "", false) require.ErrorIs(t, err, errInvalidMarginModel) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - result, err := d.WsChangeMarginModel(t.Context(), 2, "segregated_pm", false) + result, err := e.WsChangeMarginModel(t.Context(), 2, "segregated_pm", false) require.NoError(t, err) assert.NotNil(t, result) } func TestChangeScopeInAPIKey(t *testing.T) { t.Parallel() - _, err := d.ChangeScopeInAPIKey(t.Context(), -1, "account:read_write") + _, err := e.ChangeScopeInAPIKey(t.Context(), -1, "account:read_write") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.ChangeScopeInAPIKey(t.Context(), 1, "account:read_write") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.ChangeScopeInAPIKey(t.Context(), 1, "account:read_write") require.NoError(t, err) assert.NotNil(t, result) } func TestWSChangeScopeInAPIKey(t *testing.T) { t.Parallel() - _, err := d.WSChangeScopeInAPIKey(t.Context(), 0, "account:read_write") + _, err := e.WSChangeScopeInAPIKey(t.Context(), 0, "account:read_write") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WSChangeScopeInAPIKey(t.Context(), 1, "account:read_write") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WSChangeScopeInAPIKey(t.Context(), 1, "account:read_write") require.NoError(t, err) assert.NotNil(t, result) } func TestChangeSubAccountName(t *testing.T) { t.Parallel() - err := d.ChangeSubAccountName(t.Context(), 0, "new_sub") + err := e.ChangeSubAccountName(t.Context(), 0, "new_sub") require.ErrorIs(t, err, errInvalidID) - err = d.ChangeSubAccountName(t.Context(), 312313, "") + err = e.ChangeSubAccountName(t.Context(), 312313, "") require.ErrorIs(t, err, errInvalidUsername) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.ChangeSubAccountName(t.Context(), 1, "new_sub") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.ChangeSubAccountName(t.Context(), 1, "new_sub") assert.NoError(t, err) } func TestWSChangeSubAccountName(t *testing.T) { t.Parallel() - err := d.WSChangeSubAccountName(t.Context(), 0, "new_sub") + err := e.WSChangeSubAccountName(t.Context(), 0, "new_sub") require.ErrorIs(t, err, errInvalidID) - err = d.WSChangeSubAccountName(t.Context(), 312313, "") + err = e.WSChangeSubAccountName(t.Context(), 312313, "") require.ErrorIs(t, err, errInvalidUsername) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.WSChangeSubAccountName(t.Context(), 1, "new_sub") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.WSChangeSubAccountName(t.Context(), 1, "new_sub") assert.NoError(t, err) } func TestCreateAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.CreateAPIKey(t.Context(), "account:read_write", "new_sub", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.CreateAPIKey(t.Context(), "account:read_write", "new_sub", false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSCreateAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WSCreateAPIKey(t.Context(), "account:read_write", "new_sub", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WSCreateAPIKey(t.Context(), "account:read_write", "new_sub", false) require.NoError(t, err) assert.NotNil(t, result) } func TestCreateSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.CreateSubAccount(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateSubAccount(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSCreateSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSCreateSubAccount(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSCreateSubAccount(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestDisableAPIKey(t *testing.T) { t.Parallel() - _, err := d.DisableAPIKey(t.Context(), 0) + _, err := e.DisableAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.DisableAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.DisableAPIKey(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, result) } func TestWSDisableAPIKey(t *testing.T) { t.Parallel() - _, err := d.WSDisableAPIKey(t.Context(), 0) + _, err := e.WSDisableAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WSDisableAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WSDisableAPIKey(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, result) } func TestEditAPIKey(t *testing.T) { t.Parallel() - _, err := d.EditAPIKey(t.Context(), 0, "trade", "", false, []string{"read", "read_write"}, []string{}) + _, err := e.EditAPIKey(t.Context(), 0, "trade", "", false, []string{"read", "read_write"}, []string{}) require.ErrorIs(t, err, errInvalidAPIKeyID) - _, err = d.EditAPIKey(t.Context(), 1234, "", "", false, []string{"read", "read_write"}, []string{}) + _, err = e.EditAPIKey(t.Context(), 1234, "", "", false, []string{"read", "read_write"}, []string{}) require.ErrorIs(t, err, errMaxScopeIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.EditAPIKey(t.Context(), 1234, "trade", "", false, []string{"read", "read_write"}, []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.EditAPIKey(t.Context(), 1234, "trade", "", false, []string{"read", "read_write"}, []string{}) require.NoError(t, err) assert.NotNil(t, result) } func TestWsEditAPIKey(t *testing.T) { t.Parallel() - _, err := d.WsEditAPIKey(t.Context(), 0, "trade", "", false, []string{"read", "read_write"}, []string{}) + _, err := e.WsEditAPIKey(t.Context(), 0, "trade", "", false, []string{"read", "read_write"}, []string{}) require.ErrorIs(t, err, errInvalidAPIKeyID) - _, err = d.WsEditAPIKey(t.Context(), 1234, "", "", false, []string{"read", "read_write"}, []string{}) + _, err = e.WsEditAPIKey(t.Context(), 1234, "", "", false, []string{"read", "read_write"}, []string{}) require.ErrorIs(t, err, errMaxScopeIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WsEditAPIKey(t.Context(), 1234, "trade", "", false, []string{"read", "read_write"}, []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WsEditAPIKey(t.Context(), 1234, "trade", "", false, []string{"read", "read_write"}, []string{}) require.NoError(t, err) assert.NotNil(t, result) } func TestEnableAffiliateProgram(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err := d.EnableAffiliateProgram(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.EnableAffiliateProgram(t.Context()) assert.NoError(t, err) } func TestWSEnableAffiliateProgram(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err := d.WSEnableAffiliateProgram(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.WSEnableAffiliateProgram(t.Context()) assert.NoError(t, err) } func TestEnableAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.EnableAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.EnableAPIKey(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, result) } func TestWSEnableAPIKey(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WSEnableAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WSEnableAPIKey(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAffiliateProgramInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetAffiliateProgramInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAffiliateProgramInfo(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveAffiliateProgramInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveAffiliateProgramInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveAffiliateProgramInfo(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetEmailLanguage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetEmailLanguage(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEmailLanguage(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveEmailLanguage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveEmailLanguage(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveEmailLanguage(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetNewAnnouncements(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetNewAnnouncements(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetNewAnnouncements(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveNewAnnouncements(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveNewAnnouncements(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveNewAnnouncements(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPosition(t *testing.T) { t.Parallel() - _, err := d.GetPosition(t.Context(), "") + _, err := e.GetPosition(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetPosition(t.Context(), btcPerpInstrument) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPosition(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrievePosition(t *testing.T) { t.Parallel() - _, err := d.WSRetrievePosition(t.Context(), "") + _, err := e.WSRetrievePosition(t.Context(), "") require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrievePosition(t.Context(), btcPerpInstrument) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrievePosition(t.Context(), btcPerpInstrument) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSubAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetSubAccounts(t.Context(), false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccounts(t.Context(), false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveSubAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveSubAccounts(t.Context(), false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveSubAccounts(t.Context(), false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSubAccountDetails(t *testing.T) { t.Parallel() - _, err := d.GetSubAccountDetails(t.Context(), currency.EMPTYCODE, false) + _, err := e.GetSubAccountDetails(t.Context(), currency.EMPTYCODE, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetSubAccountDetails(t.Context(), currency.BTC, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccountDetails(t.Context(), currency.BTC, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveSubAccountDetails(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveSubAccountDetails(t.Context(), currency.EMPTYCODE, false) + _, err := e.WSRetrieveSubAccountDetails(t.Context(), currency.EMPTYCODE, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveSubAccountDetails(t.Context(), currency.BTC, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveSubAccountDetails(t.Context(), currency.BTC, false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPositions(t *testing.T) { t.Parallel() - _, err := d.GetPositions(t.Context(), currency.EMPTYCODE, "option") + _, err := e.GetPositions(t.Context(), currency.EMPTYCODE, "option") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetPositions(t.Context(), currency.BTC, "option") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPositions(t.Context(), currency.BTC, "option") require.NoError(t, err) require.NotNil(t, result) - result, err = d.GetPositions(t.Context(), currency.ETH, "") + result, err = e.GetPositions(t.Context(), currency.ETH, "") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrievePositions(t *testing.T) { t.Parallel() - _, err := d.WSRetrievePositions(t.Context(), currency.EMPTYCODE, "option") + _, err := e.WSRetrievePositions(t.Context(), currency.EMPTYCODE, "option") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrievePositions(t.Context(), currency.BTC, "option") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrievePositions(t.Context(), currency.BTC, "option") require.NoError(t, err) require.NotNil(t, result) - result, err = d.WSRetrievePositions(t.Context(), currency.ETH, "") + result, err = e.WSRetrievePositions(t.Context(), currency.ETH, "") require.NoError(t, err) assert.NotNil(t, result) } @@ -1660,271 +1661,271 @@ func TestGetTransactionLog(t *testing.T) { var resp *TransactionsData err := json.Unmarshal([]byte(getTransactionLogResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetTransactionLog(t.Context(), currency.EMPTYCODE, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) + _, err = e.GetTransactionLog(t.Context(), currency.EMPTYCODE, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetTransactionLog(t.Context(), currency.BTC, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTransactionLog(t.Context(), currency.BTC, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveTransactionLog(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveTransactionLog(t.Context(), currency.EMPTYCODE, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) + _, err := e.WSRetrieveTransactionLog(t.Context(), currency.EMPTYCODE, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveTransactionLog(t.Context(), currency.BTC, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveTransactionLog(t.Context(), currency.BTC, "trade", time.Now().Add(-24*time.Hour), time.Now(), 5, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserLocks(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserLocks(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserLocks(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserLocks(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserLocks(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserLocks(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestListAPIKeys(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.ListAPIKeys(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ListAPIKeys(t.Context(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestWSListAPIKeys(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSListAPIKeys(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSListAPIKeys(t.Context(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetCustodyAccounts(t *testing.T) { t.Parallel() - _, err := d.GetCustodyAccounts(t.Context(), currency.EMPTYCODE) + _, err := e.GetCustodyAccounts(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetCustodyAccounts(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCustodyAccounts(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestWsRetrieveCustodyAccounts(t *testing.T) { t.Parallel() - _, err := d.WsRetrieveCustodyAccounts(t.Context(), currency.EMPTYCODE) + _, err := e.WsRetrieveCustodyAccounts(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WsRetrieveCustodyAccounts(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WsRetrieveCustodyAccounts(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestRemoveAPIKey(t *testing.T) { t.Parallel() - err := d.RemoveAPIKey(t.Context(), 0) + err := e.RemoveAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - err = d.RemoveAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + err = e.RemoveAPIKey(t.Context(), 1) assert.NoError(t, err) } func TestWSRemoveAPIKey(t *testing.T) { t.Parallel() - err := d.WSRemoveAPIKey(t.Context(), 0) + err := e.WSRemoveAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - err = d.WSRemoveAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + err = e.WSRemoveAPIKey(t.Context(), 1) assert.NoError(t, err) } func TestRemoveSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - err := d.RemoveSubAccount(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + err := e.RemoveSubAccount(t.Context(), 1) assert.NoError(t, err) } func TestWSRemoveSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - err := d.WSRemoveSubAccount(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + err := e.WSRemoveSubAccount(t.Context(), 1) assert.NoError(t, err) } func TestResetAPIKey(t *testing.T) { t.Parallel() - _, err := d.ResetAPIKey(t.Context(), 0) + _, err := e.ResetAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.ResetAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.ResetAPIKey(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, result) } func TestWSResetAPIKey(t *testing.T) { t.Parallel() - err := d.WSResetAPIKey(t.Context(), 0) + err := e.WSResetAPIKey(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - err = d.WSResetAPIKey(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + err = e.WSResetAPIKey(t.Context(), 1) assert.NoError(t, err) } func TestSetAnnouncementAsRead(t *testing.T) { t.Parallel() - err := d.SetAnnouncementAsRead(t.Context(), 0) + err := e.SetAnnouncementAsRead(t.Context(), 0) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.SetAnnouncementAsRead(t.Context(), 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.SetAnnouncementAsRead(t.Context(), 1) assert.NoError(t, err) } func TestSetEmailForSubAccount(t *testing.T) { t.Parallel() - err := d.SetEmailForSubAccount(t.Context(), 0, "wrongemail@wrongemail.com") + err := e.SetEmailForSubAccount(t.Context(), 0, "wrongemail@wrongemail.com") require.ErrorIs(t, err, errInvalidID) - err = d.SetEmailForSubAccount(t.Context(), 1, "") + err = e.SetEmailForSubAccount(t.Context(), 1, "") require.ErrorIs(t, err, errInvalidEmailAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.SetEmailForSubAccount(t.Context(), 1, "wrongemail@wrongemail.com") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.SetEmailForSubAccount(t.Context(), 1, "wrongemail@wrongemail.com") assert.NoError(t, err) } func TestWSSetEmailForSubAccount(t *testing.T) { t.Parallel() - err := d.WSSetEmailForSubAccount(t.Context(), 0, "wrongemail@wrongemail.com") + err := e.WSSetEmailForSubAccount(t.Context(), 0, "wrongemail@wrongemail.com") require.ErrorIs(t, err, errInvalidID) - err = d.WSSetEmailForSubAccount(t.Context(), 1, "") + err = e.WSSetEmailForSubAccount(t.Context(), 1, "") require.ErrorIs(t, err, errInvalidEmailAddress) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.WSSetEmailForSubAccount(t.Context(), 1, "wrongemail@wrongemail.com") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.WSSetEmailForSubAccount(t.Context(), 1, "wrongemail@wrongemail.com") assert.NoError(t, err) } func TestSetEmailLanguage(t *testing.T) { t.Parallel() - err := d.SetEmailLanguage(t.Context(), "") + err := e.SetEmailLanguage(t.Context(), "") require.ErrorIs(t, err, errLanguageIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.SetEmailLanguage(t.Context(), "en") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.SetEmailLanguage(t.Context(), "en") assert.NoError(t, err) } func TestWSSetEmailLanguage(t *testing.T) { t.Parallel() - err := d.WSSetEmailLanguage(t.Context(), "") + err := e.WSSetEmailLanguage(t.Context(), "") require.ErrorIs(t, err, errLanguageIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.WSSetEmailLanguage(t.Context(), "en") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.WSSetEmailLanguage(t.Context(), "en") assert.NoError(t, err) } func TestSetSelfTradingConfig(t *testing.T) { t.Parallel() - _, err := d.SetSelfTradingConfig(t.Context(), "", false) + _, err := e.SetSelfTradingConfig(t.Context(), "", false) require.ErrorIs(t, err, errTradeModeIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SetSelfTradingConfig(t.Context(), "reject_taker", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetSelfTradingConfig(t.Context(), "reject_taker", false) require.NoError(t, err) assert.NotNil(t, result) } func TestWsSetSelfTradingConfig(t *testing.T) { t.Parallel() - _, err := d.WsSetSelfTradingConfig(t.Context(), "", false) + _, err := e.WsSetSelfTradingConfig(t.Context(), "", false) require.ErrorIs(t, err, errTradeModeIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WsSetSelfTradingConfig(t.Context(), "reject_taker", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WsSetSelfTradingConfig(t.Context(), "reject_taker", false) require.NoError(t, err) assert.NotNil(t, result) } func TestToggleNotificationsFromSubAccount(t *testing.T) { t.Parallel() - err := d.ToggleNotificationsFromSubAccount(t.Context(), 0, false) + err := e.ToggleNotificationsFromSubAccount(t.Context(), 0, false) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.ToggleNotificationsFromSubAccount(t.Context(), 1, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.ToggleNotificationsFromSubAccount(t.Context(), 1, false) assert.NoError(t, err) } func TestWSToggleNotificationsFromSubAccount(t *testing.T) { t.Parallel() - err := d.WSToggleNotificationsFromSubAccount(t.Context(), 0, false) + err := e.WSToggleNotificationsFromSubAccount(t.Context(), 0, false) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.WSToggleNotificationsFromSubAccount(t.Context(), 1, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.WSToggleNotificationsFromSubAccount(t.Context(), 1, false) assert.NoError(t, err) } func TestTogglePortfolioMargining(t *testing.T) { t.Parallel() - _, err := d.TogglePortfolioMargining(t.Context(), 0, false, false) + _, err := e.TogglePortfolioMargining(t.Context(), 0, false, false) require.ErrorIs(t, err, errUserIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.TogglePortfolioMargining(t.Context(), 1234, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TogglePortfolioMargining(t.Context(), 1234, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSTogglePortfolioMargining(t *testing.T) { t.Parallel() - _, err := d.WSTogglePortfolioMargining(t.Context(), 0, false, false) + _, err := e.WSTogglePortfolioMargining(t.Context(), 0, false, false) require.ErrorIs(t, err, errUserIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSTogglePortfolioMargining(t.Context(), 1234, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSTogglePortfolioMargining(t.Context(), 1234, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestToggleSubAccountLogin(t *testing.T) { t.Parallel() - err := d.ToggleSubAccountLogin(t.Context(), -1, false) + err := e.ToggleSubAccountLogin(t.Context(), -1, false) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.ToggleSubAccountLogin(t.Context(), 1, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.ToggleSubAccountLogin(t.Context(), 1, false) assert.NoError(t, err) } func TestWSToggleSubAccountLogin(t *testing.T) { t.Parallel() - err := d.WSToggleSubAccountLogin(t.Context(), -1, false) + err := e.WSToggleSubAccountLogin(t.Context(), -1, false) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err = d.WSToggleSubAccountLogin(t.Context(), 1, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.WSToggleSubAccountLogin(t.Context(), 1, false) assert.NoError(t, err) } func TestSubmitBuy(t *testing.T) { t.Parallel() - pairs, err := d.GetEnabledPairs(asset.Futures) + pairs, err := e.GetEnabledPairs(asset.Futures) require.NoError(t, err) - _, err = d.SubmitBuy(t.Context(), &OrderBuyAndSellParams{}) + _, err = e.SubmitBuy(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.SubmitBuy(t.Context(), &OrderBuyAndSellParams{ + _, err = e.SubmitBuy(t.Context(), &OrderBuyAndSellParams{ Instrument: "", OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", @@ -1933,8 +1934,8 @@ func TestSubmitBuy(t *testing.T) { }) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitBuy(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitBuy(t.Context(), &OrderBuyAndSellParams{ Instrument: pairs[0].String(), OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", @@ -1949,9 +1950,9 @@ func TestSubmitBuy(t *testing.T) { func TestWSSubmitBuy(t *testing.T) { t.Parallel() - _, err := d.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{ + _, err = e.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{ Instrument: "", OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", @@ -1960,8 +1961,8 @@ func TestWSSubmitBuy(t *testing.T) { }) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitBuy(t.Context(), &OrderBuyAndSellParams{ Instrument: btcPerpInstrument, OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", @@ -1976,26 +1977,26 @@ func TestWSSubmitBuy(t *testing.T) { func TestSubmitSell(t *testing.T) { t.Parallel() - _, err := d.SubmitSell(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.SubmitSell(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) - _, err = d.SubmitSell(t.Context(), &OrderBuyAndSellParams{OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, Price: 500000, MaxShow: 0, TriggerPrice: 0, PostOnly: false, RejectPostOnly: false, ReduceOnly: false, MMP: false}) + _, err = e.SubmitSell(t.Context(), &OrderBuyAndSellParams{OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, Price: 500000, MaxShow: 0, TriggerPrice: 0, PostOnly: false, RejectPostOnly: false, ReduceOnly: false, MMP: false}) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitSell(t.Context(), &OrderBuyAndSellParams{Instrument: btcPerpInstrument, OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, Price: 500000, MaxShow: 0, TriggerPrice: 0, PostOnly: false, RejectPostOnly: false, ReduceOnly: false, MMP: false}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitSell(t.Context(), &OrderBuyAndSellParams{Instrument: btcPerpInstrument, OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, Price: 500000, MaxShow: 0, TriggerPrice: 0, PostOnly: false, RejectPostOnly: false, ReduceOnly: false, MMP: false}) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitSell(t *testing.T) { t.Parallel() - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) - _, err = d.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{}) + _, err = e.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{ + _, err = e.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{ Instrument: "", OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, @@ -2004,8 +2005,8 @@ func TestWSSubmitSell(t *testing.T) { }) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitSell(t.Context(), &OrderBuyAndSellParams{ Instrument: btcPerpInstrument, OrderType: "limit", Label: "testOrder", TimeInForce: "", Trigger: "", Advanced: "", Amount: info.ContractSize * 3, @@ -2018,21 +2019,21 @@ func TestWSSubmitSell(t *testing.T) { func TestEditOrderByLabel(t *testing.T) { t.Parallel() - _, err := d.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + _, err = e.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: "", Advanced: "", Amount: 1, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + _, err = e.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: btcPerpInstrument, Advanced: "", Amount: 0, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) require.ErrorIs(t, err, errInvalidAmount) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.EditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: btcPerpInstrument, Advanced: "", Amount: 1, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) @@ -2042,21 +2043,21 @@ func TestEditOrderByLabel(t *testing.T) { func TestWSEditOrderByLabel(t *testing.T) { t.Parallel() - _, err := d.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + _, err = e.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: "", Advanced: "", Amount: 1, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + _, err = e.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: btcPerpInstrument, Advanced: "", Amount: 0, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) require.ErrorIs(t, err, errInvalidAmount) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSEditOrderByLabel(t.Context(), &OrderBuyAndSellParams{ Label: "incorrectUserLabel", Instrument: btcPerpInstrument, Advanced: "", Amount: 1, Price: 30000, TriggerPrice: 0, PostOnly: false, ReduceOnly: false, RejectPostOnly: false, MMP: false, }) @@ -2071,212 +2072,212 @@ func TestSubmitCancel(t *testing.T) { var resp *PrivateCancelData err := json.Unmarshal([]byte(submitCancelResponseJSON), &resp) require.NoError(t, err) - _, err = d.SubmitCancel(t.Context(), "") + _, err = e.SubmitCancel(t.Context(), "") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancel(t.Context(), "incorrectID") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancel(t.Context(), "incorrectID") require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancel(t *testing.T) { t.Parallel() - _, err := d.WSSubmitCancel(t.Context(), "") + _, err := e.WSSubmitCancel(t.Context(), "") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancel(t.Context(), "incorrectID") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancel(t.Context(), "incorrectID") require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelAll(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelAll(t.Context(), false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelAll(t.Context(), false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancelAll(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancelAll(t.Context(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancelAll(t.Context(), true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelAllByCurrency(t *testing.T) { t.Parallel() - _, err := d.SubmitCancelAllByCurrency(t.Context(), currency.EMPTYCODE, "option", "", true) + _, err := e.SubmitCancelAllByCurrency(t.Context(), currency.EMPTYCODE, "option", "", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelAllByCurrency(t.Context(), currency.BTC, "option", "", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelAllByCurrency(t.Context(), currency.BTC, "option", "", true) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancelAllByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSSubmitCancelAllByCurrency(t.Context(), currency.EMPTYCODE, "option", "", true) + _, err := e.WSSubmitCancelAllByCurrency(t.Context(), currency.EMPTYCODE, "option", "", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancelAllByCurrency(t.Context(), currency.BTC, "option", "", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancelAllByCurrency(t.Context(), currency.BTC, "option", "", true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelAllByKind(t *testing.T) { t.Parallel() - _, err := d.SubmitCancelAllByKind(t.Context(), currency.EMPTYCODE, "option_combo", "trigger_all", true) + _, err := e.SubmitCancelAllByKind(t.Context(), currency.EMPTYCODE, "option_combo", "trigger_all", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelAllByKind(t.Context(), currency.ETH, "option_combo", "trigger_all", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelAllByKind(t.Context(), currency.ETH, "option_combo", "trigger_all", true) require.NoError(t, err) assert.NotNil(t, result) } func TestWsSubmitCancelAllByKind(t *testing.T) { t.Parallel() - _, err := d.WsSubmitCancelAllByKind(t.Context(), currency.EMPTYCODE, "option_combo", "trigger_all", true) + _, err := e.WsSubmitCancelAllByKind(t.Context(), currency.EMPTYCODE, "option_combo", "trigger_all", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WsSubmitCancelAllByKind(t.Context(), currency.ETH, "option_combo", "trigger_all", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WsSubmitCancelAllByKind(t.Context(), currency.ETH, "option_combo", "trigger_all", true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelAllByInstrument(t *testing.T) { t.Parallel() - _, err := d.SubmitCancelAllByInstrument(t.Context(), "", "all", true, true) + _, err := e.SubmitCancelAllByInstrument(t.Context(), "", "all", true, true) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelAllByInstrument(t.Context(), btcPerpInstrument, "all", true, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelAllByInstrument(t.Context(), btcPerpInstrument, "all", true, true) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancelAllByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSSubmitCancelAllByInstrument(t.Context(), "", "all", true, true) + _, err := e.WSSubmitCancelAllByInstrument(t.Context(), "", "all", true, true) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancelAllByInstrument(t.Context(), btcPerpInstrument, "all", true, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancelAllByInstrument(t.Context(), btcPerpInstrument, "all", true, true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelByLabel(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelByLabel(t.Context(), "incorrectOrderLabel", currency.EMPTYCODE, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelByLabel(t.Context(), "incorrectOrderLabel", currency.EMPTYCODE, true) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancelByLabel(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancelByLabel(t.Context(), "incorrectOrderLabel", currency.EMPTYCODE, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancelByLabel(t.Context(), "incorrectOrderLabel", currency.EMPTYCODE, true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitCancelQuotes(t *testing.T) { t.Parallel() - _, err := d.SubmitCancelQuotes(t.Context(), currency.EMPTYCODE, 0, 0, "all", "", futuresTradablePair.String(), "future", true) + _, err := e.SubmitCancelQuotes(t.Context(), currency.EMPTYCODE, 0, 0, "all", "", futuresTradablePair.String(), "future", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitCancelQuotes(t.Context(), currency.BTC, 0, 0, "all", "", futuresTradablePair.String(), "future", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitCancelQuotes(t.Context(), currency.BTC, 0, 0, "all", "", futuresTradablePair.String(), "future", true) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitCancelQuotes(t *testing.T) { t.Parallel() - _, err := d.WSSubmitCancelQuotes(t.Context(), currency.EMPTYCODE, 0, 0, "all", "", futuresTradablePair.String(), "future", true) + _, err := e.WSSubmitCancelQuotes(t.Context(), currency.EMPTYCODE, 0, 0, "all", "", futuresTradablePair.String(), "future", true) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitCancelQuotes(t.Context(), currency.BTC, 0, 0, "all", "", futuresTradablePair.String(), "future", true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitCancelQuotes(t.Context(), currency.BTC, 0, 0, "all", "", futuresTradablePair.String(), "future", true) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitClosePosition(t *testing.T) { t.Parallel() - _, err := d.SubmitClosePosition(t.Context(), "", "limit", 35000) + _, err := e.SubmitClosePosition(t.Context(), "", "limit", 35000) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitClosePosition(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), "limit", 35000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitClosePosition(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), "limit", 35000) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitClosePosition(t *testing.T) { t.Parallel() - _, err := d.WSSubmitClosePosition(t.Context(), "", "limit", 35000) + _, err := e.WSSubmitClosePosition(t.Context(), "", "limit", 35000) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitClosePosition(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), "limit", 35000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitClosePosition(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), "limit", 35000) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMargins(t *testing.T) { t.Parallel() - _, err := d.GetMargins(t.Context(), "", 5, 35000) + _, err := e.GetMargins(t.Context(), "", 5, 35000) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.GetMargins(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 0, 35000) + _, err = e.GetMargins(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 0, 35000) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.GetMargins(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 5, -1) + _, err = e.GetMargins(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 5, -1) require.ErrorIs(t, err, errInvalidPrice) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetMargins(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 5, 35000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMargins(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 5, 35000) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveMargins(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveMargins(t.Context(), "", 5, 35000) + _, err := e.WSRetrieveMargins(t.Context(), "", 5, 35000) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveMargins(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 5, 35000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveMargins(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 5, 35000) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMMPConfig(t *testing.T) { t.Parallel() - _, err := d.GetMMPConfig(t.Context(), currency.EMPTYCODE) + _, err := e.GetMMPConfig(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetMMPConfig(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMMPConfig(t.Context(), currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveMMPConfig(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveMMPConfig(t.Context(), currency.EMPTYCODE) + _, err := e.WSRetrieveMMPConfig(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveMMPConfig(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveMMPConfig(t.Context(), currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } @@ -2288,198 +2289,198 @@ func TestGetOpenOrdersByCurrency(t *testing.T) { var resp []OrderData err := json.Unmarshal([]byte(getOpenOrdersByCurrencyResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetOpenOrdersByCurrency(t.Context(), currency.EMPTYCODE, "option", "all") + _, err = e.GetOpenOrdersByCurrency(t.Context(), currency.EMPTYCODE, "option", "all") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOpenOrdersByCurrency(t.Context(), currency.BTC, "option", "all") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOpenOrdersByCurrency(t.Context(), currency.BTC, "option", "all") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOpenOrdersByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOpenOrdersByCurrency(t.Context(), currency.EMPTYCODE, "option", "all") + _, err := e.WSRetrieveOpenOrdersByCurrency(t.Context(), currency.EMPTYCODE, "option", "all") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveOpenOrdersByCurrency(t.Context(), currency.BTC, "option", "all") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveOpenOrdersByCurrency(t.Context(), currency.BTC, "option", "all") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenOrdersByLabel(t *testing.T) { t.Parallel() - _, err := d.GetOpenOrdersByLabel(t.Context(), currency.EMPTYCODE, "the-label") + _, err := e.GetOpenOrdersByLabel(t.Context(), currency.EMPTYCODE, "the-label") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOpenOrdersByLabel(t.Context(), currency.EURR, "the-label") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOpenOrdersByLabel(t.Context(), currency.EURR, "the-label") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOpenOrdersByLabel(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOpenOrdersByLabel(t.Context(), currency.EMPTYCODE, "the-label") + _, err := e.WSRetrieveOpenOrdersByLabel(t.Context(), currency.EMPTYCODE, "the-label") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSRetrieveOpenOrdersByLabel(t.Context(), currency.EURR, "the-label") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSRetrieveOpenOrdersByLabel(t.Context(), currency.EURR, "the-label") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenOrdersByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetOpenOrdersByInstrument(t.Context(), "", "all") + _, err := e.GetOpenOrdersByInstrument(t.Context(), "", "all") require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOpenOrdersByInstrument(t.Context(), btcPerpInstrument, "all") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOpenOrdersByInstrument(t.Context(), btcPerpInstrument, "all") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOpenOrdersByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOpenOrdersByInstrument(t.Context(), "", "all") + _, err := e.WSRetrieveOpenOrdersByInstrument(t.Context(), "", "all") require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveOpenOrdersByInstrument(t.Context(), btcPerpInstrument, "all") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveOpenOrdersByInstrument(t.Context(), btcPerpInstrument, "all") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderHistoryByCurrency(t *testing.T) { t.Parallel() - _, err := d.GetOrderHistoryByCurrency(t.Context(), currency.EMPTYCODE, "future", 0, 0, false, false) + _, err := e.GetOrderHistoryByCurrency(t.Context(), currency.EMPTYCODE, "future", 0, 0, false, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOrderHistoryByCurrency(t.Context(), currency.BTC, "future", 0, 0, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderHistoryByCurrency(t.Context(), currency.BTC, "future", 0, 0, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOrderHistoryByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOrderHistoryByCurrency(t.Context(), currency.EMPTYCODE, "future", 0, 0, false, false) + _, err := e.WSRetrieveOrderHistoryByCurrency(t.Context(), currency.EMPTYCODE, "future", 0, 0, false, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveOrderHistoryByCurrency(t.Context(), currency.BTC, "future", 0, 0, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveOrderHistoryByCurrency(t.Context(), currency.BTC, "future", 0, 0, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderHistoryByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetOrderHistoryByInstrument(t.Context(), "", 0, 0, false, false) + _, err := e.GetOrderHistoryByInstrument(t.Context(), "", 0, 0, false, false) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOrderHistoryByInstrument(t.Context(), btcPerpInstrument, 0, 0, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderHistoryByInstrument(t.Context(), btcPerpInstrument, 0, 0, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOrderHistoryByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOrderHistoryByInstrument(t.Context(), "", 0, 0, false, false) + _, err := e.WSRetrieveOrderHistoryByInstrument(t.Context(), "", 0, 0, false, false) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveOrderHistoryByInstrument(t.Context(), btcPerpInstrument, 0, 0, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveOrderHistoryByInstrument(t.Context(), btcPerpInstrument, 0, 0, false, false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderMarginsByID(t *testing.T) { t.Parallel() - _, err := d.GetOrderMarginsByID(t.Context(), []string{}) + _, err := e.GetOrderMarginsByID(t.Context(), []string{}) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOrderMarginsByID(t.Context(), []string{"21422175153", "21422175154"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderMarginsByID(t.Context(), []string{"21422175153", "21422175154"}) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveOrderMarginsByID(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveOrderMarginsByID(t.Context(), []string{}) + _, err := e.WSRetrieveOrderMarginsByID(t.Context(), []string{}) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveOrderMarginsByID(t.Context(), []string{"ETH-349280", "ETH-349279", "ETH-349278"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveOrderMarginsByID(t.Context(), []string{"ETH-349280", "ETH-349279", "ETH-349278"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderState(t *testing.T) { t.Parallel() - _, err := d.GetOrderState(t.Context(), "") + _, err := e.GetOrderState(t.Context(), "") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOrderState(t.Context(), "brokenid123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderState(t.Context(), "brokenid123") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrievesOrderState(t *testing.T) { t.Parallel() - _, err := d.WSRetrievesOrderState(t.Context(), "") + _, err := e.WSRetrievesOrderState(t.Context(), "") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrievesOrderState(t.Context(), "brokenid123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrievesOrderState(t.Context(), "brokenid123") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderStateByLabel(t *testing.T) { t.Parallel() - _, err := d.GetOrderStateByLabel(t.Context(), currency.EMPTYCODE, "the-label") + _, err := e.GetOrderStateByLabel(t.Context(), currency.EMPTYCODE, "the-label") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetOrderStateByLabel(t.Context(), currency.EURR, "the-label") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderStateByLabel(t.Context(), currency.EURR, "the-label") require.NoError(t, err) assert.NotNil(t, result) } func TestWsRetrieveOrderStateByLabel(t *testing.T) { t.Parallel() - _, err := d.WsRetrieveOrderStateByLabel(t.Context(), currency.EMPTYCODE, "the-label") + _, err := e.WsRetrieveOrderStateByLabel(t.Context(), currency.EMPTYCODE, "the-label") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WsRetrieveOrderStateByLabel(t.Context(), currency.EURR, "the-label") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WsRetrieveOrderStateByLabel(t.Context(), currency.EURR, "the-label") require.NoError(t, err) assert.NotNil(t, result) } func TestGetTriggerOrderHistory(t *testing.T) { t.Parallel() - _, err := d.GetTriggerOrderHistory(t.Context(), currency.EMPTYCODE, "", "", 0) + _, err := e.GetTriggerOrderHistory(t.Context(), currency.EMPTYCODE, "", "", 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetTriggerOrderHistory(t.Context(), currency.ETH, "", "", 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTriggerOrderHistory(t.Context(), currency.ETH, "", "", 0) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveTriggerOrderHistory(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveTriggerOrderHistory(t.Context(), currency.EMPTYCODE, "", "", 0) + _, err := e.WSRetrieveTriggerOrderHistory(t.Context(), currency.EMPTYCODE, "", "", 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveTriggerOrderHistory(t.Context(), currency.ETH, "", "", 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveTriggerOrderHistory(t.Context(), currency.ETH, "", "", 0) require.NoError(t, err) assert.NotNil(t, result) } @@ -2491,192 +2492,192 @@ func TestGetUserTradesByCurrency(t *testing.T) { var resp *UserTradesData err := json.Unmarshal([]byte(getUserTradesByCurrencyResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetUserTradesByCurrency(t.Context(), currency.EMPTYCODE, "future", "", "", "asc", 0, false) + _, err = e.GetUserTradesByCurrency(t.Context(), currency.EMPTYCODE, "future", "", "", "asc", 0, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserTradesByCurrency(t.Context(), currency.ETH, "future", "", "", "asc", 0, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserTradesByCurrency(t.Context(), currency.ETH, "future", "", "", "asc", 0, false) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserTradesByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveUserTradesByCurrency(t.Context(), currency.EMPTYCODE, "future", "", "", "asc", 0, false) + _, err := e.WSRetrieveUserTradesByCurrency(t.Context(), currency.EMPTYCODE, "future", "", "", "asc", 0, false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserTradesByCurrency(t.Context(), currency.ETH, "future", "", "", "asc", 0, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserTradesByCurrency(t.Context(), currency.ETH, "future", "", "", "asc", 0, false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserTradesByCurrencyAndTime(t *testing.T) { t.Parallel() - _, err := d.GetUserTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "future", "default", 5, time.Now().Add(-time.Hour*10), time.Now().Add(-time.Hour*1)) + _, err := e.GetUserTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "future", "default", 5, time.Now().Add(-time.Hour*10), time.Now().Add(-time.Hour*1)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserTradesByCurrencyAndTime(t.Context(), currency.ETH, "future", "default", 5, time.Now().Add(-time.Hour*10), time.Now().Add(-time.Hour*1)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserTradesByCurrencyAndTime(t.Context(), currency.ETH, "future", "default", 5, time.Now().Add(-time.Hour*10), time.Now().Add(-time.Hour*1)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserTradesByCurrencyAndTime(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveUserTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "future", "default", 5, time.Now().Add(-time.Hour*4), time.Now()) + _, err := e.WSRetrieveUserTradesByCurrencyAndTime(t.Context(), currency.EMPTYCODE, "future", "default", 5, time.Now().Add(-time.Hour*4), time.Now()) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserTradesByCurrencyAndTime(t.Context(), currency.ETH, "future", "default", 5, time.Now().Add(-time.Hour*4), time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserTradesByCurrencyAndTime(t.Context(), currency.ETH, "future", "default", 5, time.Now().Add(-time.Hour*4), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserTradesByInstrument(t *testing.T) { t.Parallel() - _, err := d.GetUserTradesByInstrument(t.Context(), "", "asc", 5, 10, 4, true) + _, err := e.GetUserTradesByInstrument(t.Context(), "", "asc", 5, 10, 4, true) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserTradesByInstrument(t.Context(), btcPerpInstrument, "asc", 5, 10, 4, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserTradesByInstrument(t.Context(), btcPerpInstrument, "asc", 5, 10, 4, true) require.NoError(t, err) assert.NotNil(t, result) } func TestWsRetrieveUserTradesByInstrument(t *testing.T) { t.Parallel() - _, err := d.WsRetrieveUserTradesByInstrument(t.Context(), "", "asc", 5, 10, 4, true) + _, err := e.WsRetrieveUserTradesByInstrument(t.Context(), "", "asc", 5, 10, 4, true) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WsRetrieveUserTradesByInstrument(t.Context(), btcPerpInstrument, "asc", 5, 10, 4, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WsRetrieveUserTradesByInstrument(t.Context(), btcPerpInstrument, "asc", 5, 10, 4, true) require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserTradesByInstrumentAndTime(t *testing.T) { t.Parallel() - _, err := d.GetUserTradesByInstrumentAndTime(t.Context(), "", "asc", 10, time.Now().Add(-time.Hour), time.Now()) + _, err := e.GetUserTradesByInstrumentAndTime(t.Context(), "", "asc", 10, time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserTradesByInstrumentAndTime(t.Context(), btcPerpInstrument, "asc", 10, time.Now().Add(-time.Hour), time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserTradesByInstrumentAndTime(t.Context(), btcPerpInstrument, "asc", 10, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserTradesByInstrumentAndTime(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveUserTradesByInstrumentAndTime(t.Context(), "", "asc", 10, false, time.Now().Add(-time.Hour), time.Now()) + _, err := e.WSRetrieveUserTradesByInstrumentAndTime(t.Context(), "", "asc", 10, false, time.Now().Add(-time.Hour), time.Now()) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserTradesByInstrumentAndTime(t.Context(), btcPerpInstrument, "asc", 10, false, time.Now().Add(-time.Hour), time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserTradesByInstrumentAndTime(t.Context(), btcPerpInstrument, "asc", 10, false, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserTradesByOrder(t *testing.T) { t.Parallel() - _, err := d.GetUserTradesByOrder(t.Context(), "", "default") + _, err := e.GetUserTradesByOrder(t.Context(), "", "default") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserTradesByOrder(t.Context(), "wrongOrderID", "default") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserTradesByOrder(t.Context(), "wrongOrderID", "default") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserTradesByOrder(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveUserTradesByOrder(t.Context(), "", "default") + _, err := e.WSRetrieveUserTradesByOrder(t.Context(), "", "default") require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserTradesByOrder(t.Context(), "wrongOrderID", "default") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserTradesByOrder(t.Context(), "wrongOrderID", "default") require.NoError(t, err) assert.NotNil(t, result) } func TestResetMMP(t *testing.T) { t.Parallel() - err := d.ResetMMP(t.Context(), currency.EMPTYCODE) + err := e.ResetMMP(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.ResetMMP(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.ResetMMP(t.Context(), currency.BTC) assert.NoError(t, err) } func TestWSResetMMP(t *testing.T) { t.Parallel() - err := d.WSResetMMP(t.Context(), currency.EMPTYCODE) + err := e.WSResetMMP(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.WSResetMMP(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.WSResetMMP(t.Context(), currency.BTC) assert.NoError(t, err) } func TestSendRequestForQuote(t *testing.T) { t.Parallel() - err := d.SendRequestForQuote(t.Context(), "", 1000, order.Buy) + err := e.SendRequestForQuote(t.Context(), "", 1000, order.Buy) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.SendRequestForQuote(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 1000, order.Buy) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.SendRequestForQuote(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 1000, order.Buy) assert.NoError(t, err) } func TestWSSendRequestForQuote(t *testing.T) { t.Parallel() - err := d.WSSendRequestForQuote(t.Context(), "", 1000, order.Buy) + err := e.WSSendRequestForQuote(t.Context(), "", 1000, order.Buy) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.WSSendRequestForQuote(t.Context(), d.formatFuturesTradablePair(futuresTradablePair), 1000, order.Buy) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.WSSendRequestForQuote(t.Context(), e.formatFuturesTradablePair(futuresTradablePair), 1000, order.Buy) assert.NoError(t, err) } func TestSetMMPConfig(t *testing.T) { t.Parallel() - err := d.SetMMPConfig(t.Context(), currency.EMPTYCODE, kline.FiveMin, 5, 0, 0) + err := e.SetMMPConfig(t.Context(), currency.EMPTYCODE, kline.FiveMin, 5, 0, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.SetMMPConfig(t.Context(), currency.BTC, kline.FiveMin, 5, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.SetMMPConfig(t.Context(), currency.BTC, kline.FiveMin, 5, 0, 0) assert.NoError(t, err) } func TestWSSetMMPConfig(t *testing.T) { t.Parallel() - err := d.WSSetMMPConfig(t.Context(), currency.EMPTYCODE, kline.FiveMin, 5, 0, 0) + err := e.WSSetMMPConfig(t.Context(), currency.EMPTYCODE, kline.FiveMin, 5, 0, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.WSSetMMPConfig(t.Context(), currency.BTC, kline.FiveMin, 5, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.WSSetMMPConfig(t.Context(), currency.BTC, kline.FiveMin, 5, 0, 0) assert.NoError(t, err) } func TestGetSettlementHistoryByCurency(t *testing.T) { t.Parallel() - _, err := d.GetSettlementHistoryByCurency(t.Context(), currency.EMPTYCODE, "settlement", "", 10, time.Now().Add(-time.Hour)) + _, err := e.GetSettlementHistoryByCurency(t.Context(), currency.EMPTYCODE, "settlement", "", 10, time.Now().Add(-time.Hour)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetSettlementHistoryByCurency(t.Context(), currency.BTC, "settlement", "", 10, time.Now().Add(-time.Hour)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSettlementHistoryByCurency(t.Context(), currency.BTC, "settlement", "", 10, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveSettlementHistoryByCurency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveSettlementHistoryByCurency(t.Context(), currency.EMPTYCODE, "settlement", "", 10, time.Now().Add(-time.Hour)) + _, err := e.WSRetrieveSettlementHistoryByCurency(t.Context(), currency.EMPTYCODE, "settlement", "", 10, time.Now().Add(-time.Hour)) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveSettlementHistoryByCurency(t.Context(), currency.BTC, "settlement", "", 10, time.Now().Add(-time.Hour)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveSettlementHistoryByCurency(t.Context(), currency.BTC, "settlement", "", 10, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } @@ -2689,43 +2690,43 @@ func TestGetSettlementHistoryByInstrument(t *testing.T) { err := json.Unmarshal([]byte(getSettlementHistoryByInstrumentResponseJSON), &result) require.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err = d.GetSettlementHistoryByInstrument(t.Context(), btcPerpInstrument, "settlement", "", 10, time.Now().Add(-time.Hour)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err = e.GetSettlementHistoryByInstrument(t.Context(), btcPerpInstrument, "settlement", "", 10, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveSettlementHistoryByInstrument(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveSettlementHistoryByInstrument(t.Context(), "", "settlement", "", 10, time.Now().Add(-time.Hour)) + _, err := e.WSRetrieveSettlementHistoryByInstrument(t.Context(), "", "settlement", "", 10, time.Now().Add(-time.Hour)) require.ErrorIs(t, err, errInvalidInstrumentName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveSettlementHistoryByInstrument(t.Context(), btcPerpInstrument, "settlement", "", 10, time.Now().Add(-time.Hour)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveSettlementHistoryByInstrument(t.Context(), btcPerpInstrument, "settlement", "", 10, time.Now().Add(-time.Hour)) require.NoError(t, err) assert.NotNil(t, result) } func TestSubmitEdit(t *testing.T) { t.Parallel() - _, err := d.SubmitEdit(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.SubmitEdit(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = d.SubmitEdit(t.Context(), &OrderBuyAndSellParams{OrderID: "", Advanced: "", TriggerPrice: 0.001, Price: 100000, Amount: 123}) + _, err = e.SubmitEdit(t.Context(), &OrderBuyAndSellParams{OrderID: "", Advanced: "", TriggerPrice: 0.001, Price: 100000, Amount: 123}) require.ErrorIs(t, err, errInvalidID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.SubmitEdit(t.Context(), &OrderBuyAndSellParams{OrderID: "incorrectID", Advanced: "", TriggerPrice: 0.001, Price: 100000, Amount: 123}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubmitEdit(t.Context(), &OrderBuyAndSellParams{OrderID: "incorrectID", Advanced: "", TriggerPrice: 0.001, Price: 100000, Amount: 123}) require.NoError(t, err) assert.NotNil(t, result) } func TestWSSubmitEdit(t *testing.T) { t.Parallel() - _, err := d.WSSubmitEdit(t.Context(), &OrderBuyAndSellParams{}) + _, err := e.WSSubmitEdit(t.Context(), &OrderBuyAndSellParams{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSSubmitEdit(t.Context(), &OrderBuyAndSellParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSSubmitEdit(t.Context(), &OrderBuyAndSellParams{ OrderID: "incorrectID", Advanced: "", TriggerPrice: 0.001, @@ -2740,64 +2741,64 @@ func TestWSSubmitEdit(t *testing.T) { func TestGetComboIDS(t *testing.T) { t.Parallel() - _, err := d.GetComboIDs(t.Context(), currency.EMPTYCODE, "") + _, err := e.GetComboIDs(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetComboIDs(t.Context(), currency.BTC, "") + result, err := e.GetComboIDs(t.Context(), currency.BTC, "") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveComboIDS(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveComboIDs(t.Context(), currency.EMPTYCODE, "") + _, err := e.WSRetrieveComboIDs(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - combos, err := d.WSRetrieveComboIDs(t.Context(), currency.BTC, "") + combos, err := e.WSRetrieveComboIDs(t.Context(), currency.BTC, "") require.NoError(t, err) assert.NotEmpty(t, combos) } func TestGetComboDetails(t *testing.T) { t.Parallel() - _, err := d.GetComboDetails(t.Context(), "") + _, err := e.GetComboDetails(t.Context(), "") require.ErrorIs(t, err, errInvalidComboID) - result, err := d.GetComboDetails(t.Context(), futureComboTradablePair.String()) + result, err := e.GetComboDetails(t.Context(), futureComboTradablePair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveComboDetails(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveComboDetails(t.Context(), "") + _, err := e.WSRetrieveComboDetails(t.Context(), "") require.ErrorIs(t, err, errInvalidComboID) - result, err := d.WSRetrieveComboDetails(t.Context(), futureComboTradablePair.String()) + result, err := e.WSRetrieveComboDetails(t.Context(), futureComboTradablePair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCombos(t *testing.T) { t.Parallel() - _, err := d.GetCombos(t.Context(), currency.EMPTYCODE) + _, err := e.GetCombos(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.GetCombos(t.Context(), currency.BTC) + result, err := e.GetCombos(t.Context(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestCreateCombo(t *testing.T) { t.Parallel() - _, err := d.CreateCombo(t.Context(), []ComboParam{}) + _, err := e.CreateCombo(t.Context(), []ComboParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - instruments, err := d.GetEnabledPairs(asset.Futures) + instruments, err := e.GetEnabledPairs(asset.Futures) require.NoError(t, err) if len(instruments) < 2 { t.Skip("no enough instrument found") } - _, err = d.CreateCombo(t.Context(), []ComboParam{ + _, err = e.CreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Direction: "sell", @@ -2809,7 +2810,7 @@ func TestCreateCombo(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.CreateCombo(t.Context(), []ComboParam{ + _, err = e.CreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Amount: 123, @@ -2821,7 +2822,7 @@ func TestCreateCombo(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidOrderSideOrDirection) - _, err = d.CreateCombo(t.Context(), []ComboParam{ + _, err = e.CreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Direction: "buy", @@ -2835,8 +2836,8 @@ func TestCreateCombo(t *testing.T) { }) require.ErrorIs(t, err, errDifferentInstruments) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.CreateCombo(t.Context(), []ComboParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Direction: "buy", @@ -2854,16 +2855,16 @@ func TestCreateCombo(t *testing.T) { func TestWSCreateCombo(t *testing.T) { t.Parallel() - _, err := d.WSCreateCombo(t.Context(), []ComboParam{}) + _, err := e.WSCreateCombo(t.Context(), []ComboParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - instruments, err := d.GetEnabledPairs(asset.Futures) + instruments, err := e.GetEnabledPairs(asset.Futures) require.NoError(t, err) if len(instruments) < 2 { t.Skip("no enough instrument found") } - _, err = d.WSCreateCombo(t.Context(), []ComboParam{}) + _, err = e.WSCreateCombo(t.Context(), []ComboParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - _, err = d.WSCreateCombo(t.Context(), []ComboParam{ + _, err = e.WSCreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Direction: "sell", @@ -2875,7 +2876,7 @@ func TestWSCreateCombo(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WSCreateCombo(t.Context(), []ComboParam{ + _, err = e.WSCreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Amount: 123, @@ -2888,8 +2889,8 @@ func TestWSCreateCombo(t *testing.T) { }) require.ErrorIs(t, err, errInvalidOrderSideOrDirection) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSCreateCombo(t.Context(), []ComboParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSCreateCombo(t.Context(), []ComboParam{ { InstrumentName: instruments[0].String(), Direction: "sell", @@ -2907,16 +2908,16 @@ func TestWSCreateCombo(t *testing.T) { func TestVerifyBlockTrade(t *testing.T) { t.Parallel() - _, err := d.VerifyBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err := e.VerifyBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingNonce) - _, err = d.VerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.VerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.VerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.VerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) require.NotNil(t, info) - _, err = d.VerifyBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ + _, err = e.VerifyBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -2926,8 +2927,8 @@ func TestVerifyBlockTrade(t *testing.T) { }) require.ErrorIs(t, err, errZeroTimestamp) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.VerifyBlockTrade(t.Context(), time.Now(), "something", "maker", currency.EMPTYCODE, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.VerifyBlockTrade(t.Context(), time.Now(), "something", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -2941,16 +2942,16 @@ func TestVerifyBlockTrade(t *testing.T) { func TestWSVerifyBlockTrade(t *testing.T) { t.Parallel() - _, err := d.WSVerifyBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err := e.WSVerifyBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingNonce) - _, err = d.WSVerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.WSVerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.WSVerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.WSVerifyBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) require.NotNil(t, info) - _, err = d.WSVerifyBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ + _, err = e.WSVerifyBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -2960,8 +2961,8 @@ func TestWSVerifyBlockTrade(t *testing.T) { }) require.ErrorIs(t, err, errZeroTimestamp) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSVerifyBlockTrade(t.Context(), time.Now(), "sdjkafdad", "maker", currency.EMPTYCODE, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSVerifyBlockTrade(t.Context(), time.Now(), "sdjkafdad", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 28000, InstrumentName: btcPerpInstrument, @@ -2975,34 +2976,34 @@ func TestWSVerifyBlockTrade(t *testing.T) { func TestInvalidateBlockTradeSignature(t *testing.T) { t.Parallel() - err := d.WsInvalidateBlockTradeSignature(t.Context(), "") + err := e.WsInvalidateBlockTradeSignature(t.Context(), "") require.ErrorIs(t, err, errMissingSignature) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.InvalidateBlockTradeSignature(t.Context(), "verified_signature_string") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.InvalidateBlockTradeSignature(t.Context(), "verified_signature_string") assert.NoError(t, err) } func TestWsInvalidateBlockTradeSignature(t *testing.T) { t.Parallel() - err := d.WsInvalidateBlockTradeSignature(t.Context(), "") + err := e.WsInvalidateBlockTradeSignature(t.Context(), "") require.ErrorIs(t, err, errMissingSignature) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - err = d.WsInvalidateBlockTradeSignature(t.Context(), "verified_signature_string") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err = e.WsInvalidateBlockTradeSignature(t.Context(), "verified_signature_string") assert.NoError(t, err) } func TestExecuteBlockTrade(t *testing.T) { t.Parallel() - _, err := d.ExecuteBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err := e.ExecuteBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingNonce) - _, err = d.ExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.ExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.ExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.ExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) require.NotNil(t, info) - _, err = d.ExecuteBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ + _, err = e.ExecuteBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3012,8 +3013,8 @@ func TestExecuteBlockTrade(t *testing.T) { }) require.ErrorIs(t, err, errZeroTimestamp) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.ExecuteBlockTrade(t.Context(), time.Now(), "something", "maker", currency.EMPTYCODE, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ExecuteBlockTrade(t.Context(), time.Now(), "something", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3027,16 +3028,16 @@ func TestExecuteBlockTrade(t *testing.T) { func TestWSExecuteBlockTrade(t *testing.T) { t.Parallel() - _, err := d.WSExecuteBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err := e.WSExecuteBlockTrade(t.Context(), time.Now(), "", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingNonce) - _, err = d.WSExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.WSExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.WSExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) + _, err = e.WSExecuteBlockTrade(t.Context(), time.Now(), "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - info, err := d.GetInstrument(t.Context(), btcPerpInstrument) + info, err := e.GetInstrument(t.Context(), btcPerpInstrument) require.NoError(t, err) require.NotNil(t, info) - _, err = d.WSExecuteBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{{ + _, err = e.WSExecuteBlockTrade(t.Context(), time.Time{}, "nonce-string", "maker", currency.EMPTYCODE, []BlockTradeParam{{ Price: 0.777 * 22000, InstrumentName: btcPerpInstrument, Direction: "buy", @@ -3044,8 +3045,8 @@ func TestWSExecuteBlockTrade(t *testing.T) { }}) require.ErrorIs(t, err, errZeroTimestamp) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSExecuteBlockTrade(t.Context(), time.Now(), "sdjkafdad", "maker", currency.EMPTYCODE, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSExecuteBlockTrade(t.Context(), time.Now(), "sdjkafdad", "maker", currency.EMPTYCODE, []BlockTradeParam{ { Price: 0.777 * 22000, InstrumentName: btcPerpInstrument, @@ -3064,57 +3065,57 @@ func TestGetUserBlocTrade(t *testing.T) { var resp []BlockTradeData err := json.Unmarshal([]byte(getUserBlocTradeResponseJSON), &resp) require.NoError(t, err) - _, err = d.GetUserBlockTrade(t.Context(), "") + _, err = e.GetUserBlockTrade(t.Context(), "") require.ErrorIs(t, err, errMissingBlockTradeID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetUserBlockTrade(t.Context(), "12345567") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserBlockTrade(t.Context(), "12345567") require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveUserBlockTrade(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveUserBlockTrade(t.Context(), "") + _, err := e.WSRetrieveUserBlockTrade(t.Context(), "") require.ErrorIs(t, err, errMissingBlockTradeID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveUserBlockTrade(t.Context(), "12345567") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveUserBlockTrade(t.Context(), "12345567") require.NoError(t, err) assert.NotNil(t, result) } func TestGetLastBlockTradesbyCurrency(t *testing.T) { t.Parallel() - _, err := d.GetLastBlockTradesByCurrency(t.Context(), currency.EMPTYCODE, "", "", 5) + _, err := e.GetLastBlockTradesByCurrency(t.Context(), currency.EMPTYCODE, "", "", 5) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetLastBlockTradesByCurrency(t.Context(), currency.SOL, "", "", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLastBlockTradesByCurrency(t.Context(), currency.SOL, "", "", 5) require.NoError(t, err) assert.NotNil(t, result) } func TestWSRetrieveLastBlockTradesByCurrency(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveLastBlockTradesByCurrency(t.Context(), currency.EMPTYCODE, "", "", 5) + _, err := e.WSRetrieveLastBlockTradesByCurrency(t.Context(), currency.EMPTYCODE, "", "", 5) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WSRetrieveLastBlockTradesByCurrency(t.Context(), currency.SOL, "", "", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WSRetrieveLastBlockTradesByCurrency(t.Context(), currency.SOL, "", "", 5) require.NoError(t, err) assert.NotNil(t, result) } func TestMovePositions(t *testing.T) { t.Parallel() - _, err := d.MovePositions(t.Context(), currency.EMPTYCODE, 123, 345, []BlockTradeParam{}) + _, err := e.MovePositions(t.Context(), currency.EMPTYCODE, 123, 345, []BlockTradeParam{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.MovePositions(t.Context(), currency.BTC, 0, 345, []BlockTradeParam{}) + _, err = e.MovePositions(t.Context(), currency.BTC, 0, 345, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingSubAccountID) - _, err = d.MovePositions(t.Context(), currency.BTC, 123, 0, []BlockTradeParam{}) + _, err = e.MovePositions(t.Context(), currency.BTC, 123, 0, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingSubAccountID) - _, err = d.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "", @@ -3123,7 +3124,7 @@ func TestMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "BTC-PERPETUAL", @@ -3132,7 +3133,7 @@ func TestMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: -4, InstrumentName: "BTC-PERPETUAL", @@ -3141,12 +3142,12 @@ func TestMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidPrice) - info, err := d.GetInstrument(t.Context(), "BTC-PERPETUAL") + info, err := e.GetInstrument(t.Context(), "BTC-PERPETUAL") require.NoError(t, err) require.NotNil(t, info) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.MovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "BTC-PERPETUAL", @@ -3160,13 +3161,13 @@ func TestMovePositions(t *testing.T) { func TestWSMovePositions(t *testing.T) { t.Parallel() - _, err := d.WSMovePositions(t.Context(), currency.EMPTYCODE, 123, 345, []BlockTradeParam{}) + _, err := e.WSMovePositions(t.Context(), currency.EMPTYCODE, 123, 345, []BlockTradeParam{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = d.WSMovePositions(t.Context(), currency.BTC, 0, 345, []BlockTradeParam{}) + _, err = e.WSMovePositions(t.Context(), currency.BTC, 0, 345, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingSubAccountID) - _, err = d.WSMovePositions(t.Context(), currency.BTC, 123, 0, []BlockTradeParam{}) + _, err = e.WSMovePositions(t.Context(), currency.BTC, 123, 0, []BlockTradeParam{}) require.ErrorIs(t, err, errMissingSubAccountID) - _, err = d.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "", @@ -3175,7 +3176,7 @@ func TestWSMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "BTC-PERPETUAL", @@ -3184,7 +3185,7 @@ func TestWSMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + _, err = e.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: -4, InstrumentName: "BTC-PERPETUAL", @@ -3193,12 +3194,12 @@ func TestWSMovePositions(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidPrice) - info, err := d.GetInstrument(t.Context(), "BTC-PERPETUAL") + info, err := e.GetInstrument(t.Context(), "BTC-PERPETUAL") require.NoError(t, err) require.NotNil(t, info) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WSMovePositions(t.Context(), currency.BTC, 123, 345, []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3212,11 +3213,11 @@ func TestWSMovePositions(t *testing.T) { func TestSimulateBlockTrade(t *testing.T) { t.Parallel() - _, err := d.SimulateBlockTrade(t.Context(), "", []BlockTradeParam{}) + _, err := e.SimulateBlockTrade(t.Context(), "", []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{}) + _, err = e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - _, err = d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "", @@ -3225,7 +3226,7 @@ func TestSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3234,7 +3235,7 @@ func TestSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidOrderSideOrDirection) - _, err = d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3243,7 +3244,7 @@ func TestSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: -1, InstrumentName: btcPerpInstrument, @@ -3253,10 +3254,10 @@ func TestSimulateBlockTrade(t *testing.T) { }) require.ErrorIs(t, err, errInvalidPrice) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - info, err := d.GetInstrument(t.Context(), "BTC-PERPETUAL") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + info, err := e.GetInstrument(t.Context(), "BTC-PERPETUAL") require.NoError(t, err) - result, err := d.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + result, err := e.SimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3270,11 +3271,11 @@ func TestSimulateBlockTrade(t *testing.T) { func TestWsSimulateBlockTrade(t *testing.T) { t.Parallel() - _, err := d.WsSimulateBlockTrade(t.Context(), "", []BlockTradeParam{}) + _, err := e.WsSimulateBlockTrade(t.Context(), "", []BlockTradeParam{}) require.ErrorIs(t, err, errInvalidTradeRole) - _, err = d.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{}) + _, err = e.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{}) require.ErrorIs(t, err, errNoArgumentPassed) - _, err = d.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: "", @@ -3283,7 +3284,7 @@ func TestWsSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidInstrumentName) - _, err = d.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3292,7 +3293,7 @@ func TestWsSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidOrderSideOrDirection) - _, err = d.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3301,7 +3302,7 @@ func TestWsSimulateBlockTrade(t *testing.T) { }, }) require.ErrorIs(t, err, errInvalidAmount) - _, err = d.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ + _, err = e.WsSimulateBlockTrade(t.Context(), "maker", []BlockTradeParam{ { Price: -1, InstrumentName: btcPerpInstrument, @@ -3311,11 +3312,11 @@ func TestWsSimulateBlockTrade(t *testing.T) { }) require.ErrorIs(t, err, errInvalidPrice) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - info, err := d.GetInstrument(t.Context(), "BTC-PERPETUAL") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + info, err := e.GetInstrument(t.Context(), "BTC-PERPETUAL") require.NoError(t, err) require.NotNil(t, info) - result, err := d.WsSimulateBlockTrade(t.Context(), "taker", []BlockTradeParam{ + result, err := e.WsSimulateBlockTrade(t.Context(), "taker", []BlockTradeParam{ { Price: 0.777 * 25000, InstrumentName: btcPerpInstrument, @@ -3328,13 +3329,13 @@ func TestWsSimulateBlockTrade(t *testing.T) { } func setupWs() { - if !d.Websocket.IsEnabled() { + if !e.Websocket.IsEnabled() { return } - if !sharedtestvalues.AreAPICredentialsSet(d) { - d.Websocket.SetCanUseAuthenticatedEndpoints(false) + if !sharedtestvalues.AreAPICredentialsSet(e) { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } - err := d.WsConnect() + err := e.WsConnect() if err != nil { log.Fatal(err) } @@ -3343,19 +3344,19 @@ func setupWs() { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - d := new(Deribit) //nolint:govet // Intentional lexical scope shadow - require.NoError(t, testexch.Setup(d), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - d.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := d.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err) exp := subscription.List{} - for _, s := range d.Features.Subscriptions { - for _, a := range d.GetAssetTypes(true) { - if !d.IsAssetWebsocketSupported(a) { + for _, s := range e.Features.Subscriptions { + for _, a := range e.GetAssetTypes(true) { + if !e.IsAssetWebsocketSupported(a) { continue } - pairs, err := d.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) s := s.Clone() //nolint:govet // Intentional lexical scope shadow s.Asset = a @@ -3420,24 +3421,24 @@ func TestChannelName(t *testing.T) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.UpdateAccountInfo(t.Context(), asset.Futures) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.UpdateAccountInfo(t.Context(), asset.Futures) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetAccountFundingHistory(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountFundingHistory(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Empty) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Empty) require.NoError(t, err) assert.NotNil(t, result) } @@ -3447,7 +3448,7 @@ func TestGetRecentTrades(t *testing.T) { var result []trade.Data var err error for assetType, cp := range assetTypeToPairsMap { - result, err = d.GetRecentTrades(t.Context(), cp, assetType) + result, err = e.GetRecentTrades(t.Context(), cp, assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -3455,7 +3456,7 @@ func TestGetRecentTrades(t *testing.T) { func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", AccountID: "1", @@ -3467,7 +3468,7 @@ func TestCancelAllOrders(t *testing.T) { for assetType, cp := range assetTypeToPairsMap { orderCancellation.AssetType = assetType orderCancellation.Pair = cp - result, err = d.CancelAllOrders(t.Context(), orderCancellation) + result, err = e.CancelAllOrders(t.Context(), orderCancellation) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -3475,9 +3476,9 @@ func TestCancelAllOrders(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) for assetType, cp := range assetTypeToPairsMap { - result, err := d.GetOrderInfo(t.Context(), "1234", cp, assetType) + result, err := e.GetOrderInfo(t.Context(), "1234", cp, assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -3485,17 +3486,17 @@ func TestGetOrderInfo(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.GetDepositAddress(t.Context(), currency.BTC, "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") require.ErrorIs(t, err, common.ErrNoResponse) assert.NotNil(t, result) } func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: d.Name, + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Amount: 1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -3510,7 +3511,7 @@ func TestWithdraw(t *testing.T) { func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, AssetType: asset.Futures, Side: order.AnySide, Pairs: currency.Pairs{futuresTradablePair}, @@ -3519,7 +3520,7 @@ func TestGetActiveOrders(t *testing.T) { for assetType, cp := range assetTypeToPairsMap { getOrdersRequest.Pairs = []currency.Pair{cp} getOrdersRequest.AssetType = assetType - result, err := d.GetActiveOrders(t.Context(), &getOrdersRequest) + result, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) require.NoErrorf(t, err, "expected nil, got %v for asset type %s pair %s", err, assetType, cp) require.NotNilf(t, result, "expected result not to be nil for asset type %s pair %s", assetType, cp) } @@ -3527,9 +3528,9 @@ func TestGetActiveOrders(t *testing.T) { func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) for assetType, cp := range assetTypeToPairsMap { - result, err := d.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + result, err := e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Type: order.AnyType, AssetType: assetType, Side: order.AnySide, Pairs: []currency.Pair{cp}, }) @@ -3541,11 +3542,11 @@ func TestGetOrderHistory(t *testing.T) { func TestGetAssetFromPair(t *testing.T) { var assetTypeNew asset.Item for _, assetType := range []asset.Item{asset.Spot, asset.Futures, asset.Options, asset.OptionCombo, asset.FutureCombo} { - availablePairs, err := d.GetEnabledPairs(assetType) + availablePairs, err := e.GetEnabledPairs(assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s", err, assetType) require.NotNilf(t, availablePairs, "expected result not to be nil for asset type %s", assetType) - format, err := d.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) require.NoError(t, err) for id, cp := range availablePairs { @@ -3565,13 +3566,13 @@ func TestGetAssetFromPair(t *testing.T) { func TestGetAssetPairByInstrument(t *testing.T) { t.Parallel() for _, assetType := range []asset.Item{asset.Spot, asset.Futures, asset.Options, asset.OptionCombo, asset.FutureCombo} { - availablePairs, err := d.GetAvailablePairs(assetType) + availablePairs, err := e.GetAvailablePairs(assetType) require.NoErrorf(t, err, "expected nil, got %v for asset type %s", err, assetType) require.NotNilf(t, availablePairs, "expected result not to be nil for asset type %s", assetType) for _, cp := range availablePairs { t.Run(fmt.Sprintf("%s %s", assetType, cp), func(t *testing.T) { t.Parallel() - extractedPair, extractedAsset, err := d.getAssetPairByInstrument(cp.String()) + extractedPair, extractedAsset, err := e.getAssetPairByInstrument(cp.String()) assert.NoError(t, err) assert.Equal(t, cp.String(), extractedPair.String()) assert.Equal(t, assetType.String(), extractedAsset.String()) @@ -3580,12 +3581,12 @@ func TestGetAssetPairByInstrument(t *testing.T) { } t.Run("empty asset, empty pair", func(t *testing.T) { t.Parallel() - _, _, err := d.getAssetPairByInstrument("") + _, _, err := e.getAssetPairByInstrument("") assert.ErrorIs(t, err, errInvalidInstrumentName) }) t.Run("thisIsAFakeCurrency", func(t *testing.T) { t.Parallel() - _, _, err := d.getAssetPairByInstrument("thisIsAFakeCurrency") + _, _, err := e.getAssetPairByInstrument("thisIsAFakeCurrency") assert.ErrorIs(t, err, errUnsupportedInstrumentFormat) }) } @@ -3600,10 +3601,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { FiatCurrency: currency.USD, BankTransactionType: exchange.WireTransfer, } - result, err := d.GetFeeByType(t.Context(), feeBuilder) + result, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err) require.NotNil(t, result) - if !sharedtestvalues.AreAPICredentialsSet(d) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equalf(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } else { assert.Equalf(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType, "expected %v, received %v", exchange.CryptocurrencyTradeFee, feeBuilder.FeeType) @@ -3670,14 +3671,14 @@ func TestCalculateTradingFee(t *testing.T) { func TestGetTime(t *testing.T) { t.Parallel() - result, err := d.GetTime(t.Context()) + result, err := e.GetTime(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - result, err := d.GetServerTime(t.Context(), asset.Empty) + result, err := e.GetServerTime(t.Context(), asset.Empty) require.NoError(t, err) assert.NotNil(t, result) } @@ -3692,22 +3693,22 @@ func TestModifyOrder(t *testing.T) { {AssetType: asset.Futures, Pair: futuresTradablePair, Amount: 2}: order.ErrOrderIDNotSet, } for param, errIncoming := range modifyParamToErrorMap { - _, err := d.ModifyOrder(t.Context(), param) + _, err := e.ModifyOrder(t.Context(), param) require.ErrorIs(t, err, errIncoming) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Futures, OrderID: "1234", Pair: futuresTradablePair, Amount: 2}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Futures, OrderID: "1234", Pair: futuresTradablePair, Amount: 2}) require.NoError(t, err) require.NotNil(t, result) - result, err = d.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Options, OrderID: "1234", Pair: optionsTradablePair, Amount: 2}) + result, err = e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Options, OrderID: "1234", Pair: optionsTradablePair, Amount: 2}) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", AccountID: "1", @@ -3715,7 +3716,7 @@ func TestCancelOrder(t *testing.T) { for assetType, cp := range assetTypeToPairsMap { orderCancellation.AssetType = assetType orderCancellation.Pair = cp - err := d.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) require.NoError(t, err) } } @@ -3755,7 +3756,7 @@ func TestProcessPushData(t *testing.T) { for k, v := range websocketPushData { t.Run(k, func(t *testing.T) { t.Parallel() - err := d.wsHandleData(t.Context(), []byte(v)) + err := e.wsHandleData(t.Context(), []byte(v)) require.NoErrorf(t, err, "%s: Received unexpected error for", k) }) } @@ -3773,7 +3774,7 @@ func TestFormatFuturesTradablePair(t *testing.T) { for pair, instrumentID := range futuresInstrumentsOutputList { t.Run(instrumentID, func(t *testing.T) { t.Parallel() - instrument := d.formatFuturesTradablePair(pair) + instrument := e.formatFuturesTradablePair(pair) require.Equal(t, instrumentID, instrument) }) } @@ -3789,29 +3790,29 @@ func TestOptionPairToString(t *testing.T) { {Delimiter: currency.DashDelimiter, Base: currency.MATIC, Quote: currency.NewCode("USDC-8JUN24-0D99-P")}: "MATIC_USDC-8JUN24-0d99-P", {Delimiter: currency.DashDelimiter, Base: currency.MATIC, Quote: currency.NewCode("USDC-6DEC29-0D87-C")}: "MATIC_USDC-6DEC29-0d87-C", } { - assert.Equal(t, exp, d.optionPairToString(pair), "optionPairToString should return correctly") + assert.Equal(t, exp, e.optionPairToString(pair), "optionPairToString should return correctly") } } func TestWSRetrieveCombos(t *testing.T) { t.Parallel() - _, err := d.WSRetrieveCombos(t.Context(), currency.EMPTYCODE) + _, err := e.WSRetrieveCombos(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := d.WSRetrieveCombos(t.Context(), futureComboTradablePair.Base) + result, err := e.WSRetrieveCombos(t.Context(), futureComboTradablePair.Base) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := d.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), IncludePredictedRate: true, }) require.ErrorIs(t, err, asset.ErrNotSupported) - result, err := d.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + result, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: futuresTradablePair, }) @@ -3821,12 +3822,12 @@ func TestGetLatestFundingRates(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := d.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) require.NoErrorf(t, err, "Error fetching %s pairs for test: %v", asset.Spot, err) - instrumentInfo, err := d.GetInstruments(t.Context(), currency.BTC, d.GetAssetKind(asset.Spot), false) + instrumentInfo, err := e.GetInstruments(t.Context(), currency.BTC, e.GetAssetKind(asset.Spot), false) require.NoError(t, err) require.NotEmpty(t, instrumentInfo, "instrument information must not be empty") - limits, err := d.GetOrderExecutionLimits(asset.Spot, spotTradablePair) + limits, err := e.GetOrderExecutionLimits(asset.Spot, spotTradablePair) require.NoErrorf(t, err, "Asset: %s Pair: %s Err: %v", asset.Spot, spotTradablePair, err) var instrumentDetail *InstrumentData for a := range instrumentInfo { @@ -3842,114 +3843,114 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestGetLockedStatus(t *testing.T) { t.Parallel() - result, err := d.GetLockedStatus(t.Context()) + result, err := e.GetLockedStatus(t.Context()) require.NoError(t, err) assert.NotNil(t, result) } func TestSayHello(t *testing.T) { t.Parallel() - result, err := d.SayHello(t.Context(), "Thrasher", "") + result, err := e.SayHello(t.Context(), "Thrasher", "") require.NoError(t, err) assert.NotNil(t, result) } func TestWsRetrieveCancelOnDisconnect(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WsRetrieveCancelOnDisconnect(t.Context(), "connection") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WsRetrieveCancelOnDisconnect(t.Context(), "connection") require.NoError(t, err) assert.NotNil(t, result) } func TestWsDisableCancelOnDisconnect(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WsDisableCancelOnDisconnect(t.Context(), "connection") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WsDisableCancelOnDisconnect(t.Context(), "connection") require.NoError(t, err) assert.NotNil(t, result) } func TestEnableCancelOnDisconnect(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.EnableCancelOnDisconnect(t.Context(), "account") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.EnableCancelOnDisconnect(t.Context(), "account") require.NoError(t, err) assert.NotNil(t, result) } func TestWsEnableCancelOnDisconnect(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - result, err := d.WsEnableCancelOnDisconnect(t.Context(), "connection") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WsEnableCancelOnDisconnect(t.Context(), "connection") require.NoError(t, err) assert.NotNil(t, result) } func TestLogout(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateRealOrders) - err := d.WsLogout(t.Context(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.WsLogout(t.Context(), true) assert.NoError(t, err) } func TestExchangeToken(t *testing.T) { t.Parallel() - _, err := d.ExchangeToken(t.Context(), "", 1234) + _, err := e.ExchangeToken(t.Context(), "", 1234) require.ErrorIs(t, err, errRefreshTokenRequired) - _, err = d.ExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 0) + _, err = e.ExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 0) require.ErrorIs(t, err, errSubjectIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.ExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 1234) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 1234) require.NoError(t, err) assert.NotNil(t, result) } func TestWsExchangeToken(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) - result, err := d.WsExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 1234) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.WsExchangeToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", 1234) require.NoError(t, err) assert.NotNil(t, result) } func TestForkToken(t *testing.T) { t.Parallel() - _, err := d.ForkToken(t.Context(), "", "Sami") + _, err := e.ForkToken(t.Context(), "", "Sami") require.ErrorIs(t, err, errRefreshTokenRequired) - _, err = d.ForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "") + _, err = e.ForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "") require.ErrorIs(t, err, errSessionNameRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.ForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "Sami") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.ForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "Sami") require.NoError(t, err) assert.NotNil(t, result) } func TestWsForkToken(t *testing.T) { t.Parallel() - _, err := d.WsForkToken(t.Context(), "", "Sami") + _, err := e.WsForkToken(t.Context(), "", "Sami") require.ErrorIs(t, err, errRefreshTokenRequired) - _, err = d.WsForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "") + _, err = e.WsForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "") require.ErrorIs(t, err, errSessionNameRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, d, canManipulateAPIEndpoints) - result, err := d.WsForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "Sami") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateAPIEndpoints) + result, err := e.WsForkToken(t.Context(), "1568800656974.1CWcuzUS.MGy49NK4hpTwvR1OYWfpqMEkH4T4oDg4tNIcrM7KdeyxXRcSFqiGzA_D4Cn7mqWocHmlS89FFmUYcmaN2H7lNKKTnhRg5EtrzsFCCiuyN0Wv9y-LbGLV3-Ojv_kbD50FoScQ8BDXS5b_w6Ir1MqEdQ3qFZ3MLcvlPiIgG2BqyJX3ybYnVpIlrVrrdYD1-lkjLcjxOBNJvvUKNUAzkQ", "Sami") require.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := d.GetFuturesContractDetails(t.Context(), asset.Binary) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Binary) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) - result, err := d.GetFuturesContractDetails(t.Context(), asset.Futures) + result, err := e.GetFuturesContractDetails(t.Context(), asset.Futures) require.NoError(t, err) assert.NotNil(t, result) - _, err = d.GetFuturesContractDetails(t.Context(), asset.FutureCombo) + _, err = e.GetFuturesContractDetails(t.Context(), asset.FutureCombo) require.ErrorIs(t, err, asset.ErrNotSupported) } @@ -3962,51 +3963,51 @@ func TestGetFuturesPositionSummary(t *testing.T) { } for param, errIncoming := range paramToErrorMap { - _, err := d.GetFuturesPositionSummary(t.Context(), param) + _, err := e.GetFuturesPositionSummary(t.Context(), param) require.ErrorIs(t, err, errIncoming) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, d) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) req := &futures.PositionSummaryRequest{ Asset: asset.Futures, Pair: currency.NewPair(currency.BTC, currency.NewCode(perpString)), } - result, err := d.GetFuturesPositionSummary(t.Context(), req) + result, err := e.GetFuturesPositionSummary(t.Context(), req) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenInterest(t *testing.T) { t.Parallel() - _, err := d.GetOpenInterest(t.Context(), key.PairAsset{ + _, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.SOL.Item, Quote: currency.USDC.Item, Asset: asset.Spot, }) require.ErrorIs(t, err, asset.ErrNotSupported) - _, err = d.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: optionsTradablePair.Base.Item, Quote: optionsTradablePair.Quote.Item, Asset: asset.Options, }) require.NoError(t, err) - _, err = d.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.NewCode(perpString).Item, Asset: asset.Futures, }) require.NoError(t, err) - _, err = d.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.NewCode("XRP").Item, Quote: currency.NewCode("USDC-PERPETUAL").Item, Asset: asset.Futures, }) require.NoError(t, err) - _, err = d.GetOpenInterest(t.Context(), key.PairAsset{ + _, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: futureComboTradablePair.Base.Item, Quote: futureComboTradablePair.Quote.Item, Asset: asset.FutureCombo, @@ -4039,7 +4040,7 @@ func TestIsPerpetualFutureCurrency(t *testing.T) { for i := range instances { t.Run(fmt.Sprintf("Asset: %s Pair: %s", assetType.String(), instances[i].Pair.String()), func(t *testing.T) { t.Parallel() - is, err := d.IsPerpetualFutureCurrency(assetType, instances[i].Pair) + is, err := e.IsPerpetualFutureCurrency(assetType, instances[i].Pair) require.ErrorIsf(t, err, instances[i].Error, "expected %v, got %v for asset: %s pair: %s", instances[i].Error, err, assetType.String(), instances[i].Pair.String()) require.Equalf(t, is, instances[i].Response, "expected %v, got %v for asset: %s pair: %s", instances[i].Response, is, assetType.String(), instances[i].Pair.String()) }) @@ -4058,11 +4059,11 @@ func TestGetHistoricalFundingRates(t *testing.T) { StartDate: time.Now().Add(-time.Hour * 24 * 2), EndDate: time.Now(), } - _, err = d.GetHistoricalFundingRates(t.Context(), r) + _, err = e.GetHistoricalFundingRates(t.Context(), r) require.ErrorIs(t, err, asset.ErrNotSupported) r.Asset = asset.Futures - result, err := d.GetHistoricalFundingRates(t.Context(), r) + result, err := e.GetHistoricalFundingRates(t.Context(), r) require.NoError(t, err) assert.NotNil(t, result) } @@ -4108,7 +4109,7 @@ func TestGetResolutionFromInterval(t *testing.T) { {Interval: kline.FourHour, Error: kline.ErrUnsupportedInterval}, } for x := range intervalStringMap { - result, err := d.GetResolutionFromInterval(intervalStringMap[x].Interval) + result, err := e.GetResolutionFromInterval(intervalStringMap[x].Interval) require.ErrorIs(t, err, intervalStringMap[x].Error) require.Equal(t, intervalStringMap[x].IntervalString, result) } @@ -4136,27 +4137,27 @@ func TestGetValidatedCurrencyCode(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - _, err := d.GetCurrencyTradeURL(t.Context(), asset.Spot, currency.EMPTYPAIR) + _, err := e.GetCurrencyTradeURL(t.Context(), asset.Spot, currency.EMPTYPAIR) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - for _, a := range d.GetAssetTypes(false) { + for _, a := range e.GetAssetTypes(false) { var pairs currency.Pairs - pairs, err = d.CurrencyPairs.GetPairs(a, false) + pairs, err = e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) var resp string - resp, err = d.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err = e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } // specific test to ensure perps work cp := currency.NewPair(currency.BTC, currency.NewCode("USDC-PERPETUAL")) - resp, err := d.GetCurrencyTradeURL(t.Context(), asset.Futures, cp) + resp, err := e.GetCurrencyTradeURL(t.Context(), asset.Futures, cp) require.NoError(t, err) assert.NotEmpty(t, resp) // specific test to ensure options with dates work cp = currency.NewPair(currency.BTC, currency.NewCode("14JUN24-62000-C")) - resp, err = d.GetCurrencyTradeURL(t.Context(), asset.Options, cp) + resp, err = e.GetCurrencyTradeURL(t.Context(), asset.Options, cp) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/deribit/deribit_websocket.go b/exchanges/deribit/deribit_websocket.go index ff43e1ad625..ba3224dfdc3 100644 --- a/exchanges/deribit/deribit_websocket.go +++ b/exchanges/deribit/deribit_websocket.go @@ -123,38 +123,38 @@ var ( ) // WsConnect starts a new connection with the websocket API -func (d *Deribit) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !d.Websocket.IsEnabled() || !d.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := d.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - d.Websocket.Wg.Add(1) - go d.wsReadData(ctx) - if d.Websocket.CanUseAuthenticatedEndpoints() { - err = d.wsLogin(ctx) + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.wsLogin(ctx) if err != nil { - log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", d.Name, err) - d.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", e.Name, err) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } - return d.Websocket.Conn.SendJSONMessage(ctx, request.Unset, setHeartBeatMessage) + return e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, setHeartBeatMessage) } -func (d *Deribit) wsLogin(ctx context.Context) error { - if !d.IsWebsocketAuthenticationSupported() { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", d.Name) +func (e *Exchange) wsLogin(ctx context.Context) error { + if !e.IsWebsocketAuthenticationSupported() { + return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", e.Name) } - creds, err := d.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - d.Websocket.SetCanUseAuthenticatedEndpoints(true) - n := d.Requester.GetNonce(nonce.UnixNano).String() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + n := e.Requester.GetNonce(nonce.UnixNano).String() strTS := strconv.FormatInt(time.Now().UnixMilli(), 10) str2Sign := strTS + "\n" + n + "\n" hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte(str2Sign), []byte(creds.Secret)) @@ -165,7 +165,7 @@ func (d *Deribit) wsLogin(ctx context.Context) error { req := wsInput{ JSONRPCVersion: rpcVersion, Method: "public/auth", - ID: d.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), Params: map[string]any{ "grant_type": "client_signature", "client_id": creds.Key, @@ -174,50 +174,50 @@ func (d *Deribit) wsLogin(ctx context.Context) error { "signature": hex.EncodeToString(hmac), }, } - resp, err := d.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - d.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) return err } var response wsLoginResponse err = json.Unmarshal(resp, &response) if err != nil { - return fmt.Errorf("%v %v", d.Name, err) + return fmt.Errorf("%v %v", e.Name, err) } if response.Error != nil && (response.Error.Code > 0 || response.Error.Message != "") { - return fmt.Errorf("%v Error:%v Message:%v", d.Name, response.Error.Code, response.Error.Message) + return fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return nil } // wsReadData receives and passes on websocket messages for processing -func (d *Deribit) wsReadData(ctx context.Context) { - defer d.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := d.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := d.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - d.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (d *Deribit) wsHandleData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, respRaw []byte) error { var response WsResponse err := json.Unmarshal(respRaw, &response) if err != nil { - return fmt.Errorf("%s - err %s could not parse websocket data: %s", d.Name, err, respRaw) + return fmt.Errorf("%s - err %s could not parse websocket data: %s", e.Name, err, respRaw) } if response.Method == "heartbeat" { - return d.Websocket.Conn.SendJSONMessage(ctx, request.Unset, pingMessage) + return e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, pingMessage) } if response.ID > 2 { - if !d.Websocket.Match.IncomingWithData(response.ID, respRaw) { + if !e.Websocket.Match.IncomingWithData(response.ID, respRaw) { return fmt.Errorf("can't send ws incoming data to Matched channel with RequestID: %d", response.ID) } return nil @@ -233,74 +233,74 @@ func (d *Deribit) wsHandleData(ctx context.Context, respRaw []byte) error { if err != nil { return err } - d.Websocket.DataHandler <- announcement + e.Websocket.DataHandler <- announcement case "book": - return d.processOrderbook(respRaw, channels) + return e.processOrderbook(respRaw, channels) case "chart": - return d.processCandleChart(respRaw, channels) + return e.processCandleChart(respRaw, channels) case "deribit_price_index": indexPrice := &wsIndexPrice{} - return d.processData(respRaw, indexPrice) + return e.processData(respRaw, indexPrice) case "deribit_price_ranking": priceRankings := &wsRankingPrices{} - return d.processData(respRaw, priceRankings) + return e.processData(respRaw, priceRankings) case "deribit_price_statistics": priceStatistics := &wsPriceStatistics{} - return d.processData(respRaw, priceStatistics) + return e.processData(respRaw, priceStatistics) case "deribit_volatility_index": volatilityIndex := &wsVolatilityIndex{} - return d.processData(respRaw, volatilityIndex) + return e.processData(respRaw, volatilityIndex) case "estimated_expiration_price": estimatedExpirationPrice := &wsEstimatedExpirationPrice{} - return d.processData(respRaw, estimatedExpirationPrice) + return e.processData(respRaw, estimatedExpirationPrice) case "incremental_ticker": - return d.processIncrementalTicker(respRaw, channels) + return e.processIncrementalTicker(respRaw, channels) case "instrument": instrumentState := &wsInstrumentState{} - return d.processData(respRaw, instrumentState) + return e.processData(respRaw, instrumentState) case "markprice": markPriceOptions := []wsMarkPriceOptions{} - return d.processData(respRaw, markPriceOptions) + return e.processData(respRaw, markPriceOptions) case "perpetual": perpetualInterest := &wsPerpetualInterest{} - return d.processData(respRaw, perpetualInterest) + return e.processData(respRaw, perpetualInterest) case platformStateChannel: platformState := &wsPlatformState{} - return d.processData(respRaw, platformState) + return e.processData(respRaw, platformState) case "quote": // Quote ticker information. - return d.processQuoteTicker(respRaw, channels) + return e.processQuoteTicker(respRaw, channels) case "rfq": rfq := &wsRequestForQuote{} - return d.processData(respRaw, rfq) + return e.processData(respRaw, rfq) case "ticker": - return d.processInstrumentTicker(respRaw, channels) + return e.processInstrumentTicker(respRaw, channels) case "trades": - return d.processTrades(respRaw, channels) + return e.processTrades(respRaw, channels) case "user": switch channels[1] { case "access_log": accessLog := &wsAccessLog{} - return d.processData(respRaw, accessLog) + return e.processData(respRaw, accessLog) case "changes": - return d.processUserOrderChanges(respRaw, channels) + return e.processUserOrderChanges(respRaw, channels) case "lock": userLock := &WsUserLock{} - return d.processData(respRaw, userLock) + return e.processData(respRaw, userLock) case "mmp_trigger": data := &WsMMPTrigger{ Currency: channels[2], } - return d.processData(respRaw, data) + return e.processData(respRaw, data) case "orders": - return d.processUserOrders(respRaw, channels) + return e.processUserOrders(respRaw, channels) case "portfolio": portfolio := &wsUserPortfolio{} - return d.processData(respRaw, portfolio) + return e.processData(respRaw, portfolio) case "trades": - return d.processTrades(respRaw, channels) + return e.processTrades(respRaw, channels) default: - d.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: d.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return nil } @@ -312,8 +312,8 @@ func (d *Deribit) wsHandleData(ctx context.Context, respRaw []byte) error { return nil } default: - d.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: d.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return nil } @@ -321,7 +321,7 @@ func (d *Deribit) wsHandleData(ctx context.Context, respRaw []byte) error { return nil } -func (d *Deribit) processUserOrders(respRaw []byte, channels []string) error { +func (e *Exchange) processUserOrders(respRaw []byte, channels []string) error { if len(channels) != 4 && len(channels) != 5 { return fmt.Errorf("%w, expected format 'user.orders.{instrument_name}.raw, user.orders.{instrument_name}.{interval}, user.orders.{kind}.{currency}.raw, or user.orders.{kind}.{currency}.{interval}', but found %s", errMalformedData, strings.Join(channels, ".")) } @@ -334,7 +334,7 @@ func (d *Deribit) processUserOrders(respRaw []byte, channels []string) error { } orderDetails := make([]order.Detail, len(orderData)) for x := range orderData { - cp, a, err := d.getAssetPairByInstrument(orderData[x].InstrumentName) + cp, a, err := e.getAssetPairByInstrument(orderData[x].InstrumentName) if err != nil { return err } @@ -355,7 +355,7 @@ func (d *Deribit) processUserOrders(respRaw []byte, channels []string) error { Amount: orderData[x].Amount, ExecutedAmount: orderData[x].FilledAmount, RemainingAmount: orderData[x].Amount - orderData[x].FilledAmount, - Exchange: d.Name, + Exchange: e.Name, OrderID: orderData[x].OrderID, Type: oType, Side: side, @@ -366,11 +366,11 @@ func (d *Deribit) processUserOrders(respRaw []byte, channels []string) error { Pair: cp, } } - d.Websocket.DataHandler <- orderDetails + e.Websocket.DataHandler <- orderDetails return nil } -func (d *Deribit) processUserOrderChanges(respRaw []byte, channels []string) error { +func (e *Exchange) processUserOrderChanges(respRaw []byte, channels []string) error { if len(channels) < 4 || len(channels) > 5 { return fmt.Errorf("%w, expected format 'trades.{instrument_name}.{interval} or trades.{kind}.{currency}.{interval}', but found %s", errMalformedData, strings.Join(channels, ".")) } @@ -390,14 +390,14 @@ func (d *Deribit) processUserOrderChanges(respRaw []byte, channels []string) err } var cp currency.Pair var a asset.Item - cp, a, err = d.getAssetPairByInstrument(changeData.Trades[x].InstrumentName) + cp, a, err = e.getAssetPairByInstrument(changeData.Trades[x].InstrumentName) if err != nil { return err } td[x] = trade.Data{ CurrencyPair: cp, - Exchange: d.Name, + Exchange: e.Name, Timestamp: changeData.Trades[x].Timestamp.Time(), Price: changeData.Trades[x].Price, Amount: changeData.Trades[x].Amount, @@ -424,7 +424,7 @@ func (d *Deribit) processUserOrderChanges(respRaw []byte, channels []string) err if err != nil { return err } - cp, a, err := d.getAssetPairByInstrument(changeData.Orders[x].InstrumentName) + cp, a, err := e.getAssetPairByInstrument(changeData.Orders[x].InstrumentName) if err != nil { return err } @@ -433,7 +433,7 @@ func (d *Deribit) processUserOrderChanges(respRaw []byte, channels []string) err Amount: changeData.Orders[x].Amount, ExecutedAmount: changeData.Orders[x].FilledAmount, RemainingAmount: changeData.Orders[x].Amount - changeData.Orders[x].FilledAmount, - Exchange: d.Name, + Exchange: e.Name, OrderID: changeData.Orders[x].OrderID, Type: oType, Side: side, @@ -444,13 +444,13 @@ func (d *Deribit) processUserOrderChanges(respRaw []byte, channels []string) err Pair: cp, } } - d.Websocket.DataHandler <- orders - d.Websocket.DataHandler <- changeData.Positions + e.Websocket.DataHandler <- orders + e.Websocket.DataHandler <- changeData.Positions return nil } -func (d *Deribit) processQuoteTicker(respRaw []byte, channels []string) error { - cp, a, err := d.getAssetPairByInstrument(channels[1]) +func (e *Exchange) processQuoteTicker(respRaw []byte, channels []string) error { + cp, a, err := e.getAssetPairByInstrument(channels[1]) if err != nil { return err } @@ -461,8 +461,8 @@ func (d *Deribit) processQuoteTicker(respRaw []byte, channels []string) error { if err != nil { return err } - d.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: d.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Pair: cp, AssetType: a, LastUpdated: quoteTicker.Timestamp.Time(), @@ -474,9 +474,9 @@ func (d *Deribit) processQuoteTicker(respRaw []byte, channels []string) error { return nil } -func (d *Deribit) processTrades(respRaw []byte, channels []string) error { - tradeFeed := d.IsTradeFeedEnabled() - saveTradeData := d.IsSaveTradeDataEnabled() +func (e *Exchange) processTrades(respRaw []byte, channels []string) error { + tradeFeed := e.IsTradeFeedEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() if !tradeFeed && !saveTradeData { return nil } @@ -498,13 +498,13 @@ func (d *Deribit) processTrades(respRaw []byte, channels []string) error { for x := range tradesData { var cp currency.Pair var a asset.Item - cp, a, err = d.getAssetPairByInstrument(tradeList[x].InstrumentName) + cp, a, err = e.getAssetPairByInstrument(tradeList[x].InstrumentName) if err != nil { return err } tradesData[x] = trade.Data{ CurrencyPair: cp, - Exchange: d.Name, + Exchange: e.Name, Timestamp: tradeList[x].Timestamp.Time().UTC(), Price: tradeList[x].Price, Amount: tradeList[x].Amount, @@ -515,7 +515,7 @@ func (d *Deribit) processTrades(respRaw []byte, channels []string) error { } if tradeFeed { for i := range tradesData { - d.Websocket.DataHandler <- tradesData[i] + e.Websocket.DataHandler <- tradesData[i] } } if saveTradeData { @@ -524,11 +524,11 @@ func (d *Deribit) processTrades(respRaw []byte, channels []string) error { return nil } -func (d *Deribit) processIncrementalTicker(respRaw []byte, channels []string) error { +func (e *Exchange) processIncrementalTicker(respRaw []byte, channels []string) error { if len(channels) != 2 { return fmt.Errorf("%w, expected format 'incremental_ticker.{instrument_name}', but found %s", errMalformedData, strings.Join(channels, ".")) } - cp, a, err := d.getAssetPairByInstrument(channels[1]) + cp, a, err := e.getAssetPairByInstrument(channels[1]) if err != nil { return err } @@ -539,8 +539,8 @@ func (d *Deribit) processIncrementalTicker(respRaw []byte, channels []string) er if err != nil { return err } - d.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: d.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Pair: cp, AssetType: a, LastUpdated: incrementalTicker.Timestamp.Time(), @@ -556,15 +556,15 @@ func (d *Deribit) processIncrementalTicker(respRaw []byte, channels []string) er return nil } -func (d *Deribit) processInstrumentTicker(respRaw []byte, channels []string) error { +func (e *Exchange) processInstrumentTicker(respRaw []byte, channels []string) error { if len(channels) != 3 { return fmt.Errorf("%w, expected format 'ticker.{instrument_name}.{interval}', but found %s", errMalformedData, strings.Join(channels, ".")) } - return d.processTicker(respRaw, channels) + return e.processTicker(respRaw, channels) } -func (d *Deribit) processTicker(respRaw []byte, channels []string) error { - cp, a, err := d.getAssetPairByInstrument(channels[1]) +func (e *Exchange) processTicker(respRaw []byte, channels []string) error { + cp, a, err := e.getAssetPairByInstrument(channels[1]) if err != nil { return err } @@ -576,7 +576,7 @@ func (d *Deribit) processTicker(respRaw []byte, channels []string) error { return err } tickerPrice := &ticker.Price{ - ExchangeName: d.Name, + ExchangeName: e.Name, Pair: cp, AssetType: a, LastUpdated: tickerPriceResponse.Timestamp.Time(), @@ -596,26 +596,26 @@ func (d *Deribit) processTicker(respRaw []byte, channels []string) error { tickerPrice.Ask = tickerPriceResponse.ImpliedAsk tickerPrice.Bid = tickerPriceResponse.ImpliedBid } - d.Websocket.DataHandler <- tickerPrice + e.Websocket.DataHandler <- tickerPrice return nil } -func (d *Deribit) processData(respRaw []byte, result any) error { +func (e *Exchange) processData(respRaw []byte, result any) error { var response WsResponse response.Params.Data = result err := json.Unmarshal(respRaw, &response) if err != nil { return err } - d.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result return nil } -func (d *Deribit) processCandleChart(respRaw []byte, channels []string) error { +func (e *Exchange) processCandleChart(respRaw []byte, channels []string) error { if len(channels) != 4 { return fmt.Errorf("%w, expected format 'chart.trades.{instrument_name}.{resolution}', but found %s", errMalformedData, strings.Join(channels, ".")) } - cp, a, err := d.getAssetPairByInstrument(channels[2]) + cp, a, err := e.getAssetPairByInstrument(channels[2]) if err != nil { return err } @@ -626,11 +626,11 @@ func (d *Deribit) processCandleChart(respRaw []byte, channels []string) error { if err != nil { return err } - d.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: candleData.Tick.Time(), Pair: cp, AssetType: a, - Exchange: d.Name, + Exchange: e.Name, OpenPrice: candleData.Open, HighPrice: candleData.High, LowPrice: candleData.Low, @@ -640,7 +640,7 @@ func (d *Deribit) processCandleChart(respRaw []byte, channels []string) error { return nil } -func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { +func (e *Exchange) processOrderbook(respRaw []byte, channels []string) error { var response WsResponse orderbookData := &wsOrderbook{} response.Params.Data = orderbookData @@ -649,7 +649,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { return err } if len(channels) == 3 { - cp, a, err := d.getAssetPairByInstrument(orderbookData.InstrumentName) + cp, a, err := e.getAssetPairByInstrument(orderbookData.InstrumentName) if err != nil { return err } @@ -697,9 +697,9 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { switch orderbookData.Type { case "snapshot": - return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: d.Name, - ValidateOrderbook: d.ValidateOrderbook, + return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, LastUpdated: orderbookData.Timestamp.Time(), Pair: cp, Asks: asks, @@ -708,7 +708,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { LastUpdateID: orderbookData.ChangeID, }) case "change": - return d.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Asks: asks, Bids: bids, Pair: cp, @@ -718,7 +718,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { }) } } else if len(channels) == 5 { - cp, a, err := d.getAssetPairByInstrument(orderbookData.InstrumentName) + cp, a, err := e.getAssetPairByInstrument(orderbookData.InstrumentName) if err != nil { return err } @@ -765,12 +765,12 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if len(asks) == 0 && len(bids) == 0 { return nil } - return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: asks, Bids: bids, Pair: cp, Asset: a, - Exchange: d.Name, + Exchange: e.Name, LastUpdateID: orderbookData.ChangeID, LastUpdated: orderbookData.Timestamp.Time(), }) @@ -779,12 +779,12 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { } // generateSubscriptions returns a list of configured subscriptions -func (d *Deribit) generateSubscriptions() (subscription.List, error) { - return d.Features.Subscriptions.ExpandTemplates(d) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (d *Deribit) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "interval": channelInterval, @@ -795,34 +795,34 @@ func (d *Deribit) GetSubscriptionTemplate(_ *subscription.Subscription) (*templa } // Subscribe sends a websocket message to receive data from the channel -func (d *Deribit) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - errs := d.handleSubscription(ctx, "public/subscribe", subs.Public()) - return common.AppendError(errs, d.handleSubscription(ctx, "private/subscribe", subs.Private())) + errs := e.handleSubscription(ctx, "public/subscribe", subs.Public()) + return common.AppendError(errs, e.handleSubscription(ctx, "private/subscribe", subs.Private())) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (d *Deribit) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - errs := d.handleSubscription(ctx, "public/unsubscribe", subs.Public()) - return common.AppendError(errs, d.handleSubscription(ctx, "private/unsubscribe", subs.Private())) + errs := e.handleSubscription(ctx, "public/unsubscribe", subs.Public()) + return common.AppendError(errs, e.handleSubscription(ctx, "private/unsubscribe", subs.Private())) } -func (d *Deribit) handleSubscription(ctx context.Context, method string, subs subscription.List) error { +func (e *Exchange) handleSubscription(ctx context.Context, method string, subs subscription.List) error { var err error - subs, err = subs.ExpandTemplates(d) + subs, err = subs.ExpandTemplates(e) if err != nil || len(subs) == 0 { return err } r := WsSubscriptionInput{ JSONRPCVersion: rpcVersion, - ID: d.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), Method: method, Params: map[string][]string{"channels": subs.QualifiedChannels()}, } - data, err := d.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, r.ID, r) + data, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, r.ID, r) if err != nil { return err } @@ -830,7 +830,7 @@ func (d *Deribit) handleSubscription(ctx context.Context, method string, subs su var response wsSubscriptionResponse err = json.Unmarshal(data, &response) if err != nil { - return fmt.Errorf("%v %v", d.Name, err) + return fmt.Errorf("%v %v", e.Name, err) } subAck := map[string]bool{} for _, c := range response.Result { @@ -843,9 +843,9 @@ func (d *Deribit) handleSubscription(ctx context.Context, method string, subs su if _, ok := subAck[s.QualifiedChannel]; ok { delete(subAck, s.QualifiedChannel) if !strings.Contains(method, "unsubscribe") { - err = common.AppendError(err, d.Websocket.AddSuccessfulSubscriptions(d.Websocket.Conn, s)) + err = common.AppendError(err, e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s)) } else { - err = common.AppendError(err, d.Websocket.RemoveSubscriptions(d.Websocket.Conn, s)) + err = common.AppendError(err, e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s)) } } else { err = common.AppendError(err, errors.New(s.String()+" failed to "+method)) diff --git a/exchanges/deribit/deribit_wrapper.go b/exchanges/deribit/deribit_wrapper.go index 874aebae82d..2355f5bb9fc 100644 --- a/exchanges/deribit/deribit_wrapper.go +++ b/exchanges/deribit/deribit_wrapper.go @@ -34,26 +34,26 @@ import ( ) // SetDefaults sets the basic defaults for Deribit -func (d *Deribit) SetDefaults() { - d.Name = "Deribit" - d.Enabled = true - d.Verbose = true - d.API.CredentialsValidator.RequiresKey = true - d.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Deribit" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true dashFormat := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter} underscoreFormat := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.UnderscoreDelimiter} - if err := d.SetAssetPairStore(asset.Spot, currency.PairStore{AssetEnabled: true, RequestFormat: underscoreFormat, ConfigFormat: underscoreFormat}); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", d.Name, asset.Spot, err) + if err := e.SetAssetPairStore(asset.Spot, currency.PairStore{AssetEnabled: true, RequestFormat: underscoreFormat, ConfigFormat: underscoreFormat}); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, asset.Spot, err) } for _, a := range []asset.Item{asset.Futures, asset.Options, asset.OptionCombo, asset.FutureCombo} { - if err := d.SetAssetPairStore(a, currency.PairStore{AssetEnabled: true, RequestFormat: dashFormat, ConfigFormat: dashFormat}); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", d.Name, a, err) + if err := e.SetAssetPairStore(a, currency.PairStore{AssetEnabled: true, RequestFormat: dashFormat, ConfigFormat: dashFormat}); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } // Fill out the capabilities/features that the exchange supports - d.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -129,7 +129,7 @@ func (d *Deribit) SetDefaults() { } var err error - d.Requester, err = request.New(d.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimits()), ) @@ -137,12 +137,12 @@ func (d *Deribit) SetDefaults() { log.Errorln(log.ExchangeSys, err) } for _, assetType := range []asset.Item{asset.Options, asset.OptionCombo, asset.FutureCombo} { - if err = d.DisableAssetWebsocketSupport(assetType); err != nil { + if err = e.DisableAssetWebsocketSupport(assetType); err != nil { log.Errorln(log.ExchangeSys, err) } } - d.API.Endpoints = d.NewEndpoints() - err = d.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestFutures: "https://www.deribit.com", exchange.RestSpot: "https://www.deribit.com", exchange.RestSpotSupplementary: "https://test.deribit.com", @@ -150,35 +150,35 @@ func (d *Deribit) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - d.Websocket = websocket.NewManager() - d.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - d.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - d.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (d *Deribit) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - d.SetEnabled(false) + e.SetEnabled(false) return nil } - err = d.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - err = d.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: deribitWebsocketAddress, RunningURL: deribitWebsocketAddress, - Connector: d.WsConnect, - Subscriber: d.Subscribe, - Unsubscriber: d.Unsubscribe, - GenerateSubscriptions: d.generateSubscriptions, - Features: &d.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, @@ -188,20 +188,20 @@ func (d *Deribit) Setup(exch *config.Exchange) error { return err } - return d.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ - URL: d.Websocket.GetWebsocketURL(), + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + URL: e.Websocket.GetWebsocketURL(), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (d *Deribit) FetchTradablePairs(ctx context.Context, assetType asset.Item) (currency.Pairs, error) { - if !d.SupportsAsset(assetType) { - return nil, fmt.Errorf("%s: %w - %v", d.Name, asset.ErrNotSupported, assetType) +func (e *Exchange) FetchTradablePairs(ctx context.Context, assetType asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(assetType) { + return nil, fmt.Errorf("%s: %w - %v", e.Name, asset.ErrNotSupported, assetType) } - instruments, err := d.GetInstruments(ctx, currency.EMPTYCODE, d.GetAssetKind(assetType), false) + instruments, err := e.GetInstruments(ctx, currency.EMPTYCODE, e.GetAssetKind(assetType), false) if err != nil { return nil, err } @@ -222,49 +222,49 @@ func (d *Deribit) FetchTradablePairs(ctx context.Context, assetType asset.Item) // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (d *Deribit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := d.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.GetAssetTypes(false) errs := common.CollectErrors(len(assets)) for x := range assets { go func(x int) { defer errs.Wg.Done() - pairs, err := d.FetchTradablePairs(ctx, assets[x]) + pairs, err := e.FetchTradablePairs(ctx, assets[x]) if err != nil { errs.C <- err return } - errs.C <- d.UpdatePairs(pairs, assets[x], false, forceUpdate) + errs.C <- e.UpdatePairs(pairs, assets[x], false, forceUpdate) }(x) } return errs.Collect() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (d *Deribit) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (d *Deribit) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { - if !d.SupportsAsset(assetType) { - return nil, fmt.Errorf("%s: %w - %s", d.Name, asset.ErrNotSupported, assetType) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { + if !e.SupportsAsset(assetType) { + return nil, fmt.Errorf("%s: %w - %s", e.Name, asset.ErrNotSupported, assetType) } - p, err := d.FormatExchangeCurrency(p, assetType) + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - instrumentID := d.formatPairString(assetType, p) + instrumentID := e.formatPairString(assetType, p) var tickerData *TickerData - if d.Websocket.IsConnected() { - tickerData, err = d.WSRetrievePublicTicker(ctx, instrumentID) + if e.Websocket.IsConnected() { + tickerData, err = e.WSRetrievePublicTicker(ctx, instrumentID) } else { - tickerData, err = d.GetPublicTicker(ctx, instrumentID) + tickerData, err = e.GetPublicTicker(ctx, instrumentID) } if err != nil { return nil, err } resp := ticker.Price{ - ExchangeName: d.Name, + ExchangeName: e.Name, Pair: p, AssetType: assetType, Ask: tickerData.BestAskPrice, @@ -284,30 +284,30 @@ func (d *Deribit) UpdateTicker(ctx context.Context, p currency.Pair, assetType a if err != nil { return nil, err } - return ticker.GetTicker(d.Name, p, assetType) + return ticker.GetTicker(e.Name, p, assetType) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (d *Deribit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { - p, err := d.FormatExchangeCurrency(p, assetType) +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - instrumentID := d.formatPairString(assetType, p) + instrumentID := e.formatPairString(assetType, p) var obData *Orderbook - if d.Websocket.IsConnected() { - obData, err = d.WSRetrieveOrderbookData(ctx, instrumentID, 50) + if e.Websocket.IsConnected() { + obData, err = e.WSRetrieveOrderbookData(ctx, instrumentID, 50) } else { - obData, err = d.GetOrderbook(ctx, instrumentID, 50) + obData, err = e.GetOrderbook(ctx, instrumentID, 50) } if err != nil { return nil, err } book := &orderbook.Book{ - Exchange: d.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: d.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } book.Asks = make(orderbook.Levels, 0, len(obData.Asks)) for x := range obData.Asks { @@ -333,24 +333,24 @@ func (d *Deribit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp if err != nil { return book, err } - return orderbook.Get(d.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies -func (d *Deribit) UpdateAccountInfo(ctx context.Context, _ asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, _ asset.Item) (account.Holdings, error) { var resp account.Holdings - resp.Exchange = d.Name - currencies, err := d.GetCurrencies(ctx) + resp.Exchange = e.Name + currencies, err := e.GetCurrencies(ctx) if err != nil { return resp, err } resp.Accounts = make([]account.SubAccount, len(currencies)) for x := range currencies { var data *AccountSummaryData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - data, err = d.WSRetrieveAccountSummary(ctx, currency.NewCode(currencies[x].Currency), false) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + data, err = e.WSRetrieveAccountSummary(ctx, currency.NewCode(currencies[x].Currency), false) } else { - data, err = d.GetAccountSummary(ctx, currency.NewCode(currencies[x].Currency), false) + data, err = e.GetAccountSummary(ctx, currency.NewCode(currencies[x].Currency), false) } if err != nil { return resp, err @@ -367,13 +367,13 @@ func (d *Deribit) UpdateAccountInfo(ctx context.Context, _ asset.Item) (account. } // GetAccountFundingHistory returns funding history, deposits and withdrawals -func (d *Deribit) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { var currencies []CurrencyData var err error - if d.Websocket.IsConnected() { - currencies, err = d.WSRetrieveCurrencies(ctx) + if e.Websocket.IsConnected() { + currencies, err = e.WSRetrieveCurrencies(ctx) } else { - currencies, err = d.GetCurrencies(ctx) + currencies, err = e.GetCurrencies(ctx) } if err != nil { return nil, err @@ -381,17 +381,17 @@ func (d *Deribit) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund var resp []exchange.FundingHistory for x := range currencies { var deposits *DepositsData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - deposits, err = d.WSRetrieveDeposits(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + deposits, err = e.WSRetrieveDeposits(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } else { - deposits, err = d.GetDeposits(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + deposits, err = e.GetDeposits(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } if err != nil { return nil, err } for y := range deposits.Data { resp = append(resp, exchange.FundingHistory{ - ExchangeName: d.Name, + ExchangeName: e.Name, Status: deposits.Data[y].State, TransferID: deposits.Data[y].TransactionID, Timestamp: deposits.Data[y].UpdatedTimestamp.Time(), @@ -402,17 +402,17 @@ func (d *Deribit) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund }) } var withdrawalData *WithdrawalsData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - withdrawalData, err = d.WSRetrieveWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + withdrawalData, err = e.WSRetrieveWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } else { - withdrawalData, err = d.GetWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + withdrawalData, err = e.GetWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } if err != nil { return nil, err } for z := range withdrawalData.Data { resp = append(resp, exchange.FundingHistory{ - ExchangeName: d.Name, + ExchangeName: e.Name, Status: withdrawalData.Data[z].State, TransferID: withdrawalData.Data[z].TransactionID, Timestamp: withdrawalData.Data[z].UpdatedTimestamp.Time(), @@ -427,13 +427,13 @@ func (d *Deribit) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund } // GetWithdrawalsHistory returns previous withdrawals data -func (d *Deribit) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { var currencies []CurrencyData var err error - if d.Websocket.IsConnected() { - currencies, err = d.WSRetrieveCurrencies(ctx) + if e.Websocket.IsConnected() { + currencies, err = e.WSRetrieveCurrencies(ctx) } else { - currencies, err = d.GetCurrencies(ctx) + currencies, err = e.GetCurrencies(ctx) } if err != nil { return nil, err @@ -444,10 +444,10 @@ func (d *Deribit) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ continue } var withdrawalData *WithdrawalsData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - withdrawalData, err = d.WSRetrieveWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + withdrawalData, err = e.WSRetrieveWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } else { - withdrawalData, err = d.GetWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) + withdrawalData, err = e.GetWithdrawals(ctx, currency.NewCode(currencies[x].Currency), 100, 0) } if err != nil { return nil, err @@ -468,21 +468,21 @@ func (d *Deribit) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (d *Deribit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - if !d.SupportsAsset(assetType) { - return nil, fmt.Errorf("%s: %w - %s", d.Name, asset.ErrNotSupported, assetType) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + if !e.SupportsAsset(assetType) { + return nil, fmt.Errorf("%s: %w - %s", e.Name, asset.ErrNotSupported, assetType) } - p, err := d.FormatExchangeCurrency(p, assetType) + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - instrumentID := d.formatPairString(assetType, p) + instrumentID := e.formatPairString(assetType, p) resp := []trade.Data{} var trades *PublicTradesData - if d.Websocket.IsConnected() { - trades, err = d.WSRetrieveLastTradesByInstrument(ctx, instrumentID, "", "", "", 0, false) + if e.Websocket.IsConnected() { + trades, err = e.WSRetrieveLastTradesByInstrument(ctx, instrumentID, "", "", "", 0, false) } else { - trades, err = d.GetLastTradesByInstrument(ctx, instrumentID, "", "", "", 0, false) + trades, err = e.GetLastTradesByInstrument(ctx, instrumentID, "", "", "", 0, false) } if err != nil { return nil, err @@ -494,7 +494,7 @@ func (d *Deribit) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } resp = append(resp, trade.Data{ TID: trades.Trades[a].TradeID, - Exchange: d.Name, + Exchange: e.Name, Price: trades.Trades[a].Price, Amount: trades.Trades[a].Amount, Timestamp: trades.Trades[a].Timestamp.Time(), @@ -507,20 +507,20 @@ func (d *Deribit) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } // GetHistoricTrades returns historic trade data within the timeframe provided -func (d *Deribit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if common.StartEndTimeCheck(timestampStart, timestampEnd) != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v", timestampStart, timestampEnd) } - p, err := d.FormatExchangeCurrency(p, assetType) + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var instrumentID string switch assetType { case asset.Futures, asset.Options, asset.Spot: - instrumentID = d.formatPairString(assetType, p) + instrumentID = e.formatPairString(assetType, p) default: return nil, fmt.Errorf("%w asset type %v", asset.ErrNotSupported, assetType) } @@ -528,10 +528,10 @@ func (d *Deribit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetT var tradesData *PublicTradesData hasMore := true for hasMore { - if d.Websocket.IsConnected() { - tradesData, err = d.WSRetrieveLastTradesByInstrumentAndTime(ctx, instrumentID, "asc", 100, true, timestampStart, timestampEnd) + if e.Websocket.IsConnected() { + tradesData, err = e.WSRetrieveLastTradesByInstrumentAndTime(ctx, instrumentID, "asc", 100, true, timestampStart, timestampEnd) } else { - tradesData, err = d.GetLastTradesByInstrumentAndTime(ctx, instrumentID, "asc", 100, timestampStart, timestampEnd) + tradesData, err = e.GetLastTradesByInstrumentAndTime(ctx, instrumentID, "asc", 100, timestampStart, timestampEnd) } if err != nil { return nil, err @@ -552,7 +552,7 @@ func (d *Deribit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetT } resp = append(resp, trade.Data{ TID: tradesData.Trades[t].TradeID, - Exchange: d.Name, + Exchange: e.Name, Price: tradesData.Trades[t].Price, Amount: tradesData.Trades[t].Amount, Timestamp: tradesData.Trades[t].Timestamp.Time(), @@ -566,18 +566,18 @@ func (d *Deribit) GetHistoricTrades(ctx context.Context, p currency.Pair, assetT } // SubmitOrder submits a new order -func (d *Deribit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - err := s.Validate(d.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } - if !d.SupportsAsset(s.AssetType) { - return nil, fmt.Errorf("%s: orderType %v is not valid", d.Name, s.AssetType) + if !e.SupportsAsset(s.AssetType) { + return nil, fmt.Errorf("%s: orderType %v is not valid", e.Name, s.AssetType) } var orderID string var fmtPair currency.Pair status := order.New - fmtPair, err = d.FormatExchangeCurrency(s.Pair, s.AssetType) + fmtPair, err = e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -599,10 +599,10 @@ func (d *Deribit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm } switch { case s.Side.IsLong(): - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - data, err = d.WSSubmitBuy(ctx, reqParams) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + data, err = e.WSSubmitBuy(ctx, reqParams) } else { - data, err = d.SubmitBuy(ctx, reqParams) + data, err = e.SubmitBuy(ctx, reqParams) } if err != nil { return nil, err @@ -612,10 +612,10 @@ func (d *Deribit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm } orderID = data.Order.OrderID case s.Side.IsShort(): - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - data, err = d.WSSubmitSell(ctx, reqParams) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + data, err = e.WSSubmitSell(ctx, reqParams) } else { - data, err = d.SubmitSell(ctx, reqParams) + data, err = e.SubmitSell(ctx, reqParams) } if err != nil { return nil, err @@ -635,12 +635,12 @@ func (d *Deribit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (d *Deribit) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } - if !d.SupportsAsset(action.AssetType) { - return nil, fmt.Errorf("%s: %w - %v", d.Name, asset.ErrNotSupported, action.AssetType) + if !e.SupportsAsset(action.AssetType) { + return nil, fmt.Errorf("%s: %w - %v", e.Name, asset.ErrNotSupported, action.AssetType) } var modify *PrivateTradeData var err error @@ -651,10 +651,10 @@ func (d *Deribit) ModifyOrder(ctx context.Context, action *order.Modify) (*order OrderID: action.OrderID, Price: action.Price, } - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - modify, err = d.WSSubmitEdit(ctx, reqParam) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + modify, err = e.WSSubmitEdit(ctx, reqParam) } else { - modify, err = d.SubmitEdit(ctx, reqParam) + modify, err = e.SubmitEdit(ctx, reqParam) } if err != nil { return nil, err @@ -668,18 +668,18 @@ func (d *Deribit) ModifyOrder(ctx context.Context, action *order.Modify) (*order } // CancelOrder cancels an order by its corresponding ID number -func (d *Deribit) CancelOrder(ctx context.Context, ord *order.Cancel) error { - if !d.SupportsAsset(ord.AssetType) { - return fmt.Errorf("%s: %w - %s", d.Name, asset.ErrNotSupported, ord.AssetType) +func (e *Exchange) CancelOrder(ctx context.Context, ord *order.Cancel) error { + if !e.SupportsAsset(ord.AssetType) { + return fmt.Errorf("%s: %w - %s", e.Name, asset.ErrNotSupported, ord.AssetType) } err := ord.Validate(ord.StandardCancel()) if err != nil { return err } - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - _, err = d.WSSubmitCancel(ctx, ord.OrderID) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + _, err = e.WSSubmitCancel(ctx, ord.OrderID) } else { - _, err = d.SubmitCancel(ctx, ord.OrderID) + _, err = e.SubmitCancel(ctx, ord.OrderID) } if err != nil { return err @@ -688,17 +688,17 @@ func (d *Deribit) CancelOrder(ctx context.Context, ord *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func (d *Deribit) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (d *Deribit) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } var cancelData *MultipleCancelResponse - pairFmt, err := d.GetPairFormat(orderCancellation.AssetType, true) + pairFmt, err := e.GetPairFormat(orderCancellation.AssetType, true) if err != nil { return order.CancelAllResponse{}, err } @@ -711,12 +711,12 @@ func (d *Deribit) CancelAllOrders(ctx context.Context, orderCancellation *order. case order.AnyType, order.UnknownType: orderTypeStr = "all" default: - return order.CancelAllResponse{}, fmt.Errorf("%s: orderType %v is not valid", d.Name, orderCancellation.Type) + return order.CancelAllResponse{}, fmt.Errorf("%s: orderType %v is not valid", e.Name, orderCancellation.Type) } - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - cancelData, err = d.WSSubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + cancelData, err = e.WSSubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true) } else { - cancelData, err = d.SubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true) + cancelData, err = e.SubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true) } if err != nil { return order.CancelAllResponse{}, err @@ -734,16 +734,16 @@ func (d *Deribit) CancelAllOrders(ctx context.Context, orderCancellation *order. } // GetOrderInfo returns order information based on order ID -func (d *Deribit) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, assetType asset.Item) (*order.Detail, error) { - if !d.SupportsAsset(assetType) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, assetType asset.Item) (*order.Detail, error) { + if !e.SupportsAsset(assetType) { return nil, fmt.Errorf("%w assetType %v", asset.ErrNotSupported, assetType) } var orderInfo *OrderData var err error - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - orderInfo, err = d.WSRetrievesOrderState(ctx, orderID) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + orderInfo, err = e.WSRetrievesOrderState(ctx, orderID) } else { - orderInfo, err = d.GetOrderState(ctx, orderID) + orderInfo, err = e.GetOrderState(ctx, orderID) } if err != nil { return nil, err @@ -767,7 +767,7 @@ func (d *Deribit) GetOrderInfo(ctx context.Context, orderID string, _ currency.P } else { orderStatus, err = order.StringToOrderStatus(orderInfo.OrderState) if err != nil { - return nil, fmt.Errorf("%v: orderStatus %s not supported", d.Name, orderInfo.OrderState) + return nil, fmt.Errorf("%v: orderStatus %s not supported", e.Name, orderInfo.OrderState) } } var tif order.TimeInForce @@ -777,7 +777,7 @@ func (d *Deribit) GetOrderInfo(ctx context.Context, orderID string, _ currency.P } return &order.Detail{ AssetType: assetType, - Exchange: d.Name, + Exchange: e.Name, TimeInForce: tif, Price: orderInfo.Price, Amount: orderInfo.Amount, @@ -794,13 +794,13 @@ func (d *Deribit) GetOrderInfo(ctx context.Context, orderID string, _ currency.P } // GetDepositAddress returns a deposit address for a specified currency -func (d *Deribit) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { var addressData *DepositAddressData var err error - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - addressData, err = d.WSRetrieveCurrentDepositAddress(ctx, cryptocurrency) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + addressData, err = e.WSRetrieveCurrentDepositAddress(ctx, cryptocurrency) } else { - addressData, err = d.GetCurrentDepositAddress(ctx, cryptocurrency) + addressData, err = e.GetCurrentDepositAddress(ctx, cryptocurrency) } if err != nil { return nil, err @@ -813,16 +813,16 @@ func (d *Deribit) GetDepositAddress(ctx context.Context, cryptocurrency currency // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (d *Deribit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { err := withdrawRequest.Validate() if err != nil { return nil, err } var withdrawData *WithdrawData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - withdrawData, err = d.WSSubmitWithdraw(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, "", withdrawRequest.Amount) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + withdrawData, err = e.WSSubmitWithdraw(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, "", withdrawRequest.Amount) } else { - withdrawData, err = d.SubmitWithdraw(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, "", withdrawRequest.Amount) + withdrawData, err = e.SubmitWithdraw(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, "", withdrawRequest.Amount) } if err != nil { return nil, err @@ -834,29 +834,29 @@ func (d *Deribit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted -func (d *Deribit) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted -func (d *Deribit) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (d *Deribit) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } - if !d.SupportsAsset(getOrdersRequest.AssetType) { - return nil, fmt.Errorf("%s: %w - %v", d.Name, asset.ErrNotSupported, getOrdersRequest.AssetType) + if !e.SupportsAsset(getOrdersRequest.AssetType) { + return nil, fmt.Errorf("%s: %w - %v", e.Name, asset.ErrNotSupported, getOrdersRequest.AssetType) } if len(getOrdersRequest.Pairs) == 0 { return nil, currency.ErrCurrencyPairsEmpty } resp := []order.Detail{} for x := range getOrdersRequest.Pairs { - fmtPair, err := d.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) + fmtPair, err := e.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) if err != nil { return nil, err } @@ -868,10 +868,10 @@ func (d *Deribit) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M oTypeString = getOrdersRequest.Type.Lower() } var ordersData []OrderData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - ordersData, err = d.WSRetrieveOpenOrdersByInstrument(ctx, fmtPair.String(), oTypeString) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + ordersData, err = e.WSRetrieveOpenOrdersByInstrument(ctx, fmtPair.String(), oTypeString) } else { - ordersData, err = d.GetOpenOrdersByInstrument(ctx, fmtPair.String(), oTypeString) + ordersData, err = e.GetOpenOrdersByInstrument(ctx, fmtPair.String(), oTypeString) } if err != nil { return nil, err @@ -904,7 +904,7 @@ func (d *Deribit) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M } resp = append(resp, order.Detail{ AssetType: getOrdersRequest.AssetType, - Exchange: d.Name, + Exchange: e.Name, Price: ordersData[y].Price, Amount: ordersData[y].Amount, ExecutedAmount: ordersData[y].FilledAmount, @@ -925,7 +925,7 @@ func (d *Deribit) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (d *Deribit) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -934,15 +934,15 @@ func (d *Deribit) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } var resp []order.Detail for x := range getOrdersRequest.Pairs { - fmtPair, err := d.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) + fmtPair, err := e.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) if err != nil { return nil, err } var ordersData []OrderData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - ordersData, err = d.WSRetrieveOrderHistoryByInstrument(ctx, fmtPair.String(), 100, 0, true, true) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + ordersData, err = e.WSRetrieveOrderHistoryByInstrument(ctx, fmtPair.String(), 100, 0, true, true) } else { - ordersData, err = d.GetOrderHistoryByInstrument(ctx, fmtPair.String(), 100, 0, true, true) + ordersData, err = e.GetOrderHistoryByInstrument(ctx, fmtPair.String(), 100, 0, true, true) } if err != nil { return nil, err @@ -968,7 +968,7 @@ func (d *Deribit) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } else { orderStatus, err = order.StringToOrderStatus(ordersData[y].OrderState) if err != nil { - return resp, fmt.Errorf("%v: orderStatus %s not supported", d.Name, ordersData[y].OrderState) + return resp, fmt.Errorf("%v: orderStatus %s not supported", e.Name, ordersData[y].OrderState) } } @@ -979,7 +979,7 @@ func (d *Deribit) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } resp = append(resp, order.Detail{ AssetType: getOrdersRequest.AssetType, - Exchange: d.Name, + Exchange: e.Name, Price: ordersData[y].Price, Amount: ordersData[y].Amount, ExecutedAmount: ordersData[y].FilledAmount, @@ -999,11 +999,11 @@ func (d *Deribit) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } // GetFeeByType returns an estimate of fee based on the type of transaction -func (d *Deribit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !d.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } @@ -1030,28 +1030,28 @@ func (d *Deribit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (d *Deribit) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := d.UpdateAccountInfo(ctx, assetType) - return d.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (d *Deribit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := d.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - intervalString, err := d.GetResolutionFromInterval(req.ExchangeInterval) + intervalString, err := e.GetResolutionFromInterval(req.ExchangeInterval) if err != nil { return nil, err } switch a { case asset.Futures, asset.Spot: var tradingViewData *TVChartData - if d.Websocket.IsConnected() { - tradingViewData, err = d.WSRetrievesTradingViewChartData(ctx, d.formatFuturesTradablePair(req.RequestFormatted), intervalString, start, end) + if e.Websocket.IsConnected() { + tradingViewData, err = e.WSRetrievesTradingViewChartData(ctx, e.formatFuturesTradablePair(req.RequestFormatted), intervalString, start, end) } else { - tradingViewData, err = d.GetTradingViewChart(ctx, d.formatFuturesTradablePair(req.RequestFormatted), intervalString, start, end) + tradingViewData, err = e.GetTradingViewChart(ctx, e.formatFuturesTradablePair(req.RequestFormatted), intervalString, start, end) } if err != nil { return nil, err @@ -1089,8 +1089,8 @@ func (d *Deribit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (d *Deribit) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := d.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1099,14 +1099,14 @@ func (d *Deribit) GetHistoricCandlesExtended(ctx context.Context, pair currency. switch a { case asset.Futures, asset.Spot: for x := range req.RangeHolder.Ranges { - intervalString, err := d.GetResolutionFromInterval(req.ExchangeInterval) + intervalString, err := e.GetResolutionFromInterval(req.ExchangeInterval) if err != nil { return nil, err } - if d.Websocket.IsConnected() { - tradingViewData, err = d.WSRetrievesTradingViewChartData(ctx, d.formatFuturesTradablePair(req.RequestFormatted), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) + if e.Websocket.IsConnected() { + tradingViewData, err = e.WSRetrievesTradingViewChartData(ctx, e.formatFuturesTradablePair(req.RequestFormatted), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) } else { - tradingViewData, err = d.GetTradingViewChart(ctx, d.formatFuturesTradablePair(req.RequestFormatted), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) + tradingViewData, err = e.GetTradingViewChart(ctx, e.formatFuturesTradablePair(req.RequestFormatted), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) } if err != nil { return nil, err @@ -1117,7 +1117,7 @@ func (d *Deribit) GetHistoricCandlesExtended(ctx context.Context, pair currency. len(tradingViewData.Low) != checkLen || len(tradingViewData.Close) != checkLen || len(tradingViewData.Volume) != checkLen { - return nil, fmt.Errorf("%s - %v: invalid trading view chart data received", a, d.formatFuturesTradablePair(req.RequestFormatted)) + return nil, fmt.Errorf("%s - %v: invalid trading view chart data received", a, e.formatFuturesTradablePair(req.RequestFormatted)) } for i := range tradingViewData.Ticks { timeInfo := time.UnixMilli(tradingViewData.Ticks[i]).UTC() @@ -1142,17 +1142,17 @@ func (d *Deribit) GetHistoricCandlesExtended(ctx context.Context, pair currency. } // GetServerTime returns the current exchange server time. -func (d *Deribit) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - return d.GetTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + return e.GetTime(ctx) } // AuthenticateWebsocket sends an authentication message to the websocket -func (d *Deribit) AuthenticateWebsocket(ctx context.Context) error { - return d.wsLogin(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.wsLogin(ctx) } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (d *Deribit) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } @@ -1163,10 +1163,10 @@ func (d *Deribit) GetFuturesContractDetails(ctx context.Context, item asset.Item for _, ccy := range baseCurrencies { var marketSummary []*InstrumentData var err error - if d.Websocket.IsConnected() { - marketSummary, err = d.WSRetrieveInstrumentsData(ctx, currency.NewCode(ccy), d.GetAssetKind(item), false) + if e.Websocket.IsConnected() { + marketSummary, err = e.WSRetrieveInstrumentsData(ctx, currency.NewCode(ccy), e.GetAssetKind(item), false) } else { - marketSummary, err = d.GetInstruments(ctx, currency.NewCode(ccy), d.GetAssetKind(item), false) + marketSummary, err = e.GetInstruments(ctx, currency.NewCode(ccy), e.GetAssetKind(item), false) } if err != nil { return nil, err @@ -1197,7 +1197,7 @@ func (d *Deribit) GetFuturesContractDetails(ctx context.Context, item asset.Item contractSettlementType = futures.Linear } resp = append(resp, futures.Contract{ - Exchange: d.Name, + Exchange: e.Name, Name: cp, Underlying: currency.NewPair(currency.NewCode(inst.BaseCurrency), currency.NewCode(inst.QuoteCurrency)), Asset: item, @@ -1216,17 +1216,17 @@ func (d *Deribit) GetFuturesContractDetails(ctx context.Context, item asset.Item } // UpdateOrderExecutionLimits sets exchange execution order limits for an asset type -func (d *Deribit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { - if !d.SupportsAsset(a) { - return fmt.Errorf("%s: %w - %v", d.Name, asset.ErrNotSupported, a) +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { + return fmt.Errorf("%s: %w - %v", e.Name, asset.ErrNotSupported, a) } for _, x := range baseCurrencies { var instrumentsData []*InstrumentData var err error - if d.Websocket.IsConnected() { - instrumentsData, err = d.WSRetrieveInstrumentsData(ctx, currency.NewCode(x), d.GetAssetKind(a), false) + if e.Websocket.IsConnected() { + instrumentsData, err = e.WSRetrieveInstrumentsData(ctx, currency.NewCode(x), e.GetAssetKind(a), false) } else { - instrumentsData, err = d.GetInstruments(ctx, currency.NewCode(x), d.GetAssetKind(a), false) + instrumentsData, err = e.GetInstruments(ctx, currency.NewCode(x), e.GetAssetKind(a), false) } if err != nil { return err @@ -1248,7 +1248,7 @@ func (d *Deribit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) MinimumBaseAmount: inst.MinimumTradeAmount, } } - err = d.LoadLimits(limits) + err = e.LoadLimits(limits) if err != nil { return err } @@ -1257,7 +1257,7 @@ func (d *Deribit) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) } // GetFuturesPositionSummary returns position summary details for an active position -func (d *Deribit) GetFuturesPositionSummary(ctx context.Context, r *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { +func (e *Exchange) GetFuturesPositionSummary(ctx context.Context, r *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } @@ -1267,15 +1267,15 @@ func (d *Deribit) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi if r.Pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - fPair, err := d.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } var pos []PositionData - if d.Websocket.IsConnected() && d.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - pos, err = d.WSRetrievePositions(ctx, fPair.Base, d.GetAssetKind(r.Asset)) + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + pos, err = e.WSRetrievePositions(ctx, fPair.Base, e.GetAssetKind(r.Asset)) } else { - pos, err = d.GetPositions(ctx, fPair.Base, d.GetAssetKind(r.Asset)) + pos, err = e.GetPositions(ctx, fPair.Base, e.GetAssetKind(r.Asset)) } if err != nil { return nil, err @@ -1290,7 +1290,7 @@ func (d *Deribit) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi if index == -1 { return nil, errors.New("position information for the instrument not found") } - contracts, err := d.GetFuturesContractDetails(ctx, r.Asset) + contracts, err := e.GetFuturesContractDetails(ctx, r.Asset) if err != nil { return nil, err } @@ -1335,29 +1335,29 @@ func (d *Deribit) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi } // GetOpenInterest returns the open interest rate for a given asset pair -func (d *Deribit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { if len(k) == 0 { return nil, fmt.Errorf("%w requires pair", common.ErrFunctionNotSupported) } for i := range k { if k[i].Asset == asset.Spot || - !d.SupportsAsset(k[i].Asset) { + !e.SupportsAsset(k[i].Asset) { return nil, fmt.Errorf("%w %v %v", asset.ErrNotSupported, k[i].Asset, k[i].Pair()) } } result := make([]futures.OpenInterest, 0, len(k)) for i := range k { - pFmt, err := d.CurrencyPairs.GetFormat(k[i].Asset, true) + pFmt, err := e.CurrencyPairs.GetFormat(k[i].Asset, true) if err != nil { return nil, err } cp := k[i].Pair().Format(pFmt) - p := d.formatPairString(k[i].Asset, cp) + p := e.formatPairString(k[i].Asset, cp) var oi []BookSummaryData - if d.Websocket.IsConnected() { - oi, err = d.WSRetrieveBookSummaryByInstrument(ctx, p) + if e.Websocket.IsConnected() { + oi, err = e.WSRetrieveBookSummaryByInstrument(ctx, p) } else { - oi, err = d.GetBookSummaryByInstrument(ctx, p) + oi, err = e.GetBookSummaryByInstrument(ctx, p) } if err != nil { return nil, err @@ -1365,7 +1365,7 @@ func (d *Deribit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu for a := range oi { result = append(result, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: d.Name, + Exchange: e.Name, Base: k[i].Base, Quote: k[i].Quote, Asset: k[i].Asset, @@ -1382,13 +1382,13 @@ func (d *Deribit) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (d *Deribit) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { if cp.IsEmpty() { return "", currency.ErrCurrencyPairEmpty } switch a { case asset.Futures: - isPerp, err := d.IsPerpetualFutureCurrency(a, cp) + isPerp, err := e.IsPerpetualFutureCurrency(a, cp) if err != nil { return "", err } @@ -1419,7 +1419,7 @@ func (d *Deribit) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp curren // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future // differs by exchange -func (d *Deribit) IsPerpetualFutureCurrency(assetType asset.Item, pair currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(assetType asset.Item, pair currency.Pair) (bool, error) { if pair.IsEmpty() { return false, currency.ErrCurrencyPairEmpty } @@ -1432,28 +1432,28 @@ func (d *Deribit) IsPerpetualFutureCurrency(assetType asset.Item, pair currency. } // GetLatestFundingRates returns the latest funding rates data -func (d *Deribit) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } - if !d.SupportsAsset(r.Asset) { + if !e.SupportsAsset(r.Asset) { return nil, fmt.Errorf("%s %w", r.Asset, asset.ErrNotSupported) } - isPerpetual, err := d.IsPerpetualFutureCurrency(r.Asset, r.Pair) + isPerpetual, err := e.IsPerpetualFutureCurrency(r.Asset, r.Pair) if err != nil { return nil, err } if !isPerpetual { return nil, fmt.Errorf("%w %q", futures.ErrNotPerpetualFuture, r.Pair) } - pFmt, err := d.CurrencyPairs.GetFormat(r.Asset, true) + pFmt, err := e.CurrencyPairs.GetFormat(r.Asset, true) if err != nil { return nil, err } cp := r.Pair.Format(pFmt) - p := d.formatPairString(r.Asset, cp) + p := e.formatPairString(r.Asset, cp) var fri []FundingRateHistory - fri, err = d.GetFundingRateHistory(ctx, p, time.Now().Add(-time.Hour*16), time.Now()) + fri, err = e.GetFundingRateHistory(ctx, p, time.Now().Add(-time.Hour*16), time.Now()) if err != nil { return nil, err } @@ -1466,7 +1466,7 @@ func (d *Deribit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } resp[0] = fundingrate.LatestRateResponse{ TimeChecked: time.Now(), - Exchange: d.Name, + Exchange: e.Name, Asset: r.Asset, Pair: r.Pair, LatestRate: fundingrate.Rate{ @@ -1483,7 +1483,7 @@ func (d *Deribit) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } // GetHistoricalFundingRates returns historical funding rates for a future -func (d *Deribit) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { +func (e *Exchange) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1503,22 +1503,22 @@ func (d *Deribit) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. if r.IncludePayments { return nil, fmt.Errorf("include payments %w", common.ErrNotYetImplemented) } - pFmt, err := d.CurrencyPairs.GetFormat(r.Asset, true) + pFmt, err := e.CurrencyPairs.GetFormat(r.Asset, true) if err != nil { return nil, err } cp := r.Pair.Format(pFmt) - p := d.formatPairString(r.Asset, cp) + p := e.formatPairString(r.Asset, cp) ed := r.EndDate var fundingRates []fundingrate.Rate mfr := make(map[int64]struct{}) for ed.After(r.StartDate) { var records []FundingRateHistory - if d.Websocket.IsConnected() { - records, err = d.WSRetrieveFundingRateHistory(ctx, p, r.StartDate, ed) + if e.Websocket.IsConnected() { + records, err = e.WSRetrieveFundingRateHistory(ctx, p, r.StartDate, ed) } else { - records, err = d.GetFundingRateHistory(ctx, p, r.StartDate, ed) + records, err = e.GetFundingRateHistory(ctx, p, r.StartDate, ed) } if err != nil { return nil, err @@ -1549,7 +1549,7 @@ func (d *Deribit) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. return fundingRates[i].Time.Before(fundingRates[j].Time) }) return &fundingrate.HistoricalRates{ - Exchange: d.Name, + Exchange: e.Name, Asset: r.Asset, Pair: r.Pair, FundingRates: fundingRates, @@ -1560,12 +1560,12 @@ func (d *Deribit) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. }, nil } -func (d *Deribit) formatPairString(assetType asset.Item, pair currency.Pair) string { +func (e *Exchange) formatPairString(assetType asset.Item, pair currency.Pair) string { switch assetType { case asset.Futures: - return d.formatFuturesTradablePair(pair) + return e.formatFuturesTradablePair(pair) case asset.Options: - return d.optionPairToString(pair) + return e.optionPairToString(pair) } return pair.String() } diff --git a/exchanges/deribit/deribit_ws_endpoints.go b/exchanges/deribit/deribit_ws_endpoints.go index 26c49d4dd76..96e79eb2a39 100644 --- a/exchanges/deribit/deribit_ws_endpoints.go +++ b/exchanges/deribit/deribit_ws_endpoints.go @@ -18,7 +18,7 @@ import ( ) // WSRetrieveBookBySummary retrieves book summary data for currency requested through websocket connection. -func (d *Deribit) WSRetrieveBookBySummary(ctx context.Context, ccy currency.Code, kind string) ([]BookSummaryData, error) { +func (e *Exchange) WSRetrieveBookBySummary(ctx context.Context, ccy currency.Code, kind string) ([]BookSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -32,11 +32,11 @@ func (d *Deribit) WSRetrieveBookBySummary(ctx context.Context, ccy currency.Code input.Kind = kind } var resp []BookSummaryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getBookByCurrency, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getBookByCurrency, input, &resp, false) } // WSRetrieveBookSummaryByInstrument retrieves book summary data for instrument requested through the websocket connection. -func (d *Deribit) WSRetrieveBookSummaryByInstrument(ctx context.Context, instrument string) ([]BookSummaryData, error) { +func (e *Exchange) WSRetrieveBookSummaryByInstrument(ctx context.Context, instrument string) ([]BookSummaryData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -46,11 +46,11 @@ func (d *Deribit) WSRetrieveBookSummaryByInstrument(ctx context.Context, instrum Instrument: instrument, } var resp []BookSummaryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getBookByInstrument, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getBookByInstrument, input, &resp, false) } // WSRetrieveContractSize retrieves contract size for instrument requested through the websocket connection. -func (d *Deribit) WSRetrieveContractSize(ctx context.Context, instrument string) (*ContractSizeData, error) { +func (e *Exchange) WSRetrieveContractSize(ctx context.Context, instrument string) (*ContractSizeData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -60,17 +60,17 @@ func (d *Deribit) WSRetrieveContractSize(ctx context.Context, instrument string) Instrument: instrument, } var resp *ContractSizeData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getContractSize, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getContractSize, input, &resp, false) } // WSRetrieveCurrencies retrieves all cryptocurrencies supported by the API through the websocket connection. -func (d *Deribit) WSRetrieveCurrencies(ctx context.Context) ([]CurrencyData, error) { +func (e *Exchange) WSRetrieveCurrencies(ctx context.Context) ([]CurrencyData, error) { var resp []CurrencyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getCurrencies, nil, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getCurrencies, nil, &resp, false) } // WSRetrieveDeliveryPrices retrieves delivery prices using index name through the websocket connection. -func (d *Deribit) WSRetrieveDeliveryPrices(ctx context.Context, indexName string, offset, count int64) (*IndexDeliveryPrice, error) { +func (e *Exchange) WSRetrieveDeliveryPrices(ctx context.Context, indexName string, offset, count int64) (*IndexDeliveryPrice, error) { if indexName == "" { return nil, errUnsupportedIndexName } @@ -84,12 +84,12 @@ func (d *Deribit) WSRetrieveDeliveryPrices(ctx context.Context, indexName string Count: count, } var resp *IndexDeliveryPrice - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getDeliveryPrices, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getDeliveryPrices, input, &resp, false) } // WSRetrieveFundingChartData retrieves funding chart data for the requested instrument and time length through the websocket connection. // supported lengths: 8h, 24h, 1m <-(1month) -func (d *Deribit) WSRetrieveFundingChartData(ctx context.Context, instrument, length string) (*FundingChartData, error) { +func (e *Exchange) WSRetrieveFundingChartData(ctx context.Context, instrument, length string) (*FundingChartData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -104,11 +104,11 @@ func (d *Deribit) WSRetrieveFundingChartData(ctx context.Context, instrument, le Length: length, } var resp *FundingChartData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getFundingChartData, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getFundingChartData, input, &resp, false) } // WSRetrieveFundingRateHistory retrieves hourly historical interest rate for requested PERPETUAL instrument through the websocket connection. -func (d *Deribit) WSRetrieveFundingRateHistory(ctx context.Context, instrumentName string, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (e *Exchange) WSRetrieveFundingRateHistory(ctx context.Context, instrumentName string, startTime, endTime time.Time) ([]FundingRateHistory, error) { if instrumentName == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -126,11 +126,11 @@ func (d *Deribit) WSRetrieveFundingRateHistory(ctx context.Context, instrumentNa EndTime: endTime.UnixMilli(), } var resp []FundingRateHistory - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getFundingRateHistory, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getFundingRateHistory, input, &resp, false) } // WSRetrieveFundingRateValue retrieves funding rate value data through the websocket connection. -func (d *Deribit) WSRetrieveFundingRateValue(ctx context.Context, instrument string, startTime, endTime time.Time) (float64, error) { +func (e *Exchange) WSRetrieveFundingRateValue(ctx context.Context, instrument string, startTime, endTime time.Time) (float64, error) { if instrument == "" { return 0, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -147,11 +147,11 @@ func (d *Deribit) WSRetrieveFundingRateValue(ctx context.Context, instrument str EndTimestamp: endTime.UnixMilli(), } var resp float64 - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getFundingRateValue, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getFundingRateValue, input, &resp, false) } // WSRetrieveHistoricalVolatility retrieves historical volatility data -func (d *Deribit) WSRetrieveHistoricalVolatility(ctx context.Context, ccy currency.Code) ([]HistoricalVolatilityData, error) { +func (e *Exchange) WSRetrieveHistoricalVolatility(ctx context.Context, ccy currency.Code) ([]HistoricalVolatilityData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -161,11 +161,11 @@ func (d *Deribit) WSRetrieveHistoricalVolatility(ctx context.Context, ccy curren Currency: ccy, } var data []HistoricalVolatilityData - return data, d.SendWSRequest(ctx, nonMatchingEPL, getHistoricalVolatility, input, &data, false) + return data, e.SendWSRequest(ctx, nonMatchingEPL, getHistoricalVolatility, input, &data, false) } // WSRetrieveCurrencyIndexPrice the current index price for the instruments, for the selected currency through the websocket connection. -func (d *Deribit) WSRetrieveCurrencyIndexPrice(ctx context.Context, ccy currency.Code) (map[string]float64, error) { +func (e *Exchange) WSRetrieveCurrencyIndexPrice(ctx context.Context, ccy currency.Code) (map[string]float64, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -175,11 +175,11 @@ func (d *Deribit) WSRetrieveCurrencyIndexPrice(ctx context.Context, ccy currency Currency: ccy, } var resp map[string]float64 - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getCurrencyIndexPrice, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getCurrencyIndexPrice, input, &resp, false) } // WSRetrieveIndexPrice retrieves price data for the requested index through the websocket connection. -func (d *Deribit) WSRetrieveIndexPrice(ctx context.Context, index string) (*IndexPriceData, error) { +func (e *Exchange) WSRetrieveIndexPrice(ctx context.Context, index string) (*IndexPriceData, error) { if index == "" { return nil, fmt.Errorf("%w index can not be empty", errUnsupportedIndexName) } @@ -189,17 +189,17 @@ func (d *Deribit) WSRetrieveIndexPrice(ctx context.Context, index string) (*Inde IndexName: index, } var resp *IndexPriceData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getIndexPrice, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getIndexPrice, input, &resp, false) } // WSRetrieveIndexPriceNames names of indexes through the websocket connection. -func (d *Deribit) WSRetrieveIndexPriceNames(ctx context.Context) ([]string, error) { +func (e *Exchange) WSRetrieveIndexPriceNames(ctx context.Context) ([]string, error) { var resp []string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getIndexPriceNames, nil, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getIndexPriceNames, nil, &resp, false) } // WSRetrieveInstrumentData retrieves data for a requested instrument through the websocket connection. -func (d *Deribit) WSRetrieveInstrumentData(ctx context.Context, instrument string) (*InstrumentData, error) { +func (e *Exchange) WSRetrieveInstrumentData(ctx context.Context, instrument string) (*InstrumentData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -209,11 +209,11 @@ func (d *Deribit) WSRetrieveInstrumentData(ctx context.Context, instrument strin Instrument: instrument, } var resp *InstrumentData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getInstrument, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getInstrument, input, &resp, false) } // WSRetrieveInstrumentsData gets data for all available instruments -func (d *Deribit) WSRetrieveInstrumentsData(ctx context.Context, ccy currency.Code, kind string, expired bool) ([]*InstrumentData, error) { +func (e *Exchange) WSRetrieveInstrumentsData(ctx context.Context, ccy currency.Code, kind string, expired bool) ([]*InstrumentData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -227,11 +227,11 @@ func (d *Deribit) WSRetrieveInstrumentsData(ctx context.Context, ccy currency.Co Kind: kind, } var resp []*InstrumentData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getInstruments, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getInstruments, input, &resp, false) } // WSRetrieveLastSettlementsByCurrency retrieves last settlement data by currency through the websocket connection. -func (d *Deribit) WSRetrieveLastSettlementsByCurrency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { +func (e *Exchange) WSRetrieveLastSettlementsByCurrency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -249,11 +249,11 @@ func (d *Deribit) WSRetrieveLastSettlementsByCurrency(ctx context.Context, ccy c SearchStartTimestamp: startTime.UnixMilli(), } var resp *SettlementsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastSettlementsByCurrency, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastSettlementsByCurrency, input, &resp, false) } // WSRetrieveLastSettlementsByInstrument retrieves last settlement data for requested instrument through the websocket connection. -func (d *Deribit) WSRetrieveLastSettlementsByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { +func (e *Exchange) WSRetrieveLastSettlementsByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, startTime time.Time) (*SettlementsData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -273,11 +273,11 @@ func (d *Deribit) WSRetrieveLastSettlementsByInstrument(ctx context.Context, ins input.SearchStartTimestamp = startTime.UnixMilli() } var resp *SettlementsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastSettlementsByInstrument, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastSettlementsByInstrument, input, &resp, false) } // WSRetrieveLastTradesByCurrency retrieves last trades for requested currency through the websocket connection. -func (d *Deribit) WSRetrieveLastTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { +func (e *Exchange) WSRetrieveLastTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -299,11 +299,11 @@ func (d *Deribit) WSRetrieveLastTradesByCurrency(ctx context.Context, ccy curren Sorting: sorting, } var resp *PublicTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByCurrency, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByCurrency, input, &resp, false) } // WSRetrieveLastTradesByCurrencyAndTime retrieves last trades for requested currency and time intervals through the websocket connection. -func (d *Deribit) WSRetrieveLastTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*PublicTradesData, error) { +func (e *Exchange) WSRetrieveLastTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*PublicTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -328,11 +328,11 @@ func (d *Deribit) WSRetrieveLastTradesByCurrencyAndTime(ctx context.Context, ccy Sorting: sorting, } var resp *PublicTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByCurrencyAndTime, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByCurrencyAndTime, input, &resp, false) } // WSRetrieveLastTradesByInstrument retrieves last trades for requested instrument requested through the websocket connection. -func (d *Deribit) WSRetrieveLastTradesByInstrument(ctx context.Context, instrument, startSeq, endSeq, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { +func (e *Exchange) WSRetrieveLastTradesByInstrument(ctx context.Context, instrument, startSeq, endSeq, sorting string, count int64, includeOld bool) (*PublicTradesData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -352,11 +352,11 @@ func (d *Deribit) WSRetrieveLastTradesByInstrument(ctx context.Context, instrume IncludeOld: includeOld, } var resp *PublicTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByInstrument, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByInstrument, input, &resp, false) } // WSRetrieveLastTradesByInstrumentAndTime retrieves last trades for requested instrument requested and time intervals through the websocket connection. -func (d *Deribit) WSRetrieveLastTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*PublicTradesData, error) { +func (e *Exchange) WSRetrieveLastTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*PublicTradesData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -379,11 +379,11 @@ func (d *Deribit) WSRetrieveLastTradesByInstrumentAndTime(ctx context.Context, i input.StartTimestamp = startTime.UnixMilli() input.EndTimestamp = endTime.UnixMilli() var resp *PublicTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByInstrumentAndTime, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastTradesByInstrumentAndTime, input, &resp, false) } // WSRetrieveMarkPriceHistory retrieves data for mark price history through the websocket connection. -func (d *Deribit) WSRetrieveMarkPriceHistory(ctx context.Context, instrument string, startTime, endTime time.Time) ([]MarkPriceHistory, error) { +func (e *Exchange) WSRetrieveMarkPriceHistory(ctx context.Context, instrument string, startTime, endTime time.Time) ([]MarkPriceHistory, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -400,11 +400,11 @@ func (d *Deribit) WSRetrieveMarkPriceHistory(ctx context.Context, instrument str EndTimestamp: endTime.UnixMilli(), } var resp []MarkPriceHistory - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getMarkPriceHistory, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getMarkPriceHistory, input, &resp, false) } // WSRetrieveOrderbookData retrieves data orderbook of requested instrument through the web-socket connection. -func (d *Deribit) WSRetrieveOrderbookData(ctx context.Context, instrument string, depth int64) (*Orderbook, error) { +func (e *Exchange) WSRetrieveOrderbookData(ctx context.Context, instrument string, depth int64) (*Orderbook, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -416,11 +416,11 @@ func (d *Deribit) WSRetrieveOrderbookData(ctx context.Context, instrument string Depth: depth, } var resp *Orderbook - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderbook, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderbook, input, &resp, false) } // WSRetrieveOrderbookByInstrumentID retrieves orderbook by instrument ID through websocket connection. -func (d *Deribit) WSRetrieveOrderbookByInstrumentID(ctx context.Context, instrumentID int64, depth float64) (*Orderbook, error) { +func (e *Exchange) WSRetrieveOrderbookByInstrumentID(ctx context.Context, instrumentID int64, depth float64) (*Orderbook, error) { if instrumentID == 0 { return nil, errInvalidInstrumentID } @@ -432,23 +432,23 @@ func (d *Deribit) WSRetrieveOrderbookByInstrumentID(ctx context.Context, instrum Depth: depth, } var resp *Orderbook - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderbookByInstrumentID, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderbookByInstrumentID, input, &resp, false) } // WsRetrieveSupportedIndexNames retrieves the identifiers of all supported Price Indexes // 'type' represents Type of a cryptocurrency price index. possible 'all', 'spot', 'derivative' -func (d *Deribit) WsRetrieveSupportedIndexNames(ctx context.Context, priceIndexType string) ([]string, error) { +func (e *Exchange) WsRetrieveSupportedIndexNames(ctx context.Context, priceIndexType string) ([]string, error) { input := &struct { PriceIndexType string `json:"type,omitempty"` }{ PriceIndexType: priceIndexType, } var resp []string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "public/get_supported_index_names", input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "public/get_supported_index_names", input, &resp, false) } // WSRetrieveRequestForQuote retrieves RFQ information. -func (d *Deribit) WSRetrieveRequestForQuote(ctx context.Context, ccy currency.Code, kind string) ([]RequestForQuote, error) { +func (e *Exchange) WSRetrieveRequestForQuote(ctx context.Context, ccy currency.Code, kind string) ([]RequestForQuote, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -460,22 +460,22 @@ func (d *Deribit) WSRetrieveRequestForQuote(ctx context.Context, ccy currency.Co Kind: kind, } var resp []RequestForQuote - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getRFQ, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getRFQ, input, &resp, false) } // WSRetrieveTradeVolumes retrieves trade volumes' data of all instruments through the websocket connection. -func (d *Deribit) WSRetrieveTradeVolumes(ctx context.Context, extended bool) ([]TradeVolumesData, error) { +func (e *Exchange) WSRetrieveTradeVolumes(ctx context.Context, extended bool) ([]TradeVolumesData, error) { input := &struct { Extended bool `json:"extended,omitempty"` }{ Extended: extended, } var resp []TradeVolumesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTradeVolumes, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTradeVolumes, input, &resp, false) } // WSRetrievesTradingViewChartData retrieves volatility index data for the requested instrument through the websocket connection. -func (d *Deribit) WSRetrievesTradingViewChartData(ctx context.Context, instrument, resolution string, startTime, endTime time.Time) (*TVChartData, error) { +func (e *Exchange) WSRetrievesTradingViewChartData(ctx context.Context, instrument, resolution string, startTime, endTime time.Time) (*TVChartData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -497,11 +497,11 @@ func (d *Deribit) WSRetrievesTradingViewChartData(ctx context.Context, instrumen EndTimestamp: endTime.UnixMilli(), } var resp *TVChartData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTradingViewChartData, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTradingViewChartData, input, &resp, false) } // WSRetrieveVolatilityIndexData retrieves volatility index data for the requested currency through the websocket connection. -func (d *Deribit) WSRetrieveVolatilityIndexData(ctx context.Context, ccy currency.Code, resolution string, startTime, endTime time.Time) ([]VolatilityIndexData, error) { +func (e *Exchange) WSRetrieveVolatilityIndexData(ctx context.Context, ccy currency.Code, resolution string, startTime, endTime time.Time) ([]VolatilityIndexData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -524,7 +524,7 @@ func (d *Deribit) WSRetrieveVolatilityIndexData(ctx context.Context, ccy currenc EndTimestamp: endTime.UnixMilli(), } var resp VolatilityIndexRawData - err = d.SendWSRequest(ctx, nonMatchingEPL, getVolatilityIndex, input, &resp, false) + err = e.SendWSRequest(ctx, nonMatchingEPL, getVolatilityIndex, input, &resp, false) if err != nil { return nil, err } @@ -542,7 +542,7 @@ func (d *Deribit) WSRetrieveVolatilityIndexData(ctx context.Context, ccy currenc } // WSRetrievePublicTicker retrieves public ticker data of the instrument requested through the websocket connection. -func (d *Deribit) WSRetrievePublicTicker(ctx context.Context, instrument string) (*TickerData, error) { +func (e *Exchange) WSRetrievePublicTicker(ctx context.Context, instrument string) (*TickerData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } @@ -552,11 +552,11 @@ func (d *Deribit) WSRetrievePublicTicker(ctx context.Context, instrument string) Instrument: instrument, } var resp *TickerData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTicker, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTicker, input, &resp, false) } // WSRetrieveAccountSummary retrieves account summary data for the requested instrument through the websocket connection. -func (d *Deribit) WSRetrieveAccountSummary(ctx context.Context, ccy currency.Code, extended bool) (*AccountSummaryData, error) { +func (e *Exchange) WSRetrieveAccountSummary(ctx context.Context, ccy currency.Code, extended bool) (*AccountSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -568,11 +568,11 @@ func (d *Deribit) WSRetrieveAccountSummary(ctx context.Context, ccy currency.Cod Extended: extended, } var resp *AccountSummaryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getAccountSummary, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getAccountSummary, input, &resp, true) } // WSCancelWithdrawal cancels withdrawal request for a given currency by its id through the websocket connection. -func (d *Deribit) WSCancelWithdrawal(ctx context.Context, ccy currency.Code, id int64) (*CancelWithdrawalData, error) { +func (e *Exchange) WSCancelWithdrawal(ctx context.Context, ccy currency.Code, id int64) (*CancelWithdrawalData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -587,11 +587,11 @@ func (d *Deribit) WSCancelWithdrawal(ctx context.Context, ccy currency.Code, id ID: id, } var resp *CancelWithdrawalData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, cancelWithdrawal, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, cancelWithdrawal, input, &resp, true) } // WSCancelTransferByID cancels transfer by ID through the websocket connection. -func (d *Deribit) WSCancelTransferByID(ctx context.Context, ccy currency.Code, tfa string, id int64) (*AccountSummaryData, error) { +func (e *Exchange) WSCancelTransferByID(ctx context.Context, ccy currency.Code, tfa string, id int64) (*AccountSummaryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -608,11 +608,11 @@ func (d *Deribit) WSCancelTransferByID(ctx context.Context, ccy currency.Code, t TwoFactorAuthenticationCode: tfa, } var resp *AccountSummaryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, cancelTransferByID, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, cancelTransferByID, input, &resp, true) } // WSCreateDepositAddress creates a deposit address for the currency requested through the websocket connection. -func (d *Deribit) WSCreateDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { +func (e *Exchange) WSCreateDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -622,11 +622,11 @@ func (d *Deribit) WSCreateDepositAddress(ctx context.Context, ccy currency.Code) Currency: ccy, } var resp *DepositAddressData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, createDepositAddress, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, createDepositAddress, input, &resp, true) } // WSRetrieveDeposits retrieves the deposits of a given currency through the websocket connection. -func (d *Deribit) WSRetrieveDeposits(ctx context.Context, ccy currency.Code, count, offset int64) (*DepositsData, error) { +func (e *Exchange) WSRetrieveDeposits(ctx context.Context, ccy currency.Code, count, offset int64) (*DepositsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -640,11 +640,11 @@ func (d *Deribit) WSRetrieveDeposits(ctx context.Context, ccy currency.Code, cou Offset: offset, } var resp *DepositsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getDeposits, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getDeposits, input, &resp, true) } // WSRetrieveTransfers retrieves data for the requested currency through the websocket connection. -func (d *Deribit) WSRetrieveTransfers(ctx context.Context, ccy currency.Code, count, offset int64) (*TransfersData, error) { +func (e *Exchange) WSRetrieveTransfers(ctx context.Context, ccy currency.Code, count, offset int64) (*TransfersData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -658,11 +658,11 @@ func (d *Deribit) WSRetrieveTransfers(ctx context.Context, ccy currency.Code, co Offset: offset, } var resp *TransfersData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTransfers, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTransfers, input, &resp, true) } // WSRetrieveCurrentDepositAddress retrieves the current deposit address for the requested currency through the websocket connection. -func (d *Deribit) WSRetrieveCurrentDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { +func (e *Exchange) WSRetrieveCurrentDepositAddress(ctx context.Context, ccy currency.Code) (*DepositAddressData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -672,7 +672,7 @@ func (d *Deribit) WSRetrieveCurrentDepositAddress(ctx context.Context, ccy curre Currency: ccy, } var resp *DepositAddressData - err := d.SendWSRequest(ctx, nonMatchingEPL, getCurrentDepositAddress, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, getCurrentDepositAddress, input, &resp, true) if err != nil { return nil, err } else if resp == nil { @@ -682,7 +682,7 @@ func (d *Deribit) WSRetrieveCurrentDepositAddress(ctx context.Context, ccy curre } // WSRetrieveWithdrawals retrieves withdrawals data for a requested currency through the websocket connection. -func (d *Deribit) WSRetrieveWithdrawals(ctx context.Context, ccy currency.Code, count, offset int64) (*WithdrawalsData, error) { +func (e *Exchange) WSRetrieveWithdrawals(ctx context.Context, ccy currency.Code, count, offset int64) (*WithdrawalsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -696,11 +696,11 @@ func (d *Deribit) WSRetrieveWithdrawals(ctx context.Context, ccy currency.Code, Offset: offset, } var resp *WithdrawalsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getWithdrawals, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getWithdrawals, input, &resp, true) } // WsSubmitTransferBetweenSubAccounts transfer funds between two (sub)accounts. -func (d *Deribit) WsSubmitTransferBetweenSubAccounts(ctx context.Context, ccy currency.Code, amount float64, destinationID int64, source string) (*TransferData, error) { +func (e *Exchange) WsSubmitTransferBetweenSubAccounts(ctx context.Context, ccy currency.Code, amount float64, destinationID int64, source string) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -722,11 +722,11 @@ func (d *Deribit) WsSubmitTransferBetweenSubAccounts(ctx context.Context, ccy cu Source: source, } var resp *TransferData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, submitTransferBetweenSubAccounts, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, submitTransferBetweenSubAccounts, input, &resp, true) } // WSSubmitTransferToSubAccount submits a request to transfer a currency to a subaccount -func (d *Deribit) WSSubmitTransferToSubAccount(ctx context.Context, ccy currency.Code, amount float64, destinationID int64) (*TransferData, error) { +func (e *Exchange) WSSubmitTransferToSubAccount(ctx context.Context, ccy currency.Code, amount float64, destinationID int64) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -746,11 +746,11 @@ func (d *Deribit) WSSubmitTransferToSubAccount(ctx context.Context, ccy currency Amount: amount, } var resp *TransferData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, submitTransferToSubaccount, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, submitTransferToSubaccount, input, &resp, true) } // WSSubmitTransferToUser submits a request to transfer a currency to another user through the websocket connection. -func (d *Deribit) WSSubmitTransferToUser(ctx context.Context, ccy currency.Code, tfa, destinationAddress string, amount float64) (*TransferData, error) { +func (e *Exchange) WSSubmitTransferToUser(ctx context.Context, ccy currency.Code, tfa, destinationAddress string, amount float64) (*TransferData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -772,13 +772,13 @@ func (d *Deribit) WSSubmitTransferToUser(ctx context.Context, ccy currency.Code, Amount: amount, } var resp *TransferData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, submitTransferToUser, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, submitTransferToUser, input, &resp, true) } // ---------------------------------------------------------------------------- // WSSubmitWithdraw submits a withdrawal request to the exchange for the requested currency through the websocket connection. -func (d *Deribit) WSSubmitWithdraw(ctx context.Context, ccy currency.Code, address, priority string, amount float64) (*WithdrawData, error) { +func (e *Exchange) WSSubmitWithdraw(ctx context.Context, ccy currency.Code, address, priority string, amount float64) (*WithdrawData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -800,11 +800,11 @@ func (d *Deribit) WSSubmitWithdraw(ctx context.Context, ccy currency.Code, addre Amount: amount, } var resp *WithdrawData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, submitWithdraw, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, submitWithdraw, input, &resp, true) } // WSRetrieveAnnouncements retrieves announcements through the websocket connection. Default "start_timestamp" parameter value is current timestamp, "count" parameter value must be between 1 and 50, default is 5. -func (d *Deribit) WSRetrieveAnnouncements(ctx context.Context, startTime time.Time, count int64) ([]Announcement, error) { +func (e *Exchange) WSRetrieveAnnouncements(ctx context.Context, startTime time.Time, count int64) ([]Announcement, error) { input := &struct { StartTime int64 `json:"start_time,omitempty"` Count int64 `json:"count,omitempty"` @@ -816,11 +816,11 @@ func (d *Deribit) WSRetrieveAnnouncements(ctx context.Context, startTime time.Ti input.Count = count } var resp []Announcement - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getAnnouncements, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getAnnouncements, input, &resp, false) } // WSChangeAPIKeyName changes the name of the api key requested through the websocket connection. -func (d *Deribit) WSChangeAPIKeyName(ctx context.Context, id int64, name string) (*APIKeyData, error) { +func (e *Exchange) WSChangeAPIKeyName(ctx context.Context, id int64, name string) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } @@ -835,13 +835,13 @@ func (d *Deribit) WSChangeAPIKeyName(ctx context.Context, id int64, name string) Name: name, } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, changeAPIKeyName, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, changeAPIKeyName, input, &resp, true) } // WsChangeMarginModel change margin model // Margin model: 'cross_pm', 'cross_sm', 'segregated_pm', 'segregated_sm' // 'dry_run': If true request returns the result without switching the margining model. Default: false -func (d *Deribit) WsChangeMarginModel(ctx context.Context, userID int64, marginModel string, dryRun bool) ([]TogglePortfolioMarginResponse, error) { +func (e *Exchange) WsChangeMarginModel(ctx context.Context, userID int64, marginModel string, dryRun bool) ([]TogglePortfolioMarginResponse, error) { if marginModel == "" { return nil, errInvalidMarginModel } @@ -855,11 +855,11 @@ func (d *Deribit) WsChangeMarginModel(ctx context.Context, userID int64, marginM DryRun: dryRun, } var resp []TogglePortfolioMarginResponse - return resp, d.SendWSRequest(ctx, nonMatchingEPL, changeMarginModel, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, changeMarginModel, input, &resp, true) } // WSChangeScopeInAPIKey changes the name of the requested subaccount id through the websocket connection. -func (d *Deribit) WSChangeScopeInAPIKey(ctx context.Context, id int64, maxScope string) (*APIKeyData, error) { +func (e *Exchange) WSChangeScopeInAPIKey(ctx context.Context, id int64, maxScope string) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } @@ -871,11 +871,11 @@ func (d *Deribit) WSChangeScopeInAPIKey(ctx context.Context, id int64, maxScope MaxScope: maxScope, } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, changeScopeInAPIKey, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, changeScopeInAPIKey, input, &resp, true) } // WSChangeSubAccountName retrieves changes the name of the requested subaccount id through the websocket connection. -func (d *Deribit) WSChangeSubAccountName(ctx context.Context, sid int64, name string) error { +func (e *Exchange) WSChangeSubAccountName(ctx context.Context, sid int64, name string) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -890,7 +890,7 @@ func (d *Deribit) WSChangeSubAccountName(ctx context.Context, sid int64, name st Name: name, } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, changeSubAccountName, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, changeSubAccountName, input, &resp, true) if err != nil { return err } @@ -901,7 +901,7 @@ func (d *Deribit) WSChangeSubAccountName(ctx context.Context, sid int64, name st } // WSCreateAPIKey creates an api key based on the provided settings through the websocket connection. -func (d *Deribit) WSCreateAPIKey(ctx context.Context, maxScope, name string, defaultKey bool) (*APIKeyData, error) { +func (e *Exchange) WSCreateAPIKey(ctx context.Context, maxScope, name string, defaultKey bool) (*APIKeyData, error) { input := &struct { MaxScope string `json:"max_scope"` Name string `json:"name,omitempty"` @@ -913,17 +913,17 @@ func (d *Deribit) WSCreateAPIKey(ctx context.Context, maxScope, name string, def } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, createAPIKey, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, createAPIKey, input, &resp, true) } // WSCreateSubAccount creates a new subaccount through the websocket connection. -func (d *Deribit) WSCreateSubAccount(ctx context.Context) (*SubAccountData, error) { +func (e *Exchange) WSCreateSubAccount(ctx context.Context) (*SubAccountData, error) { var resp *SubAccountData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, createSubAccount, nil, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, createSubAccount, nil, &resp, true) } // WSDisableAPIKey disables the api key linked to the provided id through the websocket connection. -func (d *Deribit) WSDisableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { +func (e *Exchange) WSDisableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } @@ -933,7 +933,7 @@ func (d *Deribit) WSDisableAPIKey(ctx context.Context, id int64) (*APIKeyData, e ID: id, } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, disableAPIKey, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, disableAPIKey, input, &resp, true) } // WsEditAPIKey edits existing API key. At least one parameter is required. @@ -942,7 +942,7 @@ func (d *Deribit) WSDisableAPIKey(ctx context.Context, id int64) (*APIKeyData, e // wallet:[read, read_write, none], // account:[read, read_write, none], // block_trade:[read, read_write, none]. -func (d *Deribit) WsEditAPIKey(ctx context.Context, id int64, maxScope, name string, enabled bool, enabledFeatures, ipWhitelist []string) (*APIKeyData, error) { +func (e *Exchange) WsEditAPIKey(ctx context.Context, id int64, maxScope, name string, enabled bool, enabledFeatures, ipWhitelist []string) (*APIKeyData, error) { if id == 0 { return nil, errInvalidAPIKeyID } @@ -965,13 +965,13 @@ func (d *Deribit) WsEditAPIKey(ctx context.Context, id int64, maxScope, name str IPWhitelist: ipWhitelist, } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, editAPIKey, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, editAPIKey, input, &resp, true) } // WSEnableAffiliateProgram enables the affiliate program through the websocket connection. -func (d *Deribit) WSEnableAffiliateProgram(ctx context.Context) error { +func (e *Exchange) WSEnableAffiliateProgram(ctx context.Context) error { var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, enableAffiliateProgram, nil, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, enableAffiliateProgram, nil, &resp, true) if err != nil { return err } @@ -982,16 +982,16 @@ func (d *Deribit) WSEnableAffiliateProgram(ctx context.Context) error { } // WSEnableAPIKey enables the api key linked to the provided id through the websocket connection. -func (d *Deribit) WSEnableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { +func (e *Exchange) WSEnableAPIKey(ctx context.Context, id int64) (*APIKeyData, error) { if id <= 0 { return nil, fmt.Errorf("%w, invalid api key id", errInvalidID) } var resp *APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, enableAPIKey, map[string]int64{"id": id}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, enableAPIKey, map[string]int64{"id": id}, &resp, true) } // WSRetrieveAccessLog lists access logs for the user through the websocket connection. -func (d *Deribit) WSRetrieveAccessLog(ctx context.Context, offset, count int64) (*AccessLog, error) { +func (e *Exchange) WSRetrieveAccessLog(ctx context.Context, offset, count int64) (*AccessLog, error) { input := &struct { Offset int64 `json:"offset,omitempty"` Count int64 `json:"count,omitempty"` @@ -1000,44 +1000,44 @@ func (d *Deribit) WSRetrieveAccessLog(ctx context.Context, offset, count int64) Count: count, } var resp *AccessLog - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getAccessLog, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getAccessLog, input, &resp, true) } // WSRetrieveAffiliateProgramInfo retrieves the affiliate program info through the websocket connection. -func (d *Deribit) WSRetrieveAffiliateProgramInfo(ctx context.Context) (*AffiliateProgramInfo, error) { +func (e *Exchange) WSRetrieveAffiliateProgramInfo(ctx context.Context) (*AffiliateProgramInfo, error) { var resp *AffiliateProgramInfo - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getAffiliateProgramInfo, nil, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getAffiliateProgramInfo, nil, &resp, true) } // WSRetrieveEmailLanguage retrieves the current language set for the email through the websocket connection. -func (d *Deribit) WSRetrieveEmailLanguage(ctx context.Context) (string, error) { +func (e *Exchange) WSRetrieveEmailLanguage(ctx context.Context) (string, error) { var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getEmailLanguage, nil, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getEmailLanguage, nil, &resp, true) } // WSRetrieveNewAnnouncements retrieves new announcements through the websocket connection. -func (d *Deribit) WSRetrieveNewAnnouncements(ctx context.Context) ([]Announcement, error) { +func (e *Exchange) WSRetrieveNewAnnouncements(ctx context.Context) ([]Announcement, error) { var resp []Announcement - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getNewAnnouncements, nil, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getNewAnnouncements, nil, &resp, true) } // WSRetrievePosition retrieves the data of all positions in the requested instrument name through the websocket connection. -func (d *Deribit) WSRetrievePosition(ctx context.Context, instrument string) (*PositionData, error) { +func (e *Exchange) WSRetrievePosition(ctx context.Context, instrument string) (*PositionData, error) { if instrument == "" { return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } var resp *PositionData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getPosition, map[string]string{"instrument_name": instrument}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getPosition, map[string]string{"instrument_name": instrument}, &resp, true) } // WSRetrieveSubAccounts retrieves all subaccounts' data through the websocket connection. -func (d *Deribit) WSRetrieveSubAccounts(ctx context.Context, withPortfolio bool) ([]SubAccountData, error) { +func (e *Exchange) WSRetrieveSubAccounts(ctx context.Context, withPortfolio bool) ([]SubAccountData, error) { var resp []SubAccountData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getSubAccounts, map[string]bool{"with_portfolio": withPortfolio}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getSubAccounts, map[string]bool{"with_portfolio": withPortfolio}, &resp, true) } // WSRetrieveSubAccountDetails retrieves sub-account detail information through the websocket connection. -func (d *Deribit) WSRetrieveSubAccountDetails(ctx context.Context, ccy currency.Code, withOpenOrders bool) ([]SubAccountDetail, error) { +func (e *Exchange) WSRetrieveSubAccountDetails(ctx context.Context, ccy currency.Code, withOpenOrders bool) ([]SubAccountDetail, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1049,11 +1049,11 @@ func (d *Deribit) WSRetrieveSubAccountDetails(ctx context.Context, ccy currency. WithOpenOrders: withOpenOrders, } var resp []SubAccountDetail - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getSubAccountDetails, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getSubAccountDetails, input, &resp, true) } // WSRetrievePositions retrieves positions data of the user account through the websocket connection. -func (d *Deribit) WSRetrievePositions(ctx context.Context, ccy currency.Code, kind string) ([]PositionData, error) { +func (e *Exchange) WSRetrievePositions(ctx context.Context, ccy currency.Code, kind string) ([]PositionData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1065,11 +1065,11 @@ func (d *Deribit) WSRetrievePositions(ctx context.Context, ccy currency.Code, ki Kind: kind, } var resp []PositionData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getPositions, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getPositions, input, &resp, true) } // WSRetrieveTransactionLog retrieves transaction logs data through the websocket connection. -func (d *Deribit) WSRetrieveTransactionLog(ctx context.Context, ccy currency.Code, query string, startTime, endTime time.Time, count, continuation int64) (*TransactionsData, error) { +func (e *Exchange) WSRetrieveTransactionLog(ctx context.Context, ccy currency.Code, query string, startTime, endTime time.Time, count, continuation int64) (*TransactionsData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1092,37 +1092,37 @@ func (d *Deribit) WSRetrieveTransactionLog(ctx context.Context, ccy currency.Cod Continuation: continuation, } var resp *TransactionsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTransactionLog, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTransactionLog, input, &resp, true) } // WSRetrieveUserLocks retrieves information about locks on user account through the websocket connection. -func (d *Deribit) WSRetrieveUserLocks(ctx context.Context) ([]UserLock, error) { +func (e *Exchange) WSRetrieveUserLocks(ctx context.Context) ([]UserLock, error) { var resp []UserLock - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserLocks, nil, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserLocks, nil, &resp, true) } // WSListAPIKeys retrieves all the api keys associated with a user account through the websocket connection. -func (d *Deribit) WSListAPIKeys(ctx context.Context, tfa string) ([]APIKeyData, error) { +func (e *Exchange) WSListAPIKeys(ctx context.Context, tfa string) ([]APIKeyData, error) { var resp []APIKeyData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, listAPIKeys, map[string]string{"tfa": tfa}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, listAPIKeys, map[string]string{"tfa": tfa}, &resp, true) } // WsRetrieveCustodyAccounts retrieves user custody accounts -func (d *Deribit) WsRetrieveCustodyAccounts(ctx context.Context, ccy currency.Code) ([]CustodyAccount, error) { +func (e *Exchange) WsRetrieveCustodyAccounts(ctx context.Context, ccy currency.Code) ([]CustodyAccount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp []CustodyAccount - return resp, d.SendWSRequest(ctx, nonMatchingEPL, listCustodyAccounts, &map[string]string{"currency": ccy.String()}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, listCustodyAccounts, &map[string]string{"currency": ccy.String()}, &resp, true) } // WSRemoveAPIKey removes api key vid ID through the websocket connection. -func (d *Deribit) WSRemoveAPIKey(ctx context.Context, id int64) error { +func (e *Exchange) WSRemoveAPIKey(ctx context.Context, id int64) error { if id <= 0 { return fmt.Errorf("%w, invalid api key id", errInvalidID) } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, removeAPIKey, map[string]int64{"id": id}, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, removeAPIKey, map[string]int64{"id": id}, &resp, true) if err != nil { return err } @@ -1133,9 +1133,9 @@ func (d *Deribit) WSRemoveAPIKey(ctx context.Context, id int64) error { } // WSRemoveSubAccount removes a subaccount given its id through the websocket connection. -func (d *Deribit) WSRemoveSubAccount(ctx context.Context, subAccountID int64) error { +func (e *Exchange) WSRemoveSubAccount(ctx context.Context, subAccountID int64) error { var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, removeSubAccount, map[string]int64{"subaccount_id": subAccountID}, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, removeSubAccount, map[string]int64{"subaccount_id": subAccountID}, &resp, true) if err != nil { return err } @@ -1146,12 +1146,12 @@ func (d *Deribit) WSRemoveSubAccount(ctx context.Context, subAccountID int64) er } // WSResetAPIKey sets an announcement as read through the websocket connection. -func (d *Deribit) WSResetAPIKey(ctx context.Context, id int64) error { +func (e *Exchange) WSResetAPIKey(ctx context.Context, id int64) error { if id <= 0 { return fmt.Errorf("%w, invalid announcement id", errInvalidID) } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, resetAPIKey, map[string]int64{"announcement_id": id}, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, resetAPIKey, map[string]int64{"announcement_id": id}, &resp, true) if err != nil { return err } @@ -1162,7 +1162,7 @@ func (d *Deribit) WSResetAPIKey(ctx context.Context, id int64) error { } // WSSetEmailForSubAccount links an email given to the designated subaccount through the websocket connection. -func (d *Deribit) WSSetEmailForSubAccount(ctx context.Context, sid int64, email string) error { +func (e *Exchange) WSSetEmailForSubAccount(ctx context.Context, sid int64, email string) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1177,7 +1177,7 @@ func (d *Deribit) WSSetEmailForSubAccount(ctx context.Context, sid int64, email SID: sid, } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, setEmailForSubAccount, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, setEmailForSubAccount, input, &resp, true) if err != nil { return err } @@ -1188,12 +1188,12 @@ func (d *Deribit) WSSetEmailForSubAccount(ctx context.Context, sid int64, email } // WSSetEmailLanguage sets a requested language for an email through the websocket connection. -func (d *Deribit) WSSetEmailLanguage(ctx context.Context, language string) error { +func (e *Exchange) WSSetEmailLanguage(ctx context.Context, language string) error { if language == "" { return errLanguageIsRequired } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, setEmailLanguage, map[string]string{"language": language}, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, setEmailLanguage, map[string]string{"language": language}, &resp, true) if err != nil { return err } @@ -1206,7 +1206,7 @@ func (d *Deribit) WSSetEmailLanguage(ctx context.Context, language string) error // WsSetSelfTradingConfig configure self trading behavior through the websocket connection. // mode: Self trading prevention behavior. Possible values: 'reject_taker', 'cancel_maker' // extended_to_subaccounts: If value is true trading is prevented between subaccounts of given account -func (d *Deribit) WsSetSelfTradingConfig(ctx context.Context, mode string, extendedToSubaccounts bool) (string, error) { +func (e *Exchange) WsSetSelfTradingConfig(ctx context.Context, mode string, extendedToSubaccounts bool) (string, error) { if mode == "" { return "", errTradeModeIsRequired } @@ -1218,11 +1218,11 @@ func (d *Deribit) WsSetSelfTradingConfig(ctx context.Context, mode string, exten ExtendedToSubAccounts: extendedToSubaccounts, } var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, setSelfTradingConfig, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, setSelfTradingConfig, input, &resp, true) } // WSToggleNotificationsFromSubAccount toggles the notifications from a subaccount specified through the websocket connection. -func (d *Deribit) WSToggleNotificationsFromSubAccount(ctx context.Context, sid int64, state bool) error { +func (e *Exchange) WSToggleNotificationsFromSubAccount(ctx context.Context, sid int64, state bool) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1234,7 +1234,7 @@ func (d *Deribit) WSToggleNotificationsFromSubAccount(ctx context.Context, sid i State: state, } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, toggleNotificationsFromSubAccount, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, toggleNotificationsFromSubAccount, input, &resp, true) if err != nil { return err } @@ -1245,7 +1245,7 @@ func (d *Deribit) WSToggleNotificationsFromSubAccount(ctx context.Context, sid i } // WSTogglePortfolioMargining toggle between SM and PM models through the websocket connection. -func (d *Deribit) WSTogglePortfolioMargining(ctx context.Context, userID int64, enabled, dryRun bool) ([]TogglePortfolioMarginResponse, error) { +func (e *Exchange) WSTogglePortfolioMargining(ctx context.Context, userID int64, enabled, dryRun bool) ([]TogglePortfolioMarginResponse, error) { if userID == 0 { return nil, errUserIDRequired } @@ -1259,11 +1259,11 @@ func (d *Deribit) WSTogglePortfolioMargining(ctx context.Context, userID int64, DryRun: dryRun, } var resp []TogglePortfolioMarginResponse - return resp, d.SendWSRequest(ctx, nonMatchingEPL, togglePortfolioMargining, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, togglePortfolioMargining, input, &resp, true) } // WSToggleSubAccountLogin toggles access for subaccount login through the websocket connection. -func (d *Deribit) WSToggleSubAccountLogin(ctx context.Context, sid int64, state bool) error { +func (e *Exchange) WSToggleSubAccountLogin(ctx context.Context, sid int64, state bool) error { if sid <= 0 { return fmt.Errorf("%w, invalid subaccount user id", errInvalidID) } @@ -1275,7 +1275,7 @@ func (d *Deribit) WSToggleSubAccountLogin(ctx context.Context, sid int64, state State: state, } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, toggleSubAccountLogin, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, toggleSubAccountLogin, input, &resp, true) if err != nil { return err } @@ -1286,7 +1286,7 @@ func (d *Deribit) WSToggleSubAccountLogin(ctx context.Context, sid int64, state } // WSSubmitBuy submits a private buy request through the websocket connection. -func (d *Deribit) WSSubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) WSSubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w parameter is required", common.ErrNilPointer) } @@ -1294,11 +1294,11 @@ func (d *Deribit) WSSubmitBuy(ctx context.Context, arg *OrderBuyAndSellParams) ( return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } var resp *PrivateTradeData - return resp, d.SendWSRequest(ctx, matchingEPL, submitBuy, &arg, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitBuy, &arg, &resp, true) } // WSSubmitSell submits a sell request with the parameters provided through the websocket connection. -func (d *Deribit) WSSubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) WSSubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w parameter is required", common.ErrNilPointer) } @@ -1306,11 +1306,11 @@ func (d *Deribit) WSSubmitSell(ctx context.Context, arg *OrderBuyAndSellParams) return nil, fmt.Errorf("%w, instrument_name is missing", errInvalidInstrumentName) } var resp *PrivateTradeData - return resp, d.SendWSRequest(ctx, matchingEPL, submitSell, &arg, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitSell, &arg, &resp, true) } // WSSubmitEdit submits an edit order request through the websocket connection. -func (d *Deribit) WSSubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) WSSubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, common.ErrNilPointer } @@ -1321,11 +1321,11 @@ func (d *Deribit) WSSubmitEdit(ctx context.Context, arg *OrderBuyAndSellParams) return nil, errInvalidAmount } var resp *PrivateTradeData - return resp, d.SendWSRequest(ctx, matchingEPL, submitEdit, &arg, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitEdit, &arg, &resp, true) } // WSEditOrderByLabel submits an edit order request sorted via label through the websocket connection. -func (d *Deribit) WSEditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { +func (e *Exchange) WSEditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellParams) (*PrivateTradeData, error) { if arg == nil || *arg == (OrderBuyAndSellParams{}) { return nil, fmt.Errorf("%w argument cannot be null", common.ErrNilPointer) } @@ -1336,26 +1336,26 @@ func (d *Deribit) WSEditOrderByLabel(ctx context.Context, arg *OrderBuyAndSellPa return nil, errInvalidAmount } var resp *PrivateTradeData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, editByLabel, &arg, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, editByLabel, &arg, &resp, true) } // WSSubmitCancel sends a request to cancel the order via its orderID through the websocket connection. -func (d *Deribit) WSSubmitCancel(ctx context.Context, orderID string) (*PrivateCancelData, error) { +func (e *Exchange) WSSubmitCancel(ctx context.Context, orderID string) (*PrivateCancelData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } var resp *PrivateCancelData - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancel, map[string]string{"order_id": orderID}, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancel, map[string]string{"order_id": orderID}, &resp, true) } // WSSubmitCancelAll sends a request to cancel all user orders in all currencies and instruments -func (d *Deribit) WSSubmitCancelAll(ctx context.Context, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WSSubmitCancelAll(ctx context.Context, detailed bool) (*MultipleCancelResponse, error) { var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelAll, map[string]bool{"detailed": detailed}, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelAll, map[string]bool{"detailed": detailed}, &resp, true) } // WSSubmitCancelAllByCurrency sends a request to cancel all user orders for the specified currency through the websocket connection. -func (d *Deribit) WSSubmitCancelAllByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WSSubmitCancelAllByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1371,11 +1371,11 @@ func (d *Deribit) WSSubmitCancelAllByCurrency(ctx context.Context, ccy currency. Detailed: detailed, } var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelAllByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelAllByCurrency, input, &resp, true) } // WSSubmitCancelAllByInstrument sends a request to cancel all user orders for the specified instrument through the websocket connection. -func (d *Deribit) WSSubmitCancelAllByInstrument(ctx context.Context, instrument, orderType string, detailed, includeCombos bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WSSubmitCancelAllByInstrument(ctx context.Context, instrument, orderType string, detailed, includeCombos bool) (*MultipleCancelResponse, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1391,12 +1391,12 @@ func (d *Deribit) WSSubmitCancelAllByInstrument(ctx context.Context, instrument, IncludeCombos: includeCombos, } var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelAllByInstrument, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelAllByInstrument, input, &resp, true) } // WsSubmitCancelAllByKind cancels all orders in currency(currencies), optionally filtered by instrument kind and/or order type. // 'kind' Instrument kind. Possible values: 'future', 'option', 'spot', 'future_combo', 'option_combo', 'combo', 'any' -func (d *Deribit) WsSubmitCancelAllByKind(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WsSubmitCancelAllByKind(ctx context.Context, ccy currency.Code, kind, orderType string, detailed bool) (*MultipleCancelResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1412,11 +1412,11 @@ func (d *Deribit) WsSubmitCancelAllByKind(ctx context.Context, ccy currency.Code Detailed: detailed, } var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelAllByKind, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelAllByKind, input, &resp, true) } // WSSubmitCancelByLabel sends a request to cancel all user orders for the specified label through the websocket connection. -func (d *Deribit) WSSubmitCancelByLabel(ctx context.Context, label string, ccy currency.Code, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WSSubmitCancelByLabel(ctx context.Context, label string, ccy currency.Code, detailed bool) (*MultipleCancelResponse, error) { input := &struct { Label string `json:"label"` Currency string `json:"currency,omitempty"` @@ -1427,14 +1427,14 @@ func (d *Deribit) WSSubmitCancelByLabel(ctx context.Context, label string, ccy c Detailed: detailed, } var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelByLabel, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelByLabel, input, &resp, true) } // WSSubmitCancelQuotes cancels quotes based on the provided type. // // possible cancel_type values are delta, 'quote_set_id', 'instrument', 'instrument_kind', 'currency', and 'all' // possible kind values are future 'option', 'spot', 'future_combo', 'option_combo', 'combo', and 'any' -func (d *Deribit) WSSubmitCancelQuotes(ctx context.Context, ccy currency.Code, minDelta, maxDelta float64, cancelType, quoteSetID, instrumentName, kind string, detailed bool) (*MultipleCancelResponse, error) { +func (e *Exchange) WSSubmitCancelQuotes(ctx context.Context, ccy currency.Code, minDelta, maxDelta float64, cancelType, quoteSetID, instrumentName, kind string, detailed bool) (*MultipleCancelResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1461,11 +1461,11 @@ func (d *Deribit) WSSubmitCancelQuotes(ctx context.Context, ccy currency.Code, m QuoteSetID: quoteSetID, } var resp *MultipleCancelResponse - return resp, d.SendWSRequest(ctx, matchingEPL, submitCancelQuotes, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitCancelQuotes, input, &resp, true) } // WSSubmitClosePosition sends a request to cancel all user orders for the specified label through the websocket connection. -func (d *Deribit) WSSubmitClosePosition(ctx context.Context, instrument, orderType string, price float64) (*PrivateTradeData, error) { +func (e *Exchange) WSSubmitClosePosition(ctx context.Context, instrument, orderType string, price float64) (*PrivateTradeData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1479,11 +1479,11 @@ func (d *Deribit) WSSubmitClosePosition(ctx context.Context, instrument, orderTy Price: price, } var resp *PrivateTradeData - return resp, d.SendWSRequest(ctx, matchingEPL, submitClosePosition, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, submitClosePosition, input, &resp, true) } // WSRetrieveMargins sends a request to fetch account margins data through the websocket connection. -func (d *Deribit) WSRetrieveMargins(ctx context.Context, instrument string, amount, price float64) (*MarginsData, error) { +func (e *Exchange) WSRetrieveMargins(ctx context.Context, instrument string, amount, price float64) (*MarginsData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1503,20 +1503,20 @@ func (d *Deribit) WSRetrieveMargins(ctx context.Context, instrument string, amou Price: price, } var resp *MarginsData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getMargins, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getMargins, input, &resp, true) } // WSRetrieveMMPConfig sends a request to fetch the config for MMP of the requested currency through the websocket connection. -func (d *Deribit) WSRetrieveMMPConfig(ctx context.Context, ccy currency.Code) (*MMPConfigData, error) { +func (e *Exchange) WSRetrieveMMPConfig(ctx context.Context, ccy currency.Code) (*MMPConfigData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp *MMPConfigData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getMMPConfig, map[string]currency.Code{"currency": ccy}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getMMPConfig, map[string]currency.Code{"currency": ccy}, &resp, true) } // WSRetrieveOpenOrdersByCurrency retrieves open order by symbol and kind -func (d *Deribit) WSRetrieveOpenOrdersByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOpenOrdersByCurrency(ctx context.Context, ccy currency.Code, kind, orderType string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1530,11 +1530,11 @@ func (d *Deribit) WSRetrieveOpenOrdersByCurrency(ctx context.Context, ccy curren OrderType: orderType, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByCurrency, input, &resp, true) } // WSRetrieveOpenOrdersByLabel retrieves open order by label and currency -func (d *Deribit) WSRetrieveOpenOrdersByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOpenOrdersByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1546,11 +1546,11 @@ func (d *Deribit) WSRetrieveOpenOrdersByLabel(ctx context.Context, ccy currency. Label: label, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByLabel, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByLabel, input, &resp, true) } // WSRetrieveOpenOrdersByInstrument sends a request to fetch open orders data sorted by requested params through the websocket connection. -func (d *Deribit) WSRetrieveOpenOrdersByInstrument(ctx context.Context, instrument, orderType string) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOpenOrdersByInstrument(ctx context.Context, instrument, orderType string) ([]OrderData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1562,11 +1562,11 @@ func (d *Deribit) WSRetrieveOpenOrdersByInstrument(ctx context.Context, instrume Type: orderType, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByInstrument, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOpenOrdersByInstrument, input, &resp, true) } // WSRetrieveOrderHistoryByCurrency sends a request to fetch order history according to given params and currency through the websocket connection. -func (d *Deribit) WSRetrieveOrderHistoryByCurrency(ctx context.Context, ccy currency.Code, kind string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOrderHistoryByCurrency(ctx context.Context, ccy currency.Code, kind string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1586,11 +1586,11 @@ func (d *Deribit) WSRetrieveOrderHistoryByCurrency(ctx context.Context, ccy curr IncludeUnfilled: includeUnfilled, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderHistoryByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderHistoryByCurrency, input, &resp, true) } // WSRetrieveOrderHistoryByInstrument sends a request to fetch order history according to given params and instrument through the websocket connection. -func (d *Deribit) WSRetrieveOrderHistoryByInstrument(ctx context.Context, instrument string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOrderHistoryByInstrument(ctx context.Context, instrument string, count, offset int64, includeOld, includeUnfilled bool) ([]OrderData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1608,29 +1608,29 @@ func (d *Deribit) WSRetrieveOrderHistoryByInstrument(ctx context.Context, instru IncludeUnfilled: includeUnfilled, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderHistoryByInstrument, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderHistoryByInstrument, input, &resp, true) } // WSRetrieveOrderMarginsByID sends a request to fetch order margins data according to their ids through the websocket connection. -func (d *Deribit) WSRetrieveOrderMarginsByID(ctx context.Context, ids []string) ([]OrderData, error) { +func (e *Exchange) WSRetrieveOrderMarginsByID(ctx context.Context, ids []string) ([]OrderData, error) { if len(ids) == 0 { return nil, fmt.Errorf("%w, order ids cannot be empty", errInvalidID) } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderMarginByIDs, map[string][]string{"ids": ids}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderMarginByIDs, map[string][]string{"ids": ids}, &resp, true) } // WSRetrievesOrderState sends a request to fetch order state of the order id provided -func (d *Deribit) WSRetrievesOrderState(ctx context.Context, orderID string) (*OrderData, error) { +func (e *Exchange) WSRetrievesOrderState(ctx context.Context, orderID string) (*OrderData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } var resp *OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderState, map[string]string{"order_id": orderID}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderState, map[string]string{"order_id": orderID}, &resp, true) } // WsRetrieveOrderStateByLabel retrieves an order state by label and currency -func (d *Deribit) WsRetrieveOrderStateByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { +func (e *Exchange) WsRetrieveOrderStateByLabel(ctx context.Context, ccy currency.Code, label string) ([]OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1642,11 +1642,11 @@ func (d *Deribit) WsRetrieveOrderStateByLabel(ctx context.Context, ccy currency. Label: label, } var resp []OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getOrderStateByLabel, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getOrderStateByLabel, input, &resp, true) } // WSRetrieveTriggerOrderHistory sends a request to fetch order state of the order id provided through the websocket connection. -func (d *Deribit) WSRetrieveTriggerOrderHistory(ctx context.Context, ccy currency.Code, instrumentName, continuation string, count int64) (*OrderData, error) { +func (e *Exchange) WSRetrieveTriggerOrderHistory(ctx context.Context, ccy currency.Code, instrumentName, continuation string, count int64) (*OrderData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1662,11 +1662,11 @@ func (d *Deribit) WSRetrieveTriggerOrderHistory(ctx context.Context, ccy currenc Count: count, } var resp *OrderData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getTriggerOrderHistory, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getTriggerOrderHistory, input, &resp, true) } // WSRetrieveUserTradesByCurrency sends a request to fetch user trades sorted by currency through the websocket connection. -func (d *Deribit) WSRetrieveUserTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*UserTradesData, error) { +func (e *Exchange) WSRetrieveUserTradesByCurrency(ctx context.Context, ccy currency.Code, kind, startID, endID, sorting string, count int64, includeOld bool) (*UserTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1688,11 +1688,11 @@ func (d *Deribit) WSRetrieveUserTradesByCurrency(ctx context.Context, ccy curren IncludeOld: includeOld, } var resp *UserTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByCurrency, input, &resp, true) } // WSRetrieveUserTradesByCurrencyAndTime retrieves user trades sorted by currency and time through the websocket connection. -func (d *Deribit) WSRetrieveUserTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { +func (e *Exchange) WSRetrieveUserTradesByCurrencyAndTime(ctx context.Context, ccy currency.Code, kind, sorting string, count int64, startTime, endTime time.Time) (*UserTradesData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1716,11 +1716,11 @@ func (d *Deribit) WSRetrieveUserTradesByCurrencyAndTime(ctx context.Context, ccy input.EndTime = endTime.UnixMilli() } var resp *UserTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByCurrencyAndTime, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByCurrencyAndTime, input, &resp, true) } // WsRetrieveUserTradesByInstrument retrieves user trades sorted by instrument through the websocket connection. -func (d *Deribit) WsRetrieveUserTradesByInstrument(ctx context.Context, instrument, sorting string, startSeq, endSeq, count int64, includeOld bool) (*UserTradesData, error) { +func (e *Exchange) WsRetrieveUserTradesByInstrument(ctx context.Context, instrument, sorting string, startSeq, endSeq, count int64, includeOld bool) (*UserTradesData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1740,11 +1740,11 @@ func (d *Deribit) WsRetrieveUserTradesByInstrument(ctx context.Context, instrume IncludeOld: includeOld, } var resp *UserTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByInstrument, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByInstrument, input, &resp, true) } // WSRetrieveUserTradesByInstrumentAndTime retrieves user trades sorted by instrument and time through the websocket connection. -func (d *Deribit) WSRetrieveUserTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*UserTradesData, error) { +func (e *Exchange) WSRetrieveUserTradesByInstrumentAndTime(ctx context.Context, instrument, sorting string, count int64, includeOld bool, startTime, endTime time.Time) (*UserTradesData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1767,11 +1767,11 @@ func (d *Deribit) WSRetrieveUserTradesByInstrumentAndTime(ctx context.Context, i IncludeOld: includeOld, } var resp *UserTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByInstrumentAndTime, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByInstrumentAndTime, input, &resp, true) } // WSRetrieveUserTradesByOrder retrieves user trades fetched by orderID through the web socket connection. -func (d *Deribit) WSRetrieveUserTradesByOrder(ctx context.Context, orderID, sorting string) (*UserTradesData, error) { +func (e *Exchange) WSRetrieveUserTradesByOrder(ctx context.Context, orderID, sorting string) (*UserTradesData, error) { if orderID == "" { return nil, fmt.Errorf("%w, no order ID specified", errInvalidID) } @@ -1783,16 +1783,16 @@ func (d *Deribit) WSRetrieveUserTradesByOrder(ctx context.Context, orderID, sort Sorting: sorting, } var resp *UserTradesData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByOrder, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getUserTradesByOrder, input, &resp, true) } // WSResetMMP sends a request to reset MMP for a currency provided through the websocket connection. -func (d *Deribit) WSResetMMP(ctx context.Context, ccy currency.Code) error { +func (e *Exchange) WSResetMMP(ctx context.Context, ccy currency.Code) error { if ccy.IsEmpty() { return currency.ErrCurrencyCodeEmpty } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, resetMMP, map[string]currency.Code{"currency": ccy}, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, resetMMP, map[string]currency.Code{"currency": ccy}, &resp, true) if err != nil { return err } @@ -1803,7 +1803,7 @@ func (d *Deribit) WSResetMMP(ctx context.Context, ccy currency.Code) error { } // WSSendRequestForQuote sends RFQ on a given instrument through the websocket connection. -func (d *Deribit) WSSendRequestForQuote(ctx context.Context, instrumentName string, amount float64, side order.Side) error { +func (e *Exchange) WSSendRequestForQuote(ctx context.Context, instrumentName string, amount float64, side order.Side) error { if instrumentName == "" { return errInvalidInstrumentName } @@ -1817,7 +1817,7 @@ func (d *Deribit) WSSendRequestForQuote(ctx context.Context, instrumentName stri Side: side.String(), } var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, sendRFQ, input, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, sendRFQ, input, &resp, true) if err != nil { return err } @@ -1828,13 +1828,13 @@ func (d *Deribit) WSSendRequestForQuote(ctx context.Context, instrumentName stri } // WSSetMMPConfig sends a request to set the given parameter values to the mmp config for the provided currency through the websocket connection. -func (d *Deribit) WSSetMMPConfig(ctx context.Context, ccy currency.Code, interval kline.Interval, frozenTime int64, quantityLimit, deltaLimit float64) error { +func (e *Exchange) WSSetMMPConfig(ctx context.Context, ccy currency.Code, interval kline.Interval, frozenTime int64, quantityLimit, deltaLimit float64) error { if ccy.IsEmpty() { return currency.ErrCurrencyCodeEmpty } params := make(map[string]any) params["currency"] = ccy - intervalString, err := d.GetResolutionFromInterval(interval) + intervalString, err := e.GetResolutionFromInterval(interval) if err != nil { return err } @@ -1847,7 +1847,7 @@ func (d *Deribit) WSSetMMPConfig(ctx context.Context, ccy currency.Code, interva params["delta_limit"] = deltaLimit } var resp string - err = d.SendWSRequest(ctx, nonMatchingEPL, setMMPConfig, params, &resp, true) + err = e.SendWSRequest(ctx, nonMatchingEPL, setMMPConfig, params, &resp, true) if err != nil { return err } @@ -1858,7 +1858,7 @@ func (d *Deribit) WSSetMMPConfig(ctx context.Context, ccy currency.Code, interva } // WSRetrieveSettlementHistoryByInstrument sends a request to fetch settlement history data sorted by instrument through the websocket connection. -func (d *Deribit) WSRetrieveSettlementHistoryByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { +func (e *Exchange) WSRetrieveSettlementHistoryByInstrument(ctx context.Context, instrument, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { if instrument == "" { return nil, errInvalidInstrumentName } @@ -1878,11 +1878,11 @@ func (d *Deribit) WSRetrieveSettlementHistoryByInstrument(ctx context.Context, i input.SearchStartTimestamp = searchStartTimeStamp.UnixMilli() } var resp *PrivateSettlementsHistoryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getSettlementHistoryByInstrument, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getSettlementHistoryByInstrument, input, &resp, true) } // WSRetrieveSettlementHistoryByCurency sends a request to fetch settlement history data sorted by currency through the websocket connection. -func (d *Deribit) WSRetrieveSettlementHistoryByCurency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { +func (e *Exchange) WSRetrieveSettlementHistoryByCurency(ctx context.Context, ccy currency.Code, settlementType, continuation string, count int64, searchStartTimeStamp time.Time) (*PrivateSettlementsHistoryData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1902,12 +1902,12 @@ func (d *Deribit) WSRetrieveSettlementHistoryByCurency(ctx context.Context, ccy input.SearchStartTimestamp = searchStartTimeStamp.UnixMilli() } var resp *PrivateSettlementsHistoryData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getSettlementHistoryByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getSettlementHistoryByCurrency, input, &resp, true) } // WSRetrieveComboIDs Retrieves available combos. // This method can be used to get the list of all combos, or only the list of combos in the given state. -func (d *Deribit) WSRetrieveComboIDs(ctx context.Context, ccy currency.Code, state string) ([]string, error) { +func (e *Exchange) WSRetrieveComboIDs(ctx context.Context, ccy currency.Code, state string) ([]string, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1919,29 +1919,29 @@ func (d *Deribit) WSRetrieveComboIDs(ctx context.Context, ccy currency.Code, sta State: state, } var resp []string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getComboIDs, input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getComboIDs, input, &resp, false) } // WSRetrieveComboDetails retrieves information about a combo through the websocket connection. -func (d *Deribit) WSRetrieveComboDetails(ctx context.Context, comboID string) (*ComboDetail, error) { +func (e *Exchange) WSRetrieveComboDetails(ctx context.Context, comboID string) (*ComboDetail, error) { if comboID == "" { return nil, errInvalidComboID } var resp *ComboDetail - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getComboDetails, map[string]string{"combo_id": comboID}, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getComboDetails, map[string]string{"combo_id": comboID}, &resp, false) } // WSRetrieveCombos retrieves information about active combos through the websocket connection. -func (d *Deribit) WSRetrieveCombos(ctx context.Context, ccy currency.Code) ([]ComboDetail, error) { +func (e *Exchange) WSRetrieveCombos(ctx context.Context, ccy currency.Code) ([]ComboDetail, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp []ComboDetail - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getCombos, map[string]currency.Code{"currency": ccy}, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getCombos, map[string]currency.Code{"currency": ccy}, &resp, false) } // WSCreateCombo verifies and creates a combo book or returns an existing combo matching given trades through the websocket connection. -func (d *Deribit) WSCreateCombo(ctx context.Context, args []ComboParam) (*ComboDetail, error) { +func (e *Exchange) WSCreateCombo(ctx context.Context, args []ComboParam) (*ComboDetail, error) { if len(args) == 0 { return nil, errNoArgumentPassed } @@ -1958,47 +1958,47 @@ func (d *Deribit) WSCreateCombo(ctx context.Context, args []ComboParam) (*ComboD } } var resp *ComboDetail - return resp, d.SendWSRequest(ctx, nonMatchingEPL, createCombos, map[string]any{"trades": args}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, createCombos, map[string]any{"trades": args}, &resp, true) } // WsLogout gracefully close websocket connection, when COD (Cancel On Disconnect) is enabled orders are not cancelled -func (d *Deribit) WsLogout(ctx context.Context, invalidateToken bool) error { +func (e *Exchange) WsLogout(ctx context.Context, invalidateToken bool) error { input := struct { InvalidateToken bool `json:"invalidate_token,omitempty"` }{ InvalidateToken: invalidateToken, } - return d.SendWSRequest(ctx, nonMatchingEPL, "private/logout", input, &struct{}{}, true) + return e.SendWSRequest(ctx, nonMatchingEPL, "private/logout", input, &struct{}{}, true) } // WsEnableCancelOnDisconnect enable Cancel On Disconnect for the connection. // After enabling Cancel On Disconnect all orders created by the connection will be removed when the connection is closed. -func (d *Deribit) WsEnableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { +func (e *Exchange) WsEnableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { input := &struct { Scope string `json:"scope,omitempty"` }{ Scope: scope, } var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "private/enable_cancel_on_disconnect", input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "private/enable_cancel_on_disconnect", input, &resp, true) } // WsDisableCancelOnDisconnect isable Cancel On Disconnect for the connection. // When change is applied for the account, then every newly opened connection will start with inactive Cancel on Disconnect. // scope: possible values are 'connection', 'account' -func (d *Deribit) WsDisableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { +func (e *Exchange) WsDisableCancelOnDisconnect(ctx context.Context, scope string) (string, error) { input := &struct { Scope string `json:"scope,omitempty"` }{ Scope: scope, } var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "private/disable_cancel_on_disconnect", input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "private/disable_cancel_on_disconnect", input, &resp, true) } // SayHello method used to introduce the client software connected to Deribit platform over websocket. // It returns version information -func (d *Deribit) SayHello(ctx context.Context, clientName, clientVersion string) (*Info, error) { +func (e *Exchange) SayHello(ctx context.Context, clientName, clientVersion string) (*Info, error) { if clientName == "" { return nil, errors.New("client name is required") } @@ -2010,24 +2010,24 @@ func (d *Deribit) SayHello(ctx context.Context, clientName, clientVersion string ClientVersion: clientVersion, } var resp *Info - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "public/hello", input, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "public/hello", input, &resp, false) } // WsRetrieveCancelOnDisconnect read current Cancel On Disconnect configuration for the account. // 'scope': Specifies if Cancel On Disconnect change should be applied/checked for the current connection or the account (default - connection) // Scope connection can be used only when working via Websocket. -func (d *Deribit) WsRetrieveCancelOnDisconnect(ctx context.Context, scope string) (*CancelOnDisconnect, error) { +func (e *Exchange) WsRetrieveCancelOnDisconnect(ctx context.Context, scope string) (*CancelOnDisconnect, error) { input := &struct { Scope string `json:"scope,omitempty"` }{ Scope: scope, } var resp *CancelOnDisconnect - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "private/get_cancel_on_disconnect", input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "private/get_cancel_on_disconnect", input, &resp, true) } // WsExchangeToken generates a token for a new subject id. This method can be used to switch between subaccounts. -func (d *Deribit) WsExchangeToken(ctx context.Context, refreshToken string, subjectID int64) (*RefreshTokenInfo, error) { +func (e *Exchange) WsExchangeToken(ctx context.Context, refreshToken string, subjectID int64) (*RefreshTokenInfo, error) { if refreshToken == "" { return nil, errRefreshTokenRequired } @@ -2042,11 +2042,11 @@ func (d *Deribit) WsExchangeToken(ctx context.Context, refreshToken string, subj SubjectID: subjectID, } var resp *RefreshTokenInfo - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "public/exchange_token", input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "public/exchange_token", input, &resp, true) } // WsForkToken generates a token for a new named session. This method can be used only with session scoped tokens. -func (d *Deribit) WsForkToken(ctx context.Context, refreshToken, sessionName string) (*RefreshTokenInfo, error) { +func (e *Exchange) WsForkToken(ctx context.Context, refreshToken, sessionName string) (*RefreshTokenInfo, error) { if refreshToken == "" { return nil, errRefreshTokenRequired } @@ -2061,19 +2061,19 @@ func (d *Deribit) WsForkToken(ctx context.Context, refreshToken, sessionName str SessionName: sessionName, } var resp *RefreshTokenInfo - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "public/fork_token", input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "public/fork_token", input, &resp, true) } // UnsubscribeAll unsubscribe from all the public channels subscribed so far. -func (d *Deribit) UnsubscribeAll(ctx context.Context) (string, error) { +func (e *Exchange) UnsubscribeAll(ctx context.Context) (string, error) { var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "public/unsubscribe_all", nil, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "public/unsubscribe_all", nil, &resp, false) } // UnsubscribeAllPrivateChannels sends an unsubscribe request to cancel all private channels subscriptions -func (d *Deribit) UnsubscribeAllPrivateChannels(ctx context.Context) (string, error) { +func (e *Exchange) UnsubscribeAllPrivateChannels(ctx context.Context) (string, error) { var resp string - return resp, d.SendWSRequest(ctx, nonMatchingEPL, "private/unsubscribe_all", nil, &resp, false) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, "private/unsubscribe_all", nil, &resp, false) } // ------------------------------------------------------------------------------------------------ @@ -2081,7 +2081,7 @@ func (d *Deribit) UnsubscribeAllPrivateChannels(ctx context.Context) (string, er // WSExecuteBlockTrade executes a block trade request // The whole request have to be exact the same as in private/verify_block_trade, only role field should be set appropriately - it basically means that both sides have to agree on the same timestamp, nonce, trades fields and server will assure that role field is different between sides (each party accepted own role). // Using the same timestamp and nonce by both sides in private/verify_block_trade assures that even if unintentionally both sides execute given block trade with valid counterparty_signature, the given block trade will be executed only once -func (d *Deribit) WSExecuteBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { +func (e *Exchange) WSExecuteBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { if nonce == "" { return nil, errMissingNonce } @@ -2106,7 +2106,7 @@ func (d *Deribit) WSExecuteBlockTrade(ctx context.Context, timestampMS time.Time return nil, fmt.Errorf("%w, trade price can't be negative", errInvalidPrice) } } - signature, err := d.WSVerifyBlockTrade(ctx, timestampMS, nonce, role, ccy, trades) + signature, err := e.WSVerifyBlockTrade(ctx, timestampMS, nonce, role, ccy, trades) if err != nil { return nil, err } @@ -2126,11 +2126,11 @@ func (d *Deribit) WSExecuteBlockTrade(ctx context.Context, timestampMS time.Time Currency: ccy.String(), } var resp []BlockTradeResponse - return resp, d.SendWSRequest(ctx, matchingEPL, executeBlockTrades, input, &resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, executeBlockTrades, input, &resp, true) } // WSVerifyBlockTrade verifies and creates block trade signature through the websocket connection. -func (d *Deribit) WSVerifyBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { +func (e *Exchange) WSVerifyBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { if nonce == "" { return "", errMissingNonce } @@ -2175,18 +2175,18 @@ func (d *Deribit) WSVerifyBlockTrade(ctx context.Context, timestampMS time.Time, resp := &struct { Signature string `json:"signature"` }{} - return resp.Signature, d.SendWSRequest(ctx, matchingEPL, verifyBlockTrades, input, &resp, true) + return resp.Signature, e.SendWSRequest(ctx, matchingEPL, verifyBlockTrades, input, &resp, true) } // WsInvalidateBlockTradeSignature user at any time (before the private/execute_block_trade is called) can invalidate its own signature effectively cancelling block trade through the websocket connection. -func (d *Deribit) WsInvalidateBlockTradeSignature(ctx context.Context, signature string) error { +func (e *Exchange) WsInvalidateBlockTradeSignature(ctx context.Context, signature string) error { if signature == "" { return errMissingSignature } params := url.Values{} params.Set("signature", signature) var resp string - err := d.SendWSRequest(ctx, nonMatchingEPL, invalidateBlockTradesSignature, params, &resp, true) + err := e.SendWSRequest(ctx, nonMatchingEPL, invalidateBlockTradesSignature, params, &resp, true) if err != nil { return err } @@ -2197,16 +2197,16 @@ func (d *Deribit) WsInvalidateBlockTradeSignature(ctx context.Context, signature } // WSRetrieveUserBlockTrade returns information about users block trade through the websocket connection. -func (d *Deribit) WSRetrieveUserBlockTrade(ctx context.Context, id string) ([]BlockTradeData, error) { +func (e *Exchange) WSRetrieveUserBlockTrade(ctx context.Context, id string) ([]BlockTradeData, error) { if id == "" { return nil, errMissingBlockTradeID } var resp []BlockTradeData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getBlockTrades, map[string]string{"id": id}, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getBlockTrades, map[string]string{"id": id}, &resp, true) } // WSRetrieveLastBlockTradesByCurrency returns list of last users block trades through the websocket connection. -func (d *Deribit) WSRetrieveLastBlockTradesByCurrency(ctx context.Context, ccy currency.Code, startID, endID string, count int64) ([]BlockTradeData, error) { +func (e *Exchange) WSRetrieveLastBlockTradesByCurrency(ctx context.Context, ccy currency.Code, startID, endID string, count int64) ([]BlockTradeData, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2222,11 +2222,11 @@ func (d *Deribit) WSRetrieveLastBlockTradesByCurrency(ctx context.Context, ccy c Count: count, } var resp []BlockTradeData - return resp, d.SendWSRequest(ctx, nonMatchingEPL, getLastBlockTradesByCurrency, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, getLastBlockTradesByCurrency, input, &resp, true) } // WSMovePositions moves positions from source subaccount to target subaccount through the websocket connection. -func (d *Deribit) WSMovePositions(ctx context.Context, ccy currency.Code, sourceSubAccountUID, targetSubAccountUID int64, trades []BlockTradeParam) ([]BlockTradeMoveResponse, error) { +func (e *Exchange) WSMovePositions(ctx context.Context, ccy currency.Code, sourceSubAccountUID, targetSubAccountUID int64, trades []BlockTradeParam) ([]BlockTradeMoveResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2259,11 +2259,11 @@ func (d *Deribit) WSMovePositions(ctx context.Context, ccy currency.Code, source SourceUID: sourceSubAccountUID, } var resp []BlockTradeMoveResponse - return resp, d.SendWSRequest(ctx, nonMatchingEPL, movePositions, input, &resp, true) + return resp, e.SendWSRequest(ctx, nonMatchingEPL, movePositions, input, &resp, true) } // WsSimulateBlockTrade checks if a block trade can be executed through the websocket -func (d *Deribit) WsSimulateBlockTrade(ctx context.Context, role string, trades []BlockTradeParam) (bool, error) { +func (e *Exchange) WsSimulateBlockTrade(ctx context.Context, role string, trades []BlockTradeParam) (bool, error) { if role != roleMaker && role != roleTaker { return false, errInvalidTradeRole } @@ -2293,23 +2293,23 @@ func (d *Deribit) WsSimulateBlockTrade(ctx context.Context, role string, trades Trades: trades, } var resp bool - return resp, d.SendWSRequest(ctx, matchingEPL, simulateBlockPosition, input, resp, true) + return resp, e.SendWSRequest(ctx, matchingEPL, simulateBlockPosition, input, resp, true) } // SendWSRequest sends a request through the websocket connection. // both authenticated and public endpoints are allowed. -func (d *Deribit) SendWSRequest(ctx context.Context, epl request.EndpointLimit, method string, params, response any, authenticated bool) error { - if authenticated && !d.Websocket.CanUseAuthenticatedEndpoints() { +func (e *Exchange) SendWSRequest(ctx context.Context, epl request.EndpointLimit, method string, params, response any, authenticated bool) error { + if authenticated && !e.Websocket.CanUseAuthenticatedEndpoints() { return errWebsocketConnectionNotAuthenticated } input := &WsRequest{ JSONRPCVersion: rpcVersion, - ID: d.Websocket.Conn.GenerateMessageID(true), + ID: e.Websocket.Conn.GenerateMessageID(true), Method: method, Params: params, } resp := &wsResponse{Result: response} - err := d.sendWsPayload(ctx, epl, input, resp) + err := e.sendWsPayload(ctx, epl, input, resp) if err != nil { return err } @@ -2328,7 +2328,7 @@ func (d *Deribit) SendWSRequest(ctx context.Context, epl request.EndpointLimit, // sendWsPayload handles sending Websocket requests // TODO: Refactor to use rate limiting system -func (d *Deribit) sendWsPayload(ctx context.Context, ep request.EndpointLimit, input *WsRequest, response *wsResponse) error { +func (e *Exchange) sendWsPayload(ctx context.Context, ep request.EndpointLimit, input *WsRequest, response *wsResponse) error { if input == nil { return fmt.Errorf("%w, input can not be ", common.ErrNilPointer) } @@ -2341,16 +2341,16 @@ func (d *Deribit) sendWsPayload(ctx context.Context, ep request.EndpointLimit, i }() for attempt := 1; ; attempt++ { // Initiate a rate limit reservation and sleep on requested endpoint - err := d.Requester.InitiateRateLimit(ctx, ep) + err := e.Requester.InitiateRateLimit(ctx, ep) if err != nil { return fmt.Errorf("failed to rate limit Websocket request: %w", err) } - if d.Verbose { - log.Debugf(log.RequestSys, "%s attempt %d", d.Name, attempt) + if e.Verbose { + log.Debugf(log.RequestSys, "%s attempt %d", e.Name, attempt) } var payload []byte - payload, err = d.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, input.ID, input) + payload, err = e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, input.ID, input) if err != nil { return err } @@ -2368,10 +2368,10 @@ func (d *Deribit) sendWsPayload(ctx context.Context, ep request.EndpointLimit, i return errors.New("deadline would be exceeded by retry") } - if d.Verbose { + if e.Verbose { log.Errorf(log.RequestSys, "%s request has failed. Retrying request in %s, attempt %d", - d.Name, + e.Name, delay, attempt) } diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index cb1d8f84c50..e7f66f818c9 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -50,13 +50,13 @@ const ( exmoRequestRate = 180 ) -// EXMO exchange struct -type EXMO struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with EXMO +type Exchange struct { exchange.Base } // GetTrades returns the trades for a symbol or symbols -func (e *EXMO) GetTrades(ctx context.Context, symbol string) (map[string][]Trades, error) { +func (e *Exchange) GetTrades(ctx context.Context, symbol string) (map[string][]Trades, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string][]Trades) @@ -65,7 +65,7 @@ func (e *EXMO) GetTrades(ctx context.Context, symbol string) (map[string][]Trade } // GetOrderbook returns the orderbook for a symbol or symbols -func (e *EXMO) GetOrderbook(ctx context.Context, symbol string) (map[string]Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, symbol string) (map[string]Orderbook, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string]Orderbook) @@ -74,7 +74,7 @@ func (e *EXMO) GetOrderbook(ctx context.Context, symbol string) (map[string]Orde } // GetTicker returns the ticker for a symbol or symbols -func (e *EXMO) GetTicker(ctx context.Context) (map[string]Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context) (map[string]Ticker, error) { v := url.Values{} result := make(map[string]Ticker) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoTicker) @@ -82,21 +82,21 @@ func (e *EXMO) GetTicker(ctx context.Context) (map[string]Ticker, error) { } // GetPairSettings returns the pair settings for a symbol or symbols -func (e *EXMO) GetPairSettings(ctx context.Context) (map[string]PairSettings, error) { +func (e *Exchange) GetPairSettings(ctx context.Context) (map[string]PairSettings, error) { result := make(map[string]PairSettings) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoPairSettings) return result, e.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &result) } // GetCurrency returns a list of currencies -func (e *EXMO) GetCurrency(ctx context.Context) ([]string, error) { +func (e *Exchange) GetCurrency(ctx context.Context) ([]string, error) { var result []string urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoCurrency) return result, e.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &result) } // GetUserInfo returns the user info -func (e *EXMO) GetUserInfo(ctx context.Context) (UserInfo, error) { +func (e *Exchange) GetUserInfo(ctx context.Context) (UserInfo, error) { var result UserInfo return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoUserInfo, url.Values{}, &result) } @@ -104,7 +104,7 @@ func (e *EXMO) GetUserInfo(ctx context.Context) (UserInfo, error) { // CreateOrder creates an order // Params: pair, quantity, price and type // Type can be buy, sell, market_buy, market_sell, market_buy_total and market_sell_total -func (e *EXMO) CreateOrder(ctx context.Context, pair, orderType string, price, amount float64) (int64, error) { +func (e *Exchange) CreateOrder(ctx context.Context, pair, orderType string, price, amount float64) (int64, error) { type response struct { OrderID int64 `json:"order_id"` Result bool `json:"result"` @@ -122,7 +122,7 @@ func (e *EXMO) CreateOrder(ctx context.Context, pair, orderType string, price, a } // CancelExistingOrder cancels an order by the orderID -func (e *EXMO) CancelExistingOrder(ctx context.Context, orderID int64) error { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) error { v := url.Values{} v.Set("order_id", strconv.FormatInt(orderID, 10)) type response struct { @@ -134,13 +134,13 @@ func (e *EXMO) CancelExistingOrder(ctx context.Context, orderID int64) error { } // GetOpenOrders returns the users open orders -func (e *EXMO) GetOpenOrders(ctx context.Context) (map[string]OpenOrders, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context) (map[string]OpenOrders, error) { result := make(map[string]OpenOrders) return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoOpenOrders, url.Values{}, &result) } // GetUserTrades returns the user trades -func (e *EXMO) GetUserTrades(ctx context.Context, pair, offset, limit string) (map[string][]UserTrades, error) { +func (e *Exchange) GetUserTrades(ctx context.Context, pair, offset, limit string) (map[string][]UserTrades, error) { result := make(map[string][]UserTrades) v := url.Values{} v.Set("pair", pair) @@ -157,7 +157,7 @@ func (e *EXMO) GetUserTrades(ctx context.Context, pair, offset, limit string) (m } // GetCancelledOrders returns a list of cancelled orders -func (e *EXMO) GetCancelledOrders(ctx context.Context, offset, limit string) ([]CancelledOrder, error) { +func (e *Exchange) GetCancelledOrders(ctx context.Context, offset, limit string) ([]CancelledOrder, error) { var result []CancelledOrder v := url.Values{} @@ -173,7 +173,7 @@ func (e *EXMO) GetCancelledOrders(ctx context.Context, offset, limit string) ([] } // GetOrderTrades returns a history of order trade details for the specific orderID -func (e *EXMO) GetOrderTrades(ctx context.Context, orderID int64) (OrderTrades, error) { +func (e *Exchange) GetOrderTrades(ctx context.Context, orderID int64) (OrderTrades, error) { var result OrderTrades v := url.Values{} v.Set("order_id", strconv.FormatInt(orderID, 10)) @@ -183,7 +183,7 @@ func (e *EXMO) GetOrderTrades(ctx context.Context, orderID int64) (OrderTrades, // GetRequiredAmount calculates the sum of buying a certain amount of currency // for the particular currency pair -func (e *EXMO) GetRequiredAmount(ctx context.Context, pair string, amount float64) (RequiredAmount, error) { +func (e *Exchange) GetRequiredAmount(ctx context.Context, pair string, amount float64) (RequiredAmount, error) { v := url.Values{} v.Set("pair", pair) v.Set("quantity", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -192,7 +192,7 @@ func (e *EXMO) GetRequiredAmount(ctx context.Context, pair string, amount float6 } // GetCryptoDepositAddress returns a list of addresses for cryptocurrency deposits -func (e *EXMO) GetCryptoDepositAddress(ctx context.Context) (map[string]string, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context) (map[string]string, error) { var result any err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoDepositAddress, url.Values{}, &result) if err != nil { @@ -218,7 +218,7 @@ func (e *EXMO) GetCryptoDepositAddress(ctx context.Context) (map[string]string, // WithdrawCryptocurrency withdraws a cryptocurrency from the exchange to the desired address // NOTE: This API function is available only after request to their tech support team -func (e *EXMO) WithdrawCryptocurrency(ctx context.Context, currency, address, invoice, transport string, amount float64) (int64, error) { +func (e *Exchange) WithdrawCryptocurrency(ctx context.Context, currency, address, invoice, transport string, amount float64) (int64, error) { type response struct { TaskID int64 `json:"task_id,string"` Result bool `json:"result"` @@ -244,7 +244,7 @@ func (e *EXMO) WithdrawCryptocurrency(ctx context.Context, currency, address, in } // GetWithdrawTXID gets the result of a withdrawal request -func (e *EXMO) GetWithdrawTXID(ctx context.Context, taskID int64) (string, error) { +func (e *Exchange) GetWithdrawTXID(ctx context.Context, taskID int64) (string, error) { type response struct { Status bool `json:"status"` TXID string `json:"txid"` @@ -258,7 +258,7 @@ func (e *EXMO) GetWithdrawTXID(ctx context.Context, taskID int64) (string, error } // ExcodeCreate creates an EXMO coupon -func (e *EXMO) ExcodeCreate(ctx context.Context, currency string, amount float64) (ExcodeCreate, error) { +func (e *Exchange) ExcodeCreate(ctx context.Context, currency string, amount float64) (ExcodeCreate, error) { v := url.Values{} v.Set("currency", currency) v.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -268,7 +268,7 @@ func (e *EXMO) ExcodeCreate(ctx context.Context, currency string, amount float64 } // ExcodeLoad loads an EXMO coupon -func (e *EXMO) ExcodeLoad(ctx context.Context, excode string) (ExcodeLoad, error) { +func (e *Exchange) ExcodeLoad(ctx context.Context, excode string) (ExcodeLoad, error) { v := url.Values{} v.Set("code", excode) @@ -277,7 +277,7 @@ func (e *EXMO) ExcodeLoad(ctx context.Context, excode string) (ExcodeLoad, error } // GetWalletHistory returns the users deposit/withdrawal history -func (e *EXMO) GetWalletHistory(ctx context.Context, date int64) (WalletHistory, error) { +func (e *Exchange) GetWalletHistory(ctx context.Context, date int64) (WalletHistory, error) { v := url.Values{} v.Set("date", strconv.FormatInt(date, 10)) @@ -286,7 +286,7 @@ func (e *EXMO) GetWalletHistory(ctx context.Context, date int64) (WalletHistory, } // SendHTTPRequest sends an unauthenticated HTTP request -func (e *EXMO) SendHTTPRequest(ctx context.Context, endpoint exchange.URL, path string, result any) error { +func (e *Exchange) SendHTTPRequest(ctx context.Context, endpoint exchange.URL, path string, result any) error { urlPath, err := e.API.Endpoints.GetURL(endpoint) if err != nil { return err @@ -306,7 +306,7 @@ func (e *EXMO) SendHTTPRequest(ctx context.Context, endpoint exchange.URL, path } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (e *EXMO) SendAuthenticatedHTTPRequest(ctx context.Context, epath exchange.URL, method, endpoint string, vals url.Values, result any) error { +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, epath exchange.URL, method, endpoint string, vals url.Values, result any) error { creds, err := e.GetCredentials(ctx) if err != nil { return err @@ -349,7 +349,7 @@ func (e *EXMO) SendAuthenticatedHTTPRequest(ctx context.Context, epath exchange. } // GetFee returns an estimate of fee based on type of transaction -func (e *EXMO) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: @@ -509,7 +509,7 @@ func getInternationalBankDepositFee(c currency.Code, amount float64, bankTransac } // GetCryptoPaymentProvidersList returns a map of all the supported cryptocurrency transfer settings -func (e *EXMO) GetCryptoPaymentProvidersList(ctx context.Context) (map[string][]CryptoPaymentProvider, error) { +func (e *Exchange) GetCryptoPaymentProvidersList(ctx context.Context) (map[string][]CryptoPaymentProvider, error) { var result map[string][]CryptoPaymentProvider path := "/v" + exmoAPIVersion + "/" + exmoCryptoPaymentProviderList return result, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) diff --git a/exchanges/exmo/exmo_test.go b/exchanges/exmo/exmo_test.go index f8eee181ee5..eb33264c54f 100644 --- a/exchanges/exmo/exmo_test.go +++ b/exchanges/exmo/exmo_test.go @@ -27,12 +27,12 @@ const ( ) var ( - e *EXMO + e *Exchange testPair = currency.NewBTCUSD().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}) ) func TestMain(m *testing.M) { - e = new(EXMO) + e = new(Exchange) if err := testexch.Setup(e); err != nil { log.Fatalf("EXMO Setup error: %s", err) } diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index 15f123b78fe..3d75861073d 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -30,7 +30,7 @@ import ( ) // SetDefaults sets the basic defaults for exmo -func (e *EXMO) SetDefaults() { +func (e *Exchange) SetDefaults() { e.Name = "EXMO" e.Enabled = true e.Verbose = true @@ -104,7 +104,7 @@ func (e *EXMO) SetDefaults() { } // Setup takes in the supplied exchange configuration details and sets params -func (e *EXMO) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { if err := exch.Validate(); err != nil { return err } @@ -116,7 +116,7 @@ func (e *EXMO) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (e *EXMO) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { if !e.SupportsAsset(a) { return nil, asset.ErrNotSupported } @@ -140,7 +140,7 @@ func (e *EXMO) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.P // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (e *EXMO) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err @@ -153,7 +153,7 @@ func (e *EXMO) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (e *EXMO) UpdateTickers(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { if !e.SupportsAsset(a) { return fmt.Errorf("%w: %v", asset.ErrNotSupported, a) } @@ -195,7 +195,7 @@ func (e *EXMO) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (e *EXMO) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } @@ -203,7 +203,7 @@ func (e *EXMO) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -271,7 +271,7 @@ func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType a // UpdateAccountInfo retrieves balances for all enabled currencies for the // Exmo exchange -func (e *EXMO) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { result, err := e.GetUserInfo(ctx) if err != nil { return account.Holdings{}, err @@ -316,7 +316,7 @@ func (e *EXMO) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (e *EXMO) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { hist, err := e.GetWalletHistory(ctx, 0) if err != nil { return nil, err @@ -339,7 +339,7 @@ func (e *EXMO) GetAccountFundingHistory(ctx context.Context) ([]exchange.Funding } // GetWithdrawalsHistory returns previous withdrawals data -func (e *EXMO) GetWithdrawalsHistory(ctx context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { hist, err := e.GetWalletHistory(ctx, 0) if err != nil { return nil, err @@ -362,7 +362,7 @@ func (e *EXMO) GetWithdrawalsHistory(ctx context.Context, _ currency.Code, _ ass } // GetRecentTrades returns the most recent trades for a currency and asset -func (e *EXMO) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { @@ -404,12 +404,12 @@ func (e *EXMO) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a } // GetHistoricTrades returns historic trade data within the timeframe provided -func (e *EXMO) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (e *EXMO) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -441,12 +441,12 @@ func (e *EXMO) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (e *EXMO) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (e *EXMO) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -460,17 +460,17 @@ func (e *EXMO) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (e *EXMO) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (e *EXMO) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (e *EXMO) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } @@ -491,12 +491,12 @@ func (e *EXMO) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Canc } // GetOrderInfo returns order information based on order ID -func (e *EXMO) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { return nil, common.ErrFunctionNotSupported } // GetDepositAddress returns a deposit address for a specified currency -func (e *EXMO) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { fullAddr, err := e.GetCryptoDepositAddress(ctx) if err != nil { return nil, err @@ -536,7 +536,7 @@ func (e *EXMO) GetDepositAddress(ctx context.Context, cryptocurrency currency.Co // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (e *EXMO) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -554,18 +554,18 @@ func (e *EXMO) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (e *EXMO) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (e *EXMO) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (e *EXMO) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } @@ -577,7 +577,7 @@ func (e *EXMO) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder } // GetActiveOrders retrieves any orders that are active/open -func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -613,7 +613,7 @@ func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -669,24 +669,23 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (e *EXMO) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { _, err := e.UpdateAccountInfo(ctx, assetType) return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (e *EXMO) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (e *EXMO) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (e *EXMO) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { chains, err := e.GetCryptoPaymentProvidersList(ctx) if err != nil { return nil, err @@ -712,22 +711,22 @@ func (e *EXMO) GetAvailableTransferChains(ctx context.Context, cryptocurrency cu } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (e *EXMO) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (e *EXMO) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (e *EXMO) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (e *EXMO) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index 2b596488e44..e373e58b440 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -186,8 +186,8 @@ func timeInForceFromString(tif string) (order.TimeInForce, error) { return order.UnknownTIF, fmt.Errorf("%w: %q", order.ErrUnsupportedTimeInForce, tif) } -// Gateio is the overarching type across this package -type Gateio struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with GateIO +type Exchange struct { Counter common.Counter // Must be first due to alignment requirements exchange.Base wsOBUpdateMgr *wsOBUpdateManager @@ -196,34 +196,34 @@ type Gateio struct { // ***************************************** SubAccounts ******************************** // CreateNewSubAccount creates a new sub-account -func (g *Gateio) CreateNewSubAccount(ctx context.Context, arg SubAccountParams) (*SubAccount, error) { +func (e *Exchange) CreateNewSubAccount(ctx context.Context, arg SubAccountParams) (*SubAccount, error) { if arg.LoginName == "" { return nil, errors.New("login name can not be empty") } var response *SubAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccounts, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccounts, nil, &arg, &response) } // GetSubAccounts retrieves list of sub-accounts for given account -func (g *Gateio) GetSubAccounts(ctx context.Context) ([]SubAccount, error) { +func (e *Exchange) GetSubAccounts(ctx context.Context) ([]SubAccount, error) { var response []SubAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccounts, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccounts, nil, nil, &response) } // GetSingleSubAccount retrieves a single sub-account for given account -func (g *Gateio) GetSingleSubAccount(ctx context.Context, userID string) (*SubAccount, error) { +func (e *Exchange) GetSingleSubAccount(ctx context.Context, userID string) (*SubAccount, error) { if userID == "" { return nil, errors.New("user ID can not be empty") } var response *SubAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccounts+"/"+userID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccounts+"/"+userID, nil, nil, &response) } // CreateAPIKeysOfSubAccount creates a sub-account for the sub-account // // name: Permission name (all permissions will be removed if no value is passed) // >> wallet: wallet, spot: spot/margin, futures: perpetual contract, delivery: delivery, earn: earn, options: options -func (g *Gateio) CreateAPIKeysOfSubAccount(ctx context.Context, arg CreateAPIKeySubAccountParams) (*CreateAPIKeyResponse, error) { +func (e *Exchange) CreateAPIKeysOfSubAccount(ctx context.Context, arg CreateAPIKeySubAccountParams) (*CreateAPIKeyResponse, error) { if arg.SubAccountUserID == 0 { return nil, errInvalidSubAccountUserID } @@ -231,22 +231,22 @@ func (g *Gateio) CreateAPIKeysOfSubAccount(ctx context.Context, arg CreateAPIKey return nil, errors.New("sub-account key information is required") } var resp *CreateAPIKeyResponse - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(arg.SubAccountUserID, 10)+"/keys", nil, &arg, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(arg.SubAccountUserID, 10)+"/keys", nil, &arg, &resp) } // GetAllAPIKeyOfSubAccount list all API Key of the sub-account -func (g *Gateio) GetAllAPIKeyOfSubAccount(ctx context.Context, userID int64) ([]CreateAPIKeyResponse, error) { +func (e *Exchange) GetAllAPIKeyOfSubAccount(ctx context.Context, userID int64) ([]CreateAPIKeyResponse, error) { var resp []CreateAPIKeyResponse - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccountsPath+strconv.FormatInt(userID, 10)+"/keys", nil, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccountsPath+strconv.FormatInt(userID, 10)+"/keys", nil, nil, &resp) } // UpdateAPIKeyOfSubAccount update API key of the sub-account -func (g *Gateio) UpdateAPIKeyOfSubAccount(ctx context.Context, subAccountAPIKey string, arg CreateAPIKeySubAccountParams) error { - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPut, subAccountsPath+strconv.FormatInt(arg.SubAccountUserID, 10)+"/keys/"+subAccountAPIKey, nil, &arg, nil) +func (e *Exchange) UpdateAPIKeyOfSubAccount(ctx context.Context, subAccountAPIKey string, arg CreateAPIKeySubAccountParams) error { + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPut, subAccountsPath+strconv.FormatInt(arg.SubAccountUserID, 10)+"/keys/"+subAccountAPIKey, nil, &arg, nil) } // GetAPIKeyOfSubAccount retrieves the API Key of the sub-account -func (g *Gateio) GetAPIKeyOfSubAccount(ctx context.Context, subAccountUserID int64, apiKey string) (*CreateAPIKeyResponse, error) { +func (e *Exchange) GetAPIKeyOfSubAccount(ctx context.Context, subAccountUserID int64, apiKey string) (*CreateAPIKeyResponse, error) { if subAccountUserID == 0 { return nil, errInvalidSubAccountUserID } @@ -254,60 +254,60 @@ func (g *Gateio) GetAPIKeyOfSubAccount(ctx context.Context, subAccountUserID int return nil, errMissingAPIKey } var resp *CreateAPIKeyResponse - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/keys/"+apiKey, nil, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodGet, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/keys/"+apiKey, nil, nil, &resp) } // LockSubAccount locks the sub-account -func (g *Gateio) LockSubAccount(ctx context.Context, subAccountUserID int64) error { +func (e *Exchange) LockSubAccount(ctx context.Context, subAccountUserID int64) error { if subAccountUserID == 0 { return errInvalidSubAccountUserID } - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/lock", nil, nil, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/lock", nil, nil, nil) } // UnlockSubAccount locks the sub-account -func (g *Gateio) UnlockSubAccount(ctx context.Context, subAccountUserID int64) error { +func (e *Exchange) UnlockSubAccount(ctx context.Context, subAccountUserID int64) error { if subAccountUserID == 0 { return errInvalidSubAccountUserID } - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/unlock", nil, nil, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, subAccountEPL, http.MethodPost, subAccountsPath+strconv.FormatInt(subAccountUserID, 10)+"/unlock", nil, nil, nil) } // ***************************************** Spot ************************************** // ListSpotCurrencies to retrieve detailed list of each currency. -func (g *Gateio) ListSpotCurrencies(ctx context.Context) ([]CurrencyInfo, error) { +func (e *Exchange) ListSpotCurrencies(ctx context.Context) ([]CurrencyInfo, error) { var resp []CurrencyInfo - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrenciesSpotEPL, gateioSpotCurrencies, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrenciesSpotEPL, gateioSpotCurrencies, &resp) } // GetCurrencyDetail details of a specific currency. -func (g *Gateio) GetCurrencyDetail(ctx context.Context, ccy currency.Code) (*CurrencyInfo, error) { +func (e *Exchange) GetCurrencyDetail(ctx context.Context, ccy currency.Code) (*CurrencyInfo, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp *CurrencyInfo - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrenciesSpotEPL, gateioSpotCurrencies+"/"+ccy.String(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrenciesSpotEPL, gateioSpotCurrencies+"/"+ccy.String(), &resp) } // ListSpotCurrencyPairs retrieve all currency pairs supported by the exchange. -func (g *Gateio) ListSpotCurrencyPairs(ctx context.Context) ([]CurrencyPairDetail, error) { +func (e *Exchange) ListSpotCurrencyPairs(ctx context.Context) ([]CurrencyPairDetail, error) { var resp []CurrencyPairDetail - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicListCurrencyPairsSpotEPL, gateioSpotCurrencyPairs, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicListCurrencyPairsSpotEPL, gateioSpotCurrencyPairs, &resp) } // GetCurrencyPairDetail to get details of a specific order for spot/margin accounts. -func (g *Gateio) GetCurrencyPairDetail(ctx context.Context, currencyPair string) (*CurrencyPairDetail, error) { +func (e *Exchange) GetCurrencyPairDetail(ctx context.Context, currencyPair string) (*CurrencyPairDetail, error) { if currencyPair == "" { return nil, currency.ErrCurrencyPairEmpty } var resp *CurrencyPairDetail - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairDetailSpotEPL, gateioSpotCurrencyPairs+"/"+currencyPair, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairDetailSpotEPL, gateioSpotCurrencyPairs+"/"+currencyPair, &resp) } // GetTickers retrieve ticker information // Return only related data if currency_pair is specified; otherwise return all of them -func (g *Gateio) GetTickers(ctx context.Context, currencyPair, timezone string) ([]Ticker, error) { +func (e *Exchange) GetTickers(ctx context.Context, currencyPair, timezone string) ([]Ticker, error) { params := url.Values{} if currencyPair != "" { params.Set("currency_pair", currencyPair) @@ -318,15 +318,15 @@ func (g *Gateio) GetTickers(ctx context.Context, currencyPair, timezone string) params.Set("timezone", timezone) } var tickers []Ticker - return tickers, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersSpotEPL, common.EncodeURLValues(gateioSpotTickers, params), &tickers) + return tickers, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersSpotEPL, common.EncodeURLValues(gateioSpotTickers, params), &tickers) } // GetTicker retrieves a single ticker information for a currency pair. -func (g *Gateio) GetTicker(ctx context.Context, currencyPair, timezone string) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, currencyPair, timezone string) (*Ticker, error) { if currencyPair == "" { return nil, currency.ErrCurrencyPairEmpty } - tickers, err := g.GetTickers(ctx, currencyPair, timezone) + tickers, err := e.GetTickers(ctx, currencyPair, timezone) if err != nil { return nil, err } @@ -357,7 +357,7 @@ func getIntervalString(interval kline.Interval) (string, error) { } // GetIntervalFromString returns a kline.Interval representation of the interval string -func (g *Gateio) GetIntervalFromString(interval string) (kline.Interval, error) { +func (e *Exchange) GetIntervalFromString(interval string) (kline.Interval, error) { switch interval { case "10s": return kline.TenSecond, nil @@ -397,7 +397,7 @@ func (g *Gateio) GetIntervalFromString(interval string) (kline.Interval, error) } // GetOrderbook returns the orderbook data for a suppled currency pair -func (g *Gateio) GetOrderbook(ctx context.Context, pairString, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, pairString, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { if pairString == "" { return nil, currency.ErrCurrencyPairEmpty } @@ -411,14 +411,14 @@ func (g *Gateio) GetOrderbook(ctx context.Context, pairString, interval string, } params.Set("with_id", strconv.FormatBool(withOrderbookID)) var response *OrderbookData - if err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookSpotEPL, common.EncodeURLValues(gateioSpotOrderbook, params), &response); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookSpotEPL, common.EncodeURLValues(gateioSpotOrderbook, params), &response); err != nil { return nil, err } return response.MakeOrderbook(), nil } // GetMarketTrades retrieve market trades -func (g *Gateio) GetMarketTrades(ctx context.Context, pairString currency.Pair, limit uint64, lastID string, reverse bool, from, to time.Time, page uint64) ([]Trade, error) { +func (e *Exchange) GetMarketTrades(ctx context.Context, pairString currency.Pair, limit uint64, lastID string, reverse bool, from, to time.Time, page uint64) ([]Trade, error) { params := url.Values{} if pairString.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty @@ -443,11 +443,11 @@ func (g *Gateio) GetMarketTrades(ctx context.Context, pairString currency.Pair, params.Set("page", strconv.FormatUint(page, 10)) } var response []Trade - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicMarketTradesSpotEPL, common.EncodeURLValues(gateioSpotMarketTrades, params), &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicMarketTradesSpotEPL, common.EncodeURLValues(gateioSpotMarketTrades, params), &response) } // GetCandlesticks retrieves market candlesticks. -func (g *Gateio) GetCandlesticks(ctx context.Context, currencyPair currency.Pair, limit uint64, from, to time.Time, interval kline.Interval) ([]Candlestick, error) { +func (e *Exchange) GetCandlesticks(ctx context.Context, currencyPair currency.Pair, limit uint64, from, to time.Time, interval kline.Interval) ([]Candlestick, error) { params := url.Values{} if currencyPair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty @@ -472,43 +472,43 @@ func (g *Gateio) GetCandlesticks(ctx context.Context, currencyPair currency.Pair params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var candles []Candlestick - return candles, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleStickSpotEPL, common.EncodeURLValues(gateioSpotCandlesticks, params), &candles) + return candles, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleStickSpotEPL, common.EncodeURLValues(gateioSpotCandlesticks, params), &candles) } // GetTradingFeeRatio retrieves user trading fee rates -func (g *Gateio) GetTradingFeeRatio(ctx context.Context, currencyPair currency.Pair) (*SpotTradingFeeRate, error) { +func (e *Exchange) GetTradingFeeRatio(ctx context.Context, currencyPair currency.Pair) (*SpotTradingFeeRate, error) { params := url.Values{} if currencyPair.IsPopulated() { // specify a currency pair to retrieve precise fee rate params.Set("currency_pair", currencyPair.String()) } var response *SpotTradingFeeRate - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotTradingFeeEPL, http.MethodGet, gateioSpotFeeRate, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotTradingFeeEPL, http.MethodGet, gateioSpotFeeRate, params, nil, &response) } // GetSpotAccounts retrieves spot account. -func (g *Gateio) GetSpotAccounts(ctx context.Context, ccy currency.Code) ([]SpotAccount, error) { +func (e *Exchange) GetSpotAccounts(ctx context.Context, ccy currency.Code) ([]SpotAccount, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var response []SpotAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, gateioSpotAccounts, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, gateioSpotAccounts, params, nil, &response) } // GetUnifiedAccount retrieves unified account. -func (g *Gateio) GetUnifiedAccount(ctx context.Context, ccy currency.Code) (*UnifiedUserAccount, error) { +func (e *Exchange) GetUnifiedAccount(ctx context.Context, ccy currency.Code) (*UnifiedUserAccount, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var response UnifiedUserAccount - return &response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUnifiedSpotEPL, http.MethodGet, gateioUnifiedAccounts, params, nil, &response) + return &response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUnifiedSpotEPL, http.MethodGet, gateioUnifiedAccounts, params, nil, &response) } // CreateBatchOrders Create a batch of orders Batch orders requirements: custom order field text is required At most 4 currency pairs, // maximum 10 orders each, are allowed in one request No mixture of spot orders and margin orders, i.e. account must be identical for all orders -func (g *Gateio) CreateBatchOrders(ctx context.Context, args []CreateOrderRequest) ([]SpotOrder, error) { +func (e *Exchange) CreateBatchOrders(ctx context.Context, args []CreateOrderRequest) ([]SpotOrder, error) { if len(args) > 10 { return nil, fmt.Errorf("%w only 10 orders are canceled at once", errMultipleOrders) } @@ -539,14 +539,14 @@ func (g *Gateio) CreateBatchOrders(ctx context.Context, args []CreateOrderReques } } var response []SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotBatchOrdersEPL, http.MethodPost, gateioSpotBatchOrders, nil, &args, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotBatchOrdersEPL, http.MethodPost, gateioSpotBatchOrders, nil, &args, &response) } // GetSpotOpenOrders retrieves all open orders // List open orders in all currency pairs. // Note that pagination parameters affect record number in each currency pair's open order list. No pagination is applied to the number of currency pairs returned. All currency pairs with open orders will be returned. // Spot and margin orders are returned by default. To list cross margin orders, account must be set to cross_margin -func (g *Gateio) GetSpotOpenOrders(ctx context.Context, page, limit uint64, isCrossMargin bool) ([]SpotOrdersDetail, error) { +func (e *Exchange) GetSpotOpenOrders(ctx context.Context, page, limit uint64, isCrossMargin bool) ([]SpotOrdersDetail, error) { params := url.Values{} if page > 0 { params.Set("page", strconv.FormatUint(page, 10)) @@ -558,11 +558,11 @@ func (g *Gateio) GetSpotOpenOrders(ctx context.Context, page, limit uint64, isCr params.Set("account", asset.CrossMargin.String()) } var response []SpotOrdersDetail - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOpenOrdersEPL, http.MethodGet, gateioSpotOpenOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOpenOrdersEPL, http.MethodGet, gateioSpotOpenOrders, params, nil, &response) } // SpotClosePositionWhenCrossCurrencyDisabled set close position when cross-currency is disabled -func (g *Gateio) SpotClosePositionWhenCrossCurrencyDisabled(ctx context.Context, arg *ClosePositionRequestParam) (*SpotOrder, error) { +func (e *Exchange) SpotClosePositionWhenCrossCurrencyDisabled(ctx context.Context, arg *ClosePositionRequestParam) (*SpotOrder, error) { if arg == nil { return nil, errNilArgument } @@ -576,12 +576,12 @@ func (g *Gateio) SpotClosePositionWhenCrossCurrencyDisabled(ctx context.Context, return nil, errInvalidPrice } var response *SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotClosePositionEPL, http.MethodPost, gateioSpotClosePositionWhenCrossCurrencyDisabledPath, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotClosePositionEPL, http.MethodPost, gateioSpotClosePositionWhenCrossCurrencyDisabledPath, nil, &arg, &response) } // PlaceSpotOrder creates a spot order you can place orders with spot, margin or cross margin account through setting the accountfield. // It defaults to spot, which means spot account is used to place orders. -func (g *Gateio) PlaceSpotOrder(ctx context.Context, arg *CreateOrderRequest) (*SpotOrder, error) { +func (e *Exchange) PlaceSpotOrder(ctx context.Context, arg *CreateOrderRequest) (*SpotOrder, error) { if arg == nil { return nil, errNilArgument } @@ -604,11 +604,11 @@ func (g *Gateio) PlaceSpotOrder(ctx context.Context, arg *CreateOrderRequest) (* return nil, errInvalidPrice } var response *SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotPlaceOrderEPL, http.MethodPost, gateioSpotOrders, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotPlaceOrderEPL, http.MethodPost, gateioSpotOrders, nil, &arg, &response) } // GetSpotOrders retrieves spot orders. -func (g *Gateio) GetSpotOrders(ctx context.Context, currencyPair currency.Pair, status string, page, limit uint64) ([]SpotOrder, error) { +func (e *Exchange) GetSpotOrders(ctx context.Context, currencyPair currency.Pair, status string, page, limit uint64) ([]SpotOrder, error) { if currencyPair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -624,11 +624,11 @@ func (g *Gateio) GetSpotOrders(ctx context.Context, currencyPair currency.Pair, params.Set("limit", strconv.FormatUint(limit, 10)) } var response []SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOrdersEPL, http.MethodGet, gateioSpotOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOrdersEPL, http.MethodGet, gateioSpotOrders, params, nil, &response) } // CancelAllOpenOrdersSpecifiedCurrencyPair cancel all open orders in specified currency pair -func (g *Gateio) CancelAllOpenOrdersSpecifiedCurrencyPair(ctx context.Context, currencyPair currency.Pair, side order.Side, account asset.Item) ([]SpotOrder, error) { +func (e *Exchange) CancelAllOpenOrdersSpecifiedCurrencyPair(ctx context.Context, currencyPair currency.Pair, side order.Side, account asset.Item) ([]SpotOrder, error) { if currencyPair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -641,12 +641,12 @@ func (g *Gateio) CancelAllOpenOrdersSpecifiedCurrencyPair(ctx context.Context, c params.Set("account", account.String()) } var response []SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelAllOpenOrdersEPL, http.MethodDelete, gateioSpotOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelAllOpenOrdersEPL, http.MethodDelete, gateioSpotOrders, params, nil, &response) } // CancelBatchOrdersWithIDList cancels batch orders specifying the order ID and currency pair information // Multiple currency pairs can be specified, but maximum 20 orders are allowed per request -func (g *Gateio) CancelBatchOrdersWithIDList(ctx context.Context, args []CancelOrderByIDParam) ([]CancelOrderByIDResponse, error) { +func (e *Exchange) CancelBatchOrdersWithIDList(ctx context.Context, args []CancelOrderByIDParam) ([]CancelOrderByIDResponse, error) { var response []CancelOrderByIDResponse if len(args) == 0 { return nil, errNoValidParameterPassed @@ -658,11 +658,11 @@ func (g *Gateio) CancelBatchOrdersWithIDList(ctx context.Context, args []CancelO return nil, errors.New("currency pair and order ID are required") } } - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelBatchOrdersEPL, http.MethodPost, gateioSpotCancelBatchOrders, nil, &args, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelBatchOrdersEPL, http.MethodPost, gateioSpotCancelBatchOrders, nil, &args, &response) } // GetSpotOrder retrieves a single spot order using the order id and currency pair information. -func (g *Gateio) GetSpotOrder(ctx context.Context, orderID string, currencyPair currency.Pair, account asset.Item) (*SpotOrder, error) { +func (e *Exchange) GetSpotOrder(ctx context.Context, orderID string, currencyPair currency.Pair, account asset.Item) (*SpotOrder, error) { if orderID == "" { return nil, errInvalidOrderID } @@ -675,14 +675,14 @@ func (g *Gateio) GetSpotOrder(ctx context.Context, orderID string, currencyPair params.Set("account", accountType) } var response *SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOrderEPL, http.MethodGet, gateioSpotOrders+"/"+orderID, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetOrderEPL, http.MethodGet, gateioSpotOrders+"/"+orderID, params, nil, &response) } // AmendSpotOrder amend an order // By default, the orders of spot and margin account are updated. // If you need to modify orders of the cross-margin account, you must specify account as cross_margin. // For portfolio margin account, only cross_margin account is supported. -func (g *Gateio) AmendSpotOrder(ctx context.Context, orderID string, currencyPair currency.Pair, isCrossMarginAccount bool, arg *PriceAndAmount) (*SpotOrder, error) { +func (e *Exchange) AmendSpotOrder(ctx context.Context, orderID string, currencyPair currency.Pair, isCrossMarginAccount bool, arg *PriceAndAmount) (*SpotOrder, error) { if arg == nil { return nil, errNilArgument } @@ -701,13 +701,13 @@ func (g *Gateio) AmendSpotOrder(ctx context.Context, orderID string, currencyPai return nil, errors.New("only can chose one of amount or price") } var resp *SpotOrder - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAmendOrderEPL, http.MethodPatch, gateioSpotOrders+"/"+orderID, params, arg, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAmendOrderEPL, http.MethodPatch, gateioSpotOrders+"/"+orderID, params, arg, &resp) } // CancelSingleSpotOrder cancels a single order // Spot and margin orders are cancelled by default. // If trying to cancel cross margin orders or portfolio margin account are used, account must be set to cross_margin -func (g *Gateio) CancelSingleSpotOrder(ctx context.Context, orderID, currencyPair string, isCrossMarginAccount bool) (*SpotOrder, error) { +func (e *Exchange) CancelSingleSpotOrder(ctx context.Context, orderID, currencyPair string, isCrossMarginAccount bool) (*SpotOrder, error) { if orderID == "" { return nil, errInvalidOrderID } @@ -720,11 +720,11 @@ func (g *Gateio) CancelSingleSpotOrder(ctx context.Context, orderID, currencyPai params.Set("account", asset.CrossMargin.String()) } var response *SpotOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelSingleOrderEPL, http.MethodDelete, gateioSpotOrders+"/"+orderID, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelSingleOrderEPL, http.MethodDelete, gateioSpotOrders+"/"+orderID, params, nil, &response) } // GetMySpotTradingHistory retrieves personal trading history -func (g *Gateio) GetMySpotTradingHistory(ctx context.Context, p currency.Pair, orderID string, page, limit uint64, crossMargin bool, from, to time.Time) ([]SpotPersonalTradeHistory, error) { +func (e *Exchange) GetMySpotTradingHistory(ctx context.Context, p currency.Pair, orderID string, page, limit uint64, crossMargin bool, from, to time.Time) ([]SpotPersonalTradeHistory, error) { params := url.Values{} if p.IsPopulated() { params.Set("currency_pair", p.String()) @@ -748,15 +748,15 @@ func (g *Gateio) GetMySpotTradingHistory(ctx context.Context, p currency.Pair, o params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var response []SpotPersonalTradeHistory - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotTradingHistoryEPL, http.MethodGet, gateioSpotMyTrades, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotTradingHistoryEPL, http.MethodGet, gateioSpotMyTrades, params, nil, &response) } // GetServerTime retrieves current server time -func (g *Gateio) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { var resp struct { ServerTime types.Time `json:"server_time"` } - if err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicGetServerTimeEPL, gateioSpotServerTime, &resp); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicGetServerTimeEPL, gateioSpotServerTime, &resp); err != nil { return time.Time{}, err } return resp.ServerTime.Time(), nil @@ -765,16 +765,16 @@ func (g *Gateio) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, er // CountdownCancelorders Countdown cancel orders // When the timeout set by the user is reached, if there is no cancel or set a new countdown, the related pending orders will be automatically cancelled. // This endpoint can be called repeatedly to set a new countdown or cancel the countdown. -func (g *Gateio) CountdownCancelorders(ctx context.Context, arg CountdownCancelOrderParam) (*TriggerTimeResponse, error) { +func (e *Exchange) CountdownCancelorders(ctx context.Context, arg CountdownCancelOrderParam) (*TriggerTimeResponse, error) { if arg.Timeout <= 0 { return nil, errInvalidCountdown } var response *TriggerTimeResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCountdownCancelEPL, http.MethodPost, gateioSpotAllCountdown, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCountdownCancelEPL, http.MethodPost, gateioSpotAllCountdown, nil, &arg, &response) } // CreatePriceTriggeredOrder create a price-triggered order -func (g *Gateio) CreatePriceTriggeredOrder(ctx context.Context, arg *PriceTriggeredOrderParam) (*OrderID, error) { +func (e *Exchange) CreatePriceTriggeredOrder(ctx context.Context, arg *PriceTriggeredOrderParam) (*OrderID, error) { if arg == nil { return nil, errNilArgument } @@ -812,11 +812,11 @@ func (g *Gateio) CreatePriceTriggeredOrder(ctx context.Context, arg *PriceTrigge arg.Put.Account = "normal" } var response *OrderID - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCreateTriggerOrderEPL, http.MethodPost, gateioSpotPriceOrders, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCreateTriggerOrderEPL, http.MethodPost, gateioSpotPriceOrders, nil, &arg, &response) } // GetPriceTriggeredOrderList retrieves price orders created with an order detail and trigger price information. -func (g *Gateio) GetPriceTriggeredOrderList(ctx context.Context, status string, market currency.Pair, account asset.Item, offset, limit uint64) ([]SpotPriceTriggeredOrder, error) { +func (e *Exchange) GetPriceTriggeredOrderList(ctx context.Context, status string, market currency.Pair, account asset.Item, offset, limit uint64) ([]SpotPriceTriggeredOrder, error) { if status != statusOpen && status != statusFinished { return nil, fmt.Errorf("%w status %s", errInvalidOrderStatus, status) } @@ -835,11 +835,11 @@ func (g *Gateio) GetPriceTriggeredOrderList(ctx context.Context, status string, params.Set("offset", strconv.FormatUint(offset, 10)) } var response []SpotPriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetTriggerOrderListEPL, http.MethodGet, gateioSpotPriceOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetTriggerOrderListEPL, http.MethodGet, gateioSpotPriceOrders, params, nil, &response) } // CancelMultipleSpotOpenOrders deletes price triggered orders. -func (g *Gateio) CancelMultipleSpotOpenOrders(ctx context.Context, currencyPair currency.Pair, account asset.Item) ([]SpotPriceTriggeredOrder, error) { +func (e *Exchange) CancelMultipleSpotOpenOrders(ctx context.Context, currencyPair currency.Pair, account asset.Item) ([]SpotPriceTriggeredOrder, error) { params := url.Values{} if currencyPair.IsPopulated() { params.Set("market", currencyPair.String()) @@ -853,29 +853,29 @@ func (g *Gateio) CancelMultipleSpotOpenOrders(ctx context.Context, currencyPair params.Set("account", account.String()) } var response []SpotPriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelTriggerOrdersEPL, http.MethodDelete, gateioSpotPriceOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelTriggerOrdersEPL, http.MethodDelete, gateioSpotPriceOrders, params, nil, &response) } // GetSinglePriceTriggeredOrder get a single order -func (g *Gateio) GetSinglePriceTriggeredOrder(ctx context.Context, orderID string) (*SpotPriceTriggeredOrder, error) { +func (e *Exchange) GetSinglePriceTriggeredOrder(ctx context.Context, orderID string) (*SpotPriceTriggeredOrder, error) { if orderID == "" { return nil, errInvalidOrderID } var response *SpotPriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetTriggerOrderEPL, http.MethodGet, gateioSpotPriceOrders+"/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotGetTriggerOrderEPL, http.MethodGet, gateioSpotPriceOrders+"/"+orderID, nil, nil, &response) } // CancelPriceTriggeredOrder cancel a price-triggered order -func (g *Gateio) CancelPriceTriggeredOrder(ctx context.Context, orderID string) (*SpotPriceTriggeredOrder, error) { +func (e *Exchange) CancelPriceTriggeredOrder(ctx context.Context, orderID string) (*SpotPriceTriggeredOrder, error) { if orderID == "" { return nil, errInvalidOrderID } var response *SpotPriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelTriggerOrderEPL, http.MethodGet, gateioSpotPriceOrders+"/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotCancelTriggerOrderEPL, http.MethodGet, gateioSpotPriceOrders+"/"+orderID, nil, nil, &response) } // GenerateSignature returns hash for authenticated requests -func (g *Gateio) GenerateSignature(secret, method, path, query string, body any, dtime time.Time) (string, error) { +func (e *Exchange) GenerateSignature(secret, method, path, query string, body any, dtime time.Time) (string, error) { rawQuery, err := url.QueryUnescape(query) if err != nil { return "", err @@ -900,17 +900,17 @@ func (g *Gateio) GenerateSignature(secret, method, path, query string, body any, // SendAuthenticatedHTTPRequest sends authenticated requests to the Gateio API // To use this you must setup an APIKey and APISecret from the exchange -func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, method, endpoint string, param url.Values, data, result any) error { - creds, err := g.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, method, endpoint string, param url.Values, data, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := g.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } var intermediary json.RawMessage - err = g.SendPayload(ctx, epl, func() (*request.Item, error) { + err = e.SendPayload(ctx, epl, func() (*request.Item, error) { headers := make(map[string]string) urlPath := endpoint timestamp := time.Now() @@ -919,7 +919,7 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U paramValue = param.Encode() } var sig string - sig, err = g.GenerateSignature(creds.Secret, method, "/"+gateioAPIVersion+endpoint, paramValue, data, timestamp) + sig, err = e.GenerateSignature(creds.Secret, method, "/"+gateioAPIVersion+endpoint, paramValue, data, timestamp) if err != nil { return nil, err } @@ -947,9 +947,9 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U Headers: headers, Body: strings.NewReader(payload), Result: &intermediary, - Verbose: g.Verbose, - HTTPDebugging: g.HTTPDebugging, - HTTPRecording: g.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -963,7 +963,7 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U if err := json.Unmarshal(intermediary, &errCap); err == nil && errCap.Code != "" { return fmt.Errorf("%s auth request error, code: %s message: %s", - g.Name, + e.Name, errCap.Label, errCap.Message) } @@ -974,8 +974,8 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U } // SendHTTPRequest sends an unauthenticated HTTP request -func (g *Gateio) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, path string, result any) error { - endpoint, err := g.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl request.EndpointLimit, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -983,11 +983,11 @@ func (g *Gateio) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl reque Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: g.Verbose, - HTTPDebugging: g.HTTPDebugging, - HTTPRecording: g.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return g.SendPayload(ctx, epl, func() (*request.Item, error) { + return e.SendPayload(ctx, epl, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } @@ -995,7 +995,7 @@ func (g *Gateio) SendHTTPRequest(ctx context.Context, ep exchange.URL, epl reque // *********************************** Withdrawals ****************************** // WithdrawCurrency to withdraw a currency. -func (g *Gateio) WithdrawCurrency(ctx context.Context, arg WithdrawalRequestParam) (*WithdrawalResponse, error) { +func (e *Exchange) WithdrawCurrency(ctx context.Context, arg WithdrawalRequestParam) (*WithdrawalResponse, error) { if arg.Amount <= 0 { return nil, fmt.Errorf("%w currency amount must be greater than zero", errInvalidAmount) } @@ -1006,44 +1006,44 @@ func (g *Gateio) WithdrawCurrency(ctx context.Context, arg WithdrawalRequestPara return nil, errors.New("name of the chain used for withdrawal must be specified") } var response *WithdrawalResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawEPL, http.MethodPost, withdrawal, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawEPL, http.MethodPost, withdrawal, nil, &arg, &response) } // CancelWithdrawalWithSpecifiedID cancels withdrawal with specified ID. -func (g *Gateio) CancelWithdrawalWithSpecifiedID(ctx context.Context, withdrawalID string) (*WithdrawalResponse, error) { +func (e *Exchange) CancelWithdrawalWithSpecifiedID(ctx context.Context, withdrawalID string) (*WithdrawalResponse, error) { if withdrawalID == "" { return nil, errMissingWithdrawalID } var response *WithdrawalResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletCancelWithdrawEPL, http.MethodDelete, withdrawal+"/"+withdrawalID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletCancelWithdrawEPL, http.MethodDelete, withdrawal+"/"+withdrawalID, nil, nil, &response) } // *********************************** Wallet *********************************** // ListCurrencyChain retrieves a list of currency chain name -func (g *Gateio) ListCurrencyChain(ctx context.Context, ccy currency.Code) ([]CurrencyChain, error) { +func (e *Exchange) ListCurrencyChain(ctx context.Context, ccy currency.Code) ([]CurrencyChain, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp []CurrencyChain - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicListCurrencyChainEPL, common.EncodeURLValues(walletCurrencyChain, params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicListCurrencyChainEPL, common.EncodeURLValues(walletCurrencyChain, params), &resp) } // GenerateCurrencyDepositAddress generate currency deposit address -func (g *Gateio) GenerateCurrencyDepositAddress(ctx context.Context, ccy currency.Code) (*CurrencyDepositAddressInfo, error) { +func (e *Exchange) GenerateCurrencyDepositAddress(ctx context.Context, ccy currency.Code) (*CurrencyDepositAddressInfo, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var response *CurrencyDepositAddressInfo - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletDepositAddressEPL, http.MethodGet, walletDepositAddress, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletDepositAddressEPL, http.MethodGet, walletDepositAddress, params, nil, &response) } // GetWithdrawalRecords retrieves withdrawal records. Record time range cannot exceed 30 days -func (g *Gateio) GetWithdrawalRecords(ctx context.Context, ccy currency.Code, from, to time.Time, offset, limit uint64) ([]WithdrawalResponse, error) { +func (e *Exchange) GetWithdrawalRecords(ctx context.Context, ccy currency.Code, from, to time.Time, offset, limit uint64) ([]WithdrawalResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1063,11 +1063,11 @@ func (g *Gateio) GetWithdrawalRecords(ctx context.Context, ccy currency.Code, fr } } var withdrawals []WithdrawalResponse - return withdrawals, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawalRecordsEPL, http.MethodGet, walletWithdrawals, params, nil, &withdrawals) + return withdrawals, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawalRecordsEPL, http.MethodGet, walletWithdrawals, params, nil, &withdrawals) } // GetDepositRecords retrieves deposit records. Record time range cannot exceed 30 days -func (g *Gateio) GetDepositRecords(ctx context.Context, ccy currency.Code, from, to time.Time, offset, limit uint64) ([]DepositRecord, error) { +func (e *Exchange) GetDepositRecords(ctx context.Context, ccy currency.Code, from, to time.Time, offset, limit uint64) ([]DepositRecord, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1085,13 +1085,13 @@ func (g *Gateio) GetDepositRecords(ctx context.Context, ccy currency.Code, from, } } var depositHistories []DepositRecord - return depositHistories, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletDepositRecordsEPL, http.MethodGet, walletDeposits, params, nil, &depositHistories) + return depositHistories, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletDepositRecordsEPL, http.MethodGet, walletDeposits, params, nil, &depositHistories) } // TransferCurrency Transfer between different accounts. Currently support transfers between the following: // spot - margin, spot - futures(perpetual), spot - delivery // spot - cross margin, spot - options -func (g *Gateio) TransferCurrency(ctx context.Context, arg *TransferCurrencyParam) (*TransactionIDResponse, error) { +func (e *Exchange) TransferCurrency(ctx context.Context, arg *TransferCurrencyParam) (*TransactionIDResponse, error) { if arg == nil { return nil, errNilArgument } @@ -1117,10 +1117,10 @@ func (g *Gateio) TransferCurrency(ctx context.Context, arg *TransferCurrencyPara return nil, errInvalidAmount } var response *TransactionIDResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTransferCurrencyEPL, http.MethodPost, walletTransfer, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTransferCurrencyEPL, http.MethodPost, walletTransfer, nil, &arg, &response) } -func (g *Gateio) assetTypeToString(acc asset.Item) string { +func (e *Exchange) assetTypeToString(acc asset.Item) string { if acc == asset.Options { return "options" } @@ -1129,7 +1129,7 @@ func (g *Gateio) assetTypeToString(acc asset.Item) string { // SubAccountTransfer to transfer between main and sub accounts // Support transferring with sub user's spot or futures account. Note that only main user's spot account is used no matter which sub user's account is operated. -func (g *Gateio) SubAccountTransfer(ctx context.Context, arg SubAccountTransferParam) error { +func (e *Exchange) SubAccountTransfer(ctx context.Context, arg SubAccountTransferParam) error { if arg.Currency.IsEmpty() { return currency.ErrCurrencyCodeEmpty } @@ -1148,13 +1148,13 @@ func (g *Gateio) SubAccountTransfer(ctx context.Context, arg SubAccountTransferP default: return fmt.Errorf("%w %q for SubAccountTransfer; Supported: [spot, futures, delivery]", asset.ErrNotSupported, arg.SubAccountType) } - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountTransferEPL, http.MethodPost, walletSubAccountTransfer, nil, &arg, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountTransferEPL, http.MethodPost, walletSubAccountTransfer, nil, &arg, nil) } // GetSubAccountTransferHistory retrieve transfer records between main and sub accounts. // retrieve transfer records between main and sub accounts. Record time range cannot exceed 30 days // Note: only records after 2020-04-10 can be retrieved -func (g *Gateio) GetSubAccountTransferHistory(ctx context.Context, subAccountUserID string, from, to time.Time, offset, limit uint64) ([]SubAccountTransferResponse, error) { +func (e *Exchange) GetSubAccountTransferHistory(ctx context.Context, subAccountUserID string, from, to time.Time, offset, limit uint64) ([]SubAccountTransferResponse, error) { params := url.Values{} if subAccountUserID != "" { params.Set("sub_uid", subAccountUserID) @@ -1176,11 +1176,11 @@ func (g *Gateio) GetSubAccountTransferHistory(ctx context.Context, subAccountUse params.Set("limit", strconv.FormatUint(limit, 10)) } var response []SubAccountTransferResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountTransferHistoryEPL, http.MethodGet, walletSubAccountTransfer, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountTransferHistoryEPL, http.MethodGet, walletSubAccountTransfer, params, nil, &response) } // SubAccountTransferToSubAccount performs sub-account transfers to sub-account -func (g *Gateio) SubAccountTransferToSubAccount(ctx context.Context, arg *InterSubAccountTransferParams) error { +func (e *Exchange) SubAccountTransferToSubAccount(ctx context.Context, arg *InterSubAccountTransferParams) error { if arg.Currency.IsEmpty() { return currency.ErrCurrencyCodeEmpty } @@ -1199,41 +1199,41 @@ func (g *Gateio) SubAccountTransferToSubAccount(ctx context.Context, arg *InterS if arg.Amount <= 0 { return errInvalidAmount } - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountToSubAccountTransferEPL, http.MethodPost, walletInterSubAccountTransfer, nil, &arg, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountToSubAccountTransferEPL, http.MethodPost, walletInterSubAccountTransfer, nil, &arg, nil) } // GetWithdrawalStatus retrieves withdrawal status -func (g *Gateio) GetWithdrawalStatus(ctx context.Context, ccy currency.Code) ([]WithdrawalStatus, error) { +func (e *Exchange) GetWithdrawalStatus(ctx context.Context, ccy currency.Code) ([]WithdrawalStatus, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var response []WithdrawalStatus - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawStatusEPL, http.MethodGet, walletWithdrawStatus, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletWithdrawStatusEPL, http.MethodGet, walletWithdrawStatus, params, nil, &response) } // GetSubAccountBalances retrieve sub account balances -func (g *Gateio) GetSubAccountBalances(ctx context.Context, subAccountUserID string) ([]FuturesSubAccountBalance, error) { +func (e *Exchange) GetSubAccountBalances(ctx context.Context, subAccountUserID string) ([]FuturesSubAccountBalance, error) { params := url.Values{} if subAccountUserID != "" { params.Set("sub_uid", subAccountUserID) } var response []FuturesSubAccountBalance - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountBalancesEPL, http.MethodGet, walletSubAccountBalance, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountBalancesEPL, http.MethodGet, walletSubAccountBalance, params, nil, &response) } // GetSubAccountMarginBalances query sub accounts' margin balances -func (g *Gateio) GetSubAccountMarginBalances(ctx context.Context, subAccountUserID string) ([]SubAccountMarginBalance, error) { +func (e *Exchange) GetSubAccountMarginBalances(ctx context.Context, subAccountUserID string) ([]SubAccountMarginBalance, error) { params := url.Values{} if subAccountUserID != "" { params.Set("sub_uid", subAccountUserID) } var response []SubAccountMarginBalance - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountMarginBalancesEPL, http.MethodGet, walletSubAccountMarginBalance, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountMarginBalancesEPL, http.MethodGet, walletSubAccountMarginBalance, params, nil, &response) } // GetSubAccountFuturesBalances retrieves sub accounts' futures account balances -func (g *Gateio) GetSubAccountFuturesBalances(ctx context.Context, subAccountUserID string, settle currency.Code) ([]FuturesSubAccountBalance, error) { +func (e *Exchange) GetSubAccountFuturesBalances(ctx context.Context, subAccountUserID string, settle currency.Code) ([]FuturesSubAccountBalance, error) { params := url.Values{} if subAccountUserID != "" { params.Set("sub_uid", subAccountUserID) @@ -1242,21 +1242,21 @@ func (g *Gateio) GetSubAccountFuturesBalances(ctx context.Context, subAccountUse params.Set("settle", settle.Item.Lower) } var response []FuturesSubAccountBalance - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountFuturesBalancesEPL, http.MethodGet, walletSubAccountFuturesBalance, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountFuturesBalancesEPL, http.MethodGet, walletSubAccountFuturesBalance, params, nil, &response) } // GetSubAccountCrossMarginBalances query subaccount's cross_margin account info -func (g *Gateio) GetSubAccountCrossMarginBalances(ctx context.Context, subAccountUserID string) ([]SubAccountCrossMarginInfo, error) { +func (e *Exchange) GetSubAccountCrossMarginBalances(ctx context.Context, subAccountUserID string) ([]SubAccountCrossMarginInfo, error) { params := url.Values{} if subAccountUserID != "" { params.Set("sub_uid", subAccountUserID) } var response []SubAccountCrossMarginInfo - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountCrossMarginBalancesEPL, http.MethodGet, walletSubAccountCrossMarginBalances, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSubAccountCrossMarginBalancesEPL, http.MethodGet, walletSubAccountCrossMarginBalances, params, nil, &response) } // GetSavedAddresses retrieves saved currency address info and related details. -func (g *Gateio) GetSavedAddresses(ctx context.Context, ccy currency.Code, chain string, limit uint64) ([]WalletSavedAddress, error) { +func (e *Exchange) GetSavedAddresses(ctx context.Context, ccy currency.Code, chain string, limit uint64) ([]WalletSavedAddress, error) { params := url.Values{} if ccy.IsEmpty() { return nil, fmt.Errorf("%w address is required", currency.ErrCurrencyPairEmpty) @@ -1269,11 +1269,11 @@ func (g *Gateio) GetSavedAddresses(ctx context.Context, ccy currency.Code, chain params.Set("limit", strconv.FormatUint(limit, 10)) } var response []WalletSavedAddress - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSavedAddressesEPL, http.MethodGet, walletSavedAddress, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletSavedAddressesEPL, http.MethodGet, walletSavedAddress, params, nil, &response) } // GetPersonalTradingFee retrieves personal trading fee -func (g *Gateio) GetPersonalTradingFee(ctx context.Context, currencyPair currency.Pair, settle currency.Code) (*PersonalTradingFee, error) { +func (e *Exchange) GetPersonalTradingFee(ctx context.Context, currencyPair currency.Pair, settle currency.Code) (*PersonalTradingFee, error) { params := url.Values{} if currencyPair.IsPopulated() { // specify a currency pair to retrieve precise fee rate @@ -1283,23 +1283,23 @@ func (g *Gateio) GetPersonalTradingFee(ctx context.Context, currencyPair currenc params.Set("settle", settle.Item.Lower) } var response *PersonalTradingFee - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTradingFeeEPL, http.MethodGet, walletTradingFee, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTradingFeeEPL, http.MethodGet, walletTradingFee, params, nil, &response) } // GetUsersTotalBalance retrieves user's total balances -func (g *Gateio) GetUsersTotalBalance(ctx context.Context, ccy currency.Code) (*UsersAllAccountBalance, error) { +func (e *Exchange) GetUsersTotalBalance(ctx context.Context, ccy currency.Code) (*UsersAllAccountBalance, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var response *UsersAllAccountBalance - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTotalBalanceEPL, http.MethodGet, walletTotalBalance, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletTotalBalanceEPL, http.MethodGet, walletTotalBalance, params, nil, &response) } // ConvertSmallBalances converts small balances of provided currencies into GT. // If no currencies are provided, all supported currencies will be converted // See [this documentation](https://www.gate.io/help/guide/functional_guidelines/22367) for details and restrictions. -func (g *Gateio) ConvertSmallBalances(ctx context.Context, currs ...currency.Code) error { +func (e *Exchange) ConvertSmallBalances(ctx context.Context, currs ...currency.Code) error { currencyList := make([]string, len(currs)) for i := range currs { if currs[i].IsEmpty() { @@ -1315,48 +1315,48 @@ func (g *Gateio) ConvertSmallBalances(ctx context.Context, currs ...currency.Cod Currency: currencyList, IsAll: len(currs) == 0, } - return g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletConvertSmallBalancesEPL, http.MethodPost, "wallet/small_balance", nil, payload, nil) + return e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, walletConvertSmallBalancesEPL, http.MethodPost, "wallet/small_balance", nil, payload, nil) } // ********************************* Margin ******************************************* // GetMarginSupportedCurrencyPairs retrieves margin supported currency pairs. -func (g *Gateio) GetMarginSupportedCurrencyPairs(ctx context.Context) ([]MarginCurrencyPairInfo, error) { +func (e *Exchange) GetMarginSupportedCurrencyPairs(ctx context.Context) ([]MarginCurrencyPairInfo, error) { var currenciePairsInfo []MarginCurrencyPairInfo - return currenciePairsInfo, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairsMarginEPL, gateioMarginCurrencyPairs, ¤ciePairsInfo) + return currenciePairsInfo, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairsMarginEPL, gateioMarginCurrencyPairs, ¤ciePairsInfo) } // GetSingleMarginSupportedCurrencyPair retrieves margin supported currency pair detail given the currency pair. -func (g *Gateio) GetSingleMarginSupportedCurrencyPair(ctx context.Context, market currency.Pair) (*MarginCurrencyPairInfo, error) { +func (e *Exchange) GetSingleMarginSupportedCurrencyPair(ctx context.Context, market currency.Pair) (*MarginCurrencyPairInfo, error) { if market.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } var currencyPairInfo *MarginCurrencyPairInfo - return currencyPairInfo, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairsMarginEPL, gateioMarginCurrencyPairs+"/"+market.String(), ¤cyPairInfo) + return currencyPairInfo, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCurrencyPairsMarginEPL, gateioMarginCurrencyPairs+"/"+market.String(), ¤cyPairInfo) } // GetOrderbookOfLendingLoans retrieves order book of lending loans for specific currency -func (g *Gateio) GetOrderbookOfLendingLoans(ctx context.Context, ccy currency.Code) ([]OrderbookOfLendingLoan, error) { +func (e *Exchange) GetOrderbookOfLendingLoans(ctx context.Context, ccy currency.Code) ([]OrderbookOfLendingLoan, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var lendingLoans []OrderbookOfLendingLoan - return lendingLoans, g.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookMarginEPL, gateioMarginFundingBook+"?currency="+ccy.String(), &lendingLoans) + return lendingLoans, e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookMarginEPL, gateioMarginFundingBook+"?currency="+ccy.String(), &lendingLoans) } // GetMarginAccountList margin account list -func (g *Gateio) GetMarginAccountList(ctx context.Context, currencyPair currency.Pair) ([]MarginAccountItem, error) { +func (e *Exchange) GetMarginAccountList(ctx context.Context, currencyPair currency.Pair) ([]MarginAccountItem, error) { params := url.Values{} if currencyPair.IsPopulated() { params.Set("currency_pair", currencyPair.String()) } var response []MarginAccountItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountListEPL, http.MethodGet, gateioMarginAccount, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountListEPL, http.MethodGet, gateioMarginAccount, params, nil, &response) } // ListMarginAccountBalanceChangeHistory retrieves margin account balance change history // Only transferals from and to margin account are provided for now. Time range allows 30 days at most -func (g *Gateio) ListMarginAccountBalanceChangeHistory(ctx context.Context, ccy currency.Code, currencyPair currency.Pair, from, to time.Time, page, limit uint64) ([]MarginAccountBalanceChangeInfo, error) { +func (e *Exchange) ListMarginAccountBalanceChangeHistory(ctx context.Context, ccy currency.Code, currencyPair currency.Pair, from, to time.Time, page, limit uint64) ([]MarginAccountBalanceChangeInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1377,21 +1377,21 @@ func (g *Gateio) ListMarginAccountBalanceChangeHistory(ctx context.Context, ccy params.Set("limit", strconv.FormatUint(limit, 10)) } var response []MarginAccountBalanceChangeInfo - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountBalanceEPL, http.MethodGet, gateioMarginAccountBook, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountBalanceEPL, http.MethodGet, gateioMarginAccountBook, params, nil, &response) } // GetMarginFundingAccountList retrieves funding account list -func (g *Gateio) GetMarginFundingAccountList(ctx context.Context, ccy currency.Code) ([]MarginFundingAccountItem, error) { +func (e *Exchange) GetMarginFundingAccountList(ctx context.Context, ccy currency.Code) ([]MarginFundingAccountItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var response []MarginFundingAccountItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginFundingAccountListEPL, http.MethodGet, gateioMarginFundingAccounts, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginFundingAccountListEPL, http.MethodGet, gateioMarginFundingAccounts, params, nil, &response) } // MarginLoan represents lend or borrow request -func (g *Gateio) MarginLoan(ctx context.Context, arg *MarginLoanRequestParam) (*MarginLoanResponse, error) { +func (e *Exchange) MarginLoan(ctx context.Context, arg *MarginLoanRequestParam) (*MarginLoanResponse, error) { if arg == nil { return nil, errNilArgument } @@ -1411,11 +1411,11 @@ func (g *Gateio) MarginLoan(ctx context.Context, arg *MarginLoanRequestParam) (* return nil, errors.New("invalid loan rate, rate must be between 0.0002 and 0.002") } var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginLendBorrowEPL, http.MethodPost, gateioMarginLoans, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginLendBorrowEPL, http.MethodPost, gateioMarginLoans, nil, &arg, &response) } // GetMarginAllLoans retrieves all loans (borrow and lending) orders. -func (g *Gateio) GetMarginAllLoans(ctx context.Context, status, side, sortBy string, ccy currency.Code, currencyPair currency.Pair, reverseSort bool, page, limit uint64) ([]MarginLoanResponse, error) { +func (e *Exchange) GetMarginAllLoans(ctx context.Context, status, side, sortBy string, ccy currency.Code, currencyPair currency.Pair, reverseSort bool, page, limit uint64) ([]MarginLoanResponse, error) { if side != sideLend && side != sideBorrow { return nil, fmt.Errorf("%w, only 'lend' and 'borrow' are supported", order.ErrSideIsInvalid) } @@ -1445,11 +1445,11 @@ func (g *Gateio) GetMarginAllLoans(ctx context.Context, status, side, sortBy str params.Set("limit", strconv.FormatUint(limit, 10)) } var response []MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAllLoansEPL, http.MethodGet, gateioMarginLoans, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAllLoansEPL, http.MethodGet, gateioMarginLoans, params, nil, &response) } // MergeMultipleLendingLoans merge multiple lending loans -func (g *Gateio) MergeMultipleLendingLoans(ctx context.Context, ccy currency.Code, ids []string) (*MarginLoanResponse, error) { +func (e *Exchange) MergeMultipleLendingLoans(ctx context.Context, ccy currency.Code, ids []string) (*MarginLoanResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1460,12 +1460,12 @@ func (g *Gateio) MergeMultipleLendingLoans(ctx context.Context, ccy currency.Cod params.Set("currency", ccy.String()) params.Set("ids", strings.Join(ids, ",")) var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginMergeLendingLoansEPL, http.MethodPost, gateioMarginMergedLoans, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginMergeLendingLoansEPL, http.MethodPost, gateioMarginMergedLoans, params, nil, &response) } // RetriveOneSingleLoanDetail retrieve one single loan detail // "side" represents loan side: Lend or Borrow -func (g *Gateio) RetriveOneSingleLoanDetail(ctx context.Context, side, loanID string) (*MarginLoanResponse, error) { +func (e *Exchange) RetriveOneSingleLoanDetail(ctx context.Context, side, loanID string) (*MarginLoanResponse, error) { if side != sideBorrow && side != sideLend { return nil, errInvalidLoanSide } @@ -1475,12 +1475,12 @@ func (g *Gateio) RetriveOneSingleLoanDetail(ctx context.Context, side, loanID st params := url.Values{} params.Set("side", side) var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetLoanEPL, http.MethodGet, gateioMarginLoans+"/"+loanID+"/", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetLoanEPL, http.MethodGet, gateioMarginLoans+"/"+loanID+"/", params, nil, &response) } // ModifyALoan Modify a loan // only auto_renew modification is supported currently -func (g *Gateio) ModifyALoan(ctx context.Context, loanID string, arg *ModifyLoanRequestParam) (*MarginLoanResponse, error) { +func (e *Exchange) ModifyALoan(ctx context.Context, loanID string, arg *ModifyLoanRequestParam) (*MarginLoanResponse, error) { if arg == nil { return nil, errNilArgument } @@ -1497,11 +1497,11 @@ func (g *Gateio) ModifyALoan(ctx context.Context, loanID string, arg *ModifyLoan return nil, currency.ErrCurrencyPairEmpty } var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginModifyLoanEPL, http.MethodPatch, gateioMarginLoans+"/"+loanID, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginModifyLoanEPL, http.MethodPatch, gateioMarginLoans+"/"+loanID, nil, &arg, &response) } // CancelLendingLoan cancels lending loans. only lent loans can be canceled. -func (g *Gateio) CancelLendingLoan(ctx context.Context, ccy currency.Code, loanID string) (*MarginLoanResponse, error) { +func (e *Exchange) CancelLendingLoan(ctx context.Context, ccy currency.Code, loanID string) (*MarginLoanResponse, error) { if loanID == "" { return nil, fmt.Errorf("%w, %s", errInvalidLoanID, " loan_id is required") } @@ -1511,11 +1511,11 @@ func (g *Gateio) CancelLendingLoan(ctx context.Context, ccy currency.Code, loanI params := url.Values{} params.Set("currency", ccy.String()) var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginCancelLoanEPL, http.MethodDelete, gateioMarginLoans+"/"+loanID, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginCancelLoanEPL, http.MethodDelete, gateioMarginLoans+"/"+loanID, params, nil, &response) } // RepayALoan execute a loan repay. -func (g *Gateio) RepayALoan(ctx context.Context, loanID string, arg *RepayLoanRequestParam) (*MarginLoanResponse, error) { +func (e *Exchange) RepayALoan(ctx context.Context, loanID string, arg *RepayLoanRequestParam) (*MarginLoanResponse, error) { if arg == nil { return nil, errNilArgument } @@ -1535,20 +1535,20 @@ func (g *Gateio) RepayALoan(ctx context.Context, loanID string, arg *RepayLoanRe return nil, fmt.Errorf("%w, repay amount for partial repay mode must be greater than 0", errInvalidAmount) } var response *MarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginRepayLoanEPL, http.MethodPost, gateioMarginLoans+"/"+loanID+"/repayment", nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginRepayLoanEPL, http.MethodPost, gateioMarginLoans+"/"+loanID+"/repayment", nil, &arg, &response) } // ListLoanRepaymentRecords retrieves loan repayment records for specified loan ID -func (g *Gateio) ListLoanRepaymentRecords(ctx context.Context, loanID string) ([]LoanRepaymentRecord, error) { +func (e *Exchange) ListLoanRepaymentRecords(ctx context.Context, loanID string) ([]LoanRepaymentRecord, error) { if loanID == "" { return nil, fmt.Errorf("%w, %v", errInvalidLoanID, " loan_id is required") } var response []LoanRepaymentRecord - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginListLoansEPL, http.MethodGet, gateioMarginLoans+"/"+loanID+"/repayment", nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginListLoansEPL, http.MethodGet, gateioMarginLoans+"/"+loanID+"/repayment", nil, nil, &response) } // ListRepaymentRecordsOfSpecificLoan retrieves repayment records of specific loan -func (g *Gateio) ListRepaymentRecordsOfSpecificLoan(ctx context.Context, loanID, status string, page, limit uint64) ([]LoanRecord, error) { +func (e *Exchange) ListRepaymentRecordsOfSpecificLoan(ctx context.Context, loanID, status string, page, limit uint64) ([]LoanRecord, error) { if loanID == "" { return nil, fmt.Errorf("%w, %v", errInvalidLoanID, " loan_id is required") } @@ -1564,11 +1564,11 @@ func (g *Gateio) ListRepaymentRecordsOfSpecificLoan(ctx context.Context, loanID, params.Set("limit", strconv.FormatUint(limit, 10)) } var response []LoanRecord - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginRepaymentRecordEPL, http.MethodGet, gateioMarginLoanRecords, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginRepaymentRecordEPL, http.MethodGet, gateioMarginLoanRecords, params, nil, &response) } // GetOneSingleLoanRecord get one single loan record -func (g *Gateio) GetOneSingleLoanRecord(ctx context.Context, loanID, loanRecordID string) (*LoanRecord, error) { +func (e *Exchange) GetOneSingleLoanRecord(ctx context.Context, loanID, loanRecordID string) (*LoanRecord, error) { if loanID == "" { return nil, fmt.Errorf("%w, %v", errInvalidLoanID, " loan_id is required") } @@ -1578,12 +1578,12 @@ func (g *Gateio) GetOneSingleLoanRecord(ctx context.Context, loanID, loanRecordI params := url.Values{} params.Set("loan_id", loanID) var response *LoanRecord - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSingleRecordEPL, http.MethodGet, gateioMarginLoanRecords+"/"+loanRecordID, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSingleRecordEPL, http.MethodGet, gateioMarginLoanRecords+"/"+loanRecordID, params, nil, &response) } // ModifyALoanRecord modify a loan record // Only auto_renew modification is supported currently -func (g *Gateio) ModifyALoanRecord(ctx context.Context, loanRecordID string, arg *ModifyLoanRequestParam) (*LoanRecord, error) { +func (e *Exchange) ModifyALoanRecord(ctx context.Context, loanRecordID string, arg *ModifyLoanRequestParam) (*LoanRecord, error) { if arg == nil { return nil, errNilArgument } @@ -1600,11 +1600,11 @@ func (g *Gateio) ModifyALoanRecord(ctx context.Context, loanRecordID string, arg return nil, errInvalidLoanSide } var response *LoanRecord - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginModifyLoanRecordEPL, http.MethodPatch, gateioMarginLoanRecords+"/"+loanRecordID, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginModifyLoanRecordEPL, http.MethodPatch, gateioMarginLoanRecords+"/"+loanRecordID, nil, &arg, &response) } // UpdateUsersAutoRepaymentSetting represents update user's auto repayment setting -func (g *Gateio) UpdateUsersAutoRepaymentSetting(ctx context.Context, statusOn bool) (*OnOffStatus, error) { +func (e *Exchange) UpdateUsersAutoRepaymentSetting(ctx context.Context, statusOn bool) (*OnOffStatus, error) { var statusStr string if statusOn { statusStr = "on" @@ -1614,17 +1614,17 @@ func (g *Gateio) UpdateUsersAutoRepaymentSetting(ctx context.Context, statusOn b params := url.Values{} params.Set("status", statusStr) var response *OnOffStatus - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAutoRepayEPL, http.MethodPost, gateioMarginAutoRepay, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAutoRepayEPL, http.MethodPost, gateioMarginAutoRepay, params, nil, &response) } // GetUserAutoRepaymentSetting retrieve user auto repayment setting -func (g *Gateio) GetUserAutoRepaymentSetting(ctx context.Context) (*OnOffStatus, error) { +func (e *Exchange) GetUserAutoRepaymentSetting(ctx context.Context) (*OnOffStatus, error) { var response *OnOffStatus - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetAutoRepaySettingsEPL, http.MethodGet, gateioMarginAutoRepay, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetAutoRepaySettingsEPL, http.MethodGet, gateioMarginAutoRepay, nil, nil, &response) } // GetMaxTransferableAmountForSpecificMarginCurrency get the max transferable amount for a specific margin currency. -func (g *Gateio) GetMaxTransferableAmountForSpecificMarginCurrency(ctx context.Context, ccy currency.Code, currencyPair currency.Pair) (*MaxTransferAndLoanAmount, error) { +func (e *Exchange) GetMaxTransferableAmountForSpecificMarginCurrency(ctx context.Context, ccy currency.Code, currencyPair currency.Pair) (*MaxTransferAndLoanAmount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1634,11 +1634,11 @@ func (g *Gateio) GetMaxTransferableAmountForSpecificMarginCurrency(ctx context.C } params.Set("currency", ccy.String()) var response *MaxTransferAndLoanAmount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxTransferEPL, http.MethodGet, gateioMarginTransfer, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxTransferEPL, http.MethodGet, gateioMarginTransfer, params, nil, &response) } // GetMaxBorrowableAmountForSpecificMarginCurrency retrieves the max borrowble amount for specific currency -func (g *Gateio) GetMaxBorrowableAmountForSpecificMarginCurrency(ctx context.Context, ccy currency.Code, currencyPair currency.Pair) (*MaxTransferAndLoanAmount, error) { +func (e *Exchange) GetMaxBorrowableAmountForSpecificMarginCurrency(ctx context.Context, ccy currency.Code, currencyPair currency.Pair) (*MaxTransferAndLoanAmount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1648,33 +1648,33 @@ func (g *Gateio) GetMaxBorrowableAmountForSpecificMarginCurrency(ctx context.Con } params.Set("currency", ccy.String()) var response *MaxTransferAndLoanAmount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxBorrowEPL, http.MethodGet, gateioMarginBorrowable, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxBorrowEPL, http.MethodGet, gateioMarginBorrowable, params, nil, &response) } // CurrencySupportedByCrossMargin currencies supported by cross margin. -func (g *Gateio) CurrencySupportedByCrossMargin(ctx context.Context) ([]CrossMarginCurrencies, error) { +func (e *Exchange) CurrencySupportedByCrossMargin(ctx context.Context) ([]CrossMarginCurrencies, error) { var response []CrossMarginCurrencies - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSupportedCurrencyCrossListEPL, http.MethodGet, gateioCrossMarginCurrencies, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSupportedCurrencyCrossListEPL, http.MethodGet, gateioCrossMarginCurrencies, nil, nil, &response) } // GetCrossMarginSupportedCurrencyDetail retrieve detail of one single currency supported by cross margin -func (g *Gateio) GetCrossMarginSupportedCurrencyDetail(ctx context.Context, ccy currency.Code) (*CrossMarginCurrencies, error) { +func (e *Exchange) GetCrossMarginSupportedCurrencyDetail(ctx context.Context, ccy currency.Code) (*CrossMarginCurrencies, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var response *CrossMarginCurrencies - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSupportedCurrencyCrossEPL, http.MethodGet, gateioCrossMarginCurrencies+"/"+ccy.String(), nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginSupportedCurrencyCrossEPL, http.MethodGet, gateioCrossMarginCurrencies+"/"+ccy.String(), nil, nil, &response) } // GetCrossMarginAccounts retrieve cross margin account -func (g *Gateio) GetCrossMarginAccounts(ctx context.Context) (*CrossMarginAccount, error) { +func (e *Exchange) GetCrossMarginAccounts(ctx context.Context) (*CrossMarginAccount, error) { var response *CrossMarginAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountsEPL, http.MethodGet, gateioCrossMarginAccounts, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountsEPL, http.MethodGet, gateioCrossMarginAccounts, nil, nil, &response) } // GetCrossMarginAccountChangeHistory retrieve cross margin account change history // Record time range cannot exceed 30 days -func (g *Gateio) GetCrossMarginAccountChangeHistory(ctx context.Context, ccy currency.Code, from, to time.Time, page, limit uint64, accountChangeType string) ([]CrossMarginAccountHistoryItem, error) { +func (e *Exchange) GetCrossMarginAccountChangeHistory(ctx context.Context, ccy currency.Code, from, to time.Time, page, limit uint64, accountChangeType string) ([]CrossMarginAccountHistoryItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1695,12 +1695,12 @@ func (g *Gateio) GetCrossMarginAccountChangeHistory(ctx context.Context, ccy cur params.Set("type", accountChangeType) } var response []CrossMarginAccountHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountHistoryEPL, http.MethodGet, gateioCrossMarginAccountBook, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginAccountHistoryEPL, http.MethodGet, gateioCrossMarginAccountBook, params, nil, &response) } // CreateCrossMarginBorrowLoan create a cross margin borrow loan // Borrow amount cannot be less than currency minimum borrow amount -func (g *Gateio) CreateCrossMarginBorrowLoan(ctx context.Context, arg CrossMarginBorrowLoanParams) (*CrossMarginLoanResponse, error) { +func (e *Exchange) CreateCrossMarginBorrowLoan(ctx context.Context, arg CrossMarginBorrowLoanParams) (*CrossMarginLoanResponse, error) { if arg.Currency.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1708,13 +1708,13 @@ func (g *Gateio) CreateCrossMarginBorrowLoan(ctx context.Context, arg CrossMargi return nil, fmt.Errorf("%w, borrow amount must be greater than 0", errInvalidAmount) } var response CrossMarginLoanResponse - return &response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginCreateCrossBorrowLoanEPL, http.MethodPost, gateioCrossMarginLoans, nil, &arg, &response) + return &response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginCreateCrossBorrowLoanEPL, http.MethodPost, gateioCrossMarginLoans, nil, &arg, &response) } // ExecuteRepayment when the liquidity of the currency is insufficient and the transaction risk is high, the currency will be disabled, // and funds cannot be transferred.When the available balance of cross-margin is insufficient, the balance of the spot account can be used for repayment. // Please ensure that the balance of the spot account is sufficient, and system uses cross-margin account for repayment first -func (g *Gateio) ExecuteRepayment(ctx context.Context, arg CurrencyAndAmount) ([]CrossMarginLoanResponse, error) { +func (e *Exchange) ExecuteRepayment(ctx context.Context, arg CurrencyAndAmount) ([]CrossMarginLoanResponse, error) { if arg.Currency.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1722,11 +1722,11 @@ func (g *Gateio) ExecuteRepayment(ctx context.Context, arg CurrencyAndAmount) ([ return nil, fmt.Errorf("%w, repay amount must be greater than 0", errInvalidAmount) } var response []CrossMarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginExecuteRepaymentsEPL, http.MethodPost, gateioCrossMarginRepayments, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginExecuteRepaymentsEPL, http.MethodPost, gateioCrossMarginRepayments, nil, &arg, &response) } // GetCrossMarginRepayments retrieves list of cross margin repayments -func (g *Gateio) GetCrossMarginRepayments(ctx context.Context, ccy currency.Code, loanID string, limit, offset uint64, reverse bool) ([]CrossMarginLoanResponse, error) { +func (e *Exchange) GetCrossMarginRepayments(ctx context.Context, ccy currency.Code, loanID string, limit, offset uint64, reverse bool) ([]CrossMarginLoanResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1744,36 +1744,36 @@ func (g *Gateio) GetCrossMarginRepayments(ctx context.Context, ccy currency.Code params.Set("reverse", "true") } var response []CrossMarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetCrossMarginRepaymentsEPL, http.MethodGet, gateioCrossMarginRepayments, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetCrossMarginRepaymentsEPL, http.MethodGet, gateioCrossMarginRepayments, params, nil, &response) } // GetMaxTransferableAmountForSpecificCrossMarginCurrency get the max transferable amount for a specific cross margin currency -func (g *Gateio) GetMaxTransferableAmountForSpecificCrossMarginCurrency(ctx context.Context, ccy currency.Code) (*CurrencyAndAmount, error) { +func (e *Exchange) GetMaxTransferableAmountForSpecificCrossMarginCurrency(ctx context.Context, ccy currency.Code) (*CurrencyAndAmount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} var response *CurrencyAndAmount params.Set("currency", ccy.String()) - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxTransferCrossEPL, http.MethodGet, gateioCrossMarginTransferable, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxTransferCrossEPL, http.MethodGet, gateioCrossMarginTransferable, params, nil, &response) } // GetMaxBorrowableAmountForSpecificCrossMarginCurrency returns the max borrowable amount for a specific cross margin currency -func (g *Gateio) GetMaxBorrowableAmountForSpecificCrossMarginCurrency(ctx context.Context, ccy currency.Code) (*CurrencyAndAmount, error) { +func (e *Exchange) GetMaxBorrowableAmountForSpecificCrossMarginCurrency(ctx context.Context, ccy currency.Code) (*CurrencyAndAmount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var response *CurrencyAndAmount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxBorrowCrossEPL, http.MethodGet, gateioCrossMarginBorrowable, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetMaxBorrowCrossEPL, http.MethodGet, gateioCrossMarginBorrowable, params, nil, &response) } // GetCrossMarginBorrowHistory retrieves cross margin borrow history sorted by creation time in descending order by default. // Set reverse=false to return ascending results. -func (g *Gateio) GetCrossMarginBorrowHistory(ctx context.Context, status uint64, ccy currency.Code, limit, offset uint64, reverse bool) ([]CrossMarginLoanResponse, error) { +func (e *Exchange) GetCrossMarginBorrowHistory(ctx context.Context, status uint64, ccy currency.Code, limit, offset uint64, reverse bool) ([]CrossMarginLoanResponse, error) { if status < 1 || status > 3 { - return nil, fmt.Errorf("%s %v, only allowed status values are 1:failed, 2:borrowed, and 3:repayment", g.Name, errInvalidOrderStatus) + return nil, fmt.Errorf("%s %v, only allowed status values are 1:failed, 2:borrowed, and 3:repayment", e.Name, errInvalidOrderStatus) } params := url.Values{} params.Set("status", strconv.FormatUint(status, 10)) @@ -1790,31 +1790,31 @@ func (g *Gateio) GetCrossMarginBorrowHistory(ctx context.Context, status uint64, params.Set("reverse", strconv.FormatBool(reverse)) } var response []CrossMarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetCrossBorrowHistoryEPL, http.MethodGet, gateioCrossMarginLoans, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetCrossBorrowHistoryEPL, http.MethodGet, gateioCrossMarginLoans, params, nil, &response) } // GetSingleBorrowLoanDetail retrieve single borrow loan detail -func (g *Gateio) GetSingleBorrowLoanDetail(ctx context.Context, loanID string) (*CrossMarginLoanResponse, error) { +func (e *Exchange) GetSingleBorrowLoanDetail(ctx context.Context, loanID string) (*CrossMarginLoanResponse, error) { if loanID == "" { return nil, errInvalidLoanID } var response *CrossMarginLoanResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetBorrowEPL, http.MethodGet, gateioCrossMarginLoans+"/"+loanID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, marginGetBorrowEPL, http.MethodGet, gateioCrossMarginLoans+"/"+loanID, nil, nil, &response) } // *********************************Futures*************************************** // GetAllFutureContracts retrieves list all futures contracts -func (g *Gateio) GetAllFutureContracts(ctx context.Context, settle currency.Code) ([]FuturesContract, error) { +func (e *Exchange) GetAllFutureContracts(ctx context.Context, settle currency.Code) ([]FuturesContract, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var contracts []FuturesContract - return contracts, g.SendHTTPRequest(ctx, exchange.RestSpot, publicFuturesContractsEPL, futuresPath+settle.Item.Lower+"/contracts", &contracts) + return contracts, e.SendHTTPRequest(ctx, exchange.RestSpot, publicFuturesContractsEPL, futuresPath+settle.Item.Lower+"/contracts", &contracts) } // GetFuturesContract returns a single futures contract info for the specified settle and Currency Pair (contract << in this case) -func (g *Gateio) GetFuturesContract(ctx context.Context, settle currency.Code, contract string) (*FuturesContract, error) { +func (e *Exchange) GetFuturesContract(ctx context.Context, settle currency.Code, contract string) (*FuturesContract, error) { if contract == "" { return nil, currency.ErrCurrencyPairEmpty } @@ -1822,11 +1822,11 @@ func (g *Gateio) GetFuturesContract(ctx context.Context, settle currency.Code, c return nil, errEmptyOrInvalidSettlementCurrency } var futureContract *FuturesContract - return futureContract, g.SendHTTPRequest(ctx, exchange.RestSpot, publicFuturesContractsEPL, futuresPath+settle.Item.Lower+"/contracts/"+contract, &futureContract) + return futureContract, e.SendHTTPRequest(ctx, exchange.RestSpot, publicFuturesContractsEPL, futuresPath+settle.Item.Lower+"/contracts/"+contract, &futureContract) } // GetFuturesOrderbook retrieves futures order book data -func (g *Gateio) GetFuturesOrderbook(ctx context.Context, settle currency.Code, contract, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { +func (e *Exchange) GetFuturesOrderbook(ctx context.Context, settle currency.Code, contract, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { if contract == "" { return nil, currency.ErrCurrencyPairEmpty } @@ -1845,11 +1845,11 @@ func (g *Gateio) GetFuturesOrderbook(ctx context.Context, settle currency.Code, params.Set("with_id", "true") } var response *Orderbook - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/order_book", params), &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/order_book", params), &response) } // GetFuturesTradingHistory retrieves futures trading history -func (g *Gateio) GetFuturesTradingHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, lastID string, from, to time.Time) ([]TradingHistoryItem, error) { +func (e *Exchange) GetFuturesTradingHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, lastID string, from, to time.Time) ([]TradingHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1874,11 +1874,11 @@ func (g *Gateio) GetFuturesTradingHistory(ctx context.Context, settle currency.C params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var response []TradingHistoryItem - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTradingHistoryFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/trades", params), &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTradingHistoryFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/trades", params), &response) } // GetFuturesCandlesticks retrieves specified contract candlesticks. -func (g *Gateio) GetFuturesCandlesticks(ctx context.Context, settle currency.Code, contract string, from, to time.Time, limit uint64, interval kline.Interval) ([]FuturesCandlestick, error) { +func (e *Exchange) GetFuturesCandlesticks(ctx context.Context, settle currency.Code, contract string, from, to time.Time, limit uint64, interval kline.Interval) ([]FuturesCandlestick, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1904,12 +1904,12 @@ func (g *Gateio) GetFuturesCandlesticks(ctx context.Context, settle currency.Cod params.Set("interval", intervalString) } var candlesticks []FuturesCandlestick - return candlesticks, g.SendHTTPRequest(ctx, exchange.RestFutures, publicCandleSticksFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/candlesticks", params), &candlesticks) + return candlesticks, e.SendHTTPRequest(ctx, exchange.RestFutures, publicCandleSticksFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/candlesticks", params), &candlesticks) } // PremiumIndexKLine retrieves premium Index K-Line // Maximum of 1000 points can be returned in a query. Be sure not to exceed the limit when specifying from, to and interval -func (g *Gateio) PremiumIndexKLine(ctx context.Context, settleCurrency currency.Code, contract currency.Pair, from, to time.Time, limit int64, interval kline.Interval) ([]FuturesPremiumIndexKLineResponse, error) { +func (e *Exchange) PremiumIndexKLine(ctx context.Context, settleCurrency currency.Code, contract currency.Pair, from, to time.Time, limit int64, interval kline.Interval) ([]FuturesPremiumIndexKLineResponse, error) { if settleCurrency.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1933,11 +1933,11 @@ func (g *Gateio) PremiumIndexKLine(ctx context.Context, settleCurrency currency. } params.Set("interval", intervalString) var resp []FuturesPremiumIndexKLineResponse - return resp, g.SendHTTPRequest(ctx, exchange.RestSpot, publicPremiumIndexEPL, common.EncodeURLValues(futuresPath+settleCurrency.Item.Lower+"/premium_index", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, publicPremiumIndexEPL, common.EncodeURLValues(futuresPath+settleCurrency.Item.Lower+"/premium_index", params), &resp) } // GetFuturesTickers retrieves futures ticker information for a specific settle and contract info. -func (g *Gateio) GetFuturesTickers(ctx context.Context, settle currency.Code, contract currency.Pair) ([]FuturesTicker, error) { +func (e *Exchange) GetFuturesTickers(ctx context.Context, settle currency.Code, contract currency.Pair) ([]FuturesTicker, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1946,11 +1946,11 @@ func (g *Gateio) GetFuturesTickers(ctx context.Context, settle currency.Code, co params.Set("contract", contract.String()) } var tickers []FuturesTicker - return tickers, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/tickers", params), &tickers) + return tickers, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/tickers", params), &tickers) } // GetFutureFundingRates retrieves funding rate information. -func (g *Gateio) GetFutureFundingRates(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64) ([]FuturesFundingRate, error) { +func (e *Exchange) GetFutureFundingRates(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64) ([]FuturesFundingRate, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1963,11 +1963,11 @@ func (g *Gateio) GetFutureFundingRates(ctx context.Context, settle currency.Code params.Set("limit", strconv.FormatUint(limit, 10)) } var rates []FuturesFundingRate - return rates, g.SendHTTPRequest(ctx, exchange.RestSpot, publicFundingRatesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/funding_rate", params), &rates) + return rates, e.SendHTTPRequest(ctx, exchange.RestSpot, publicFundingRatesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/funding_rate", params), &rates) } // GetFuturesInsuranceBalanceHistory retrieves futures insurance balance history -func (g *Gateio) GetFuturesInsuranceBalanceHistory(ctx context.Context, settle currency.Code, limit uint64) ([]InsuranceBalance, error) { +func (e *Exchange) GetFuturesInsuranceBalanceHistory(ctx context.Context, settle currency.Code, limit uint64) ([]InsuranceBalance, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -1976,11 +1976,11 @@ func (g *Gateio) GetFuturesInsuranceBalanceHistory(ctx context.Context, settle c params.Set("limit", strconv.FormatUint(limit, 10)) } var balances []InsuranceBalance - return balances, g.SendHTTPRequest(ctx, exchange.RestSpot, publicInsuranceFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/insurance", params), &balances) + return balances, e.SendHTTPRequest(ctx, exchange.RestSpot, publicInsuranceFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/insurance", params), &balances) } // GetFutureStats retrieves futures stats -func (g *Gateio) GetFutureStats(ctx context.Context, settle currency.Code, contract currency.Pair, from time.Time, interval kline.Interval, limit uint64) ([]ContractStat, error) { +func (e *Exchange) GetFutureStats(ctx context.Context, settle currency.Code, contract currency.Pair, from time.Time, interval kline.Interval, limit uint64) ([]ContractStat, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2003,11 +2003,11 @@ func (g *Gateio) GetFutureStats(ctx context.Context, settle currency.Code, contr params.Set("limit", strconv.FormatUint(limit, 10)) } var stats []ContractStat - return stats, g.SendHTTPRequest(ctx, exchange.RestSpot, publicStatsFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/contract_stats", params), &stats) + return stats, e.SendHTTPRequest(ctx, exchange.RestSpot, publicStatsFuturesEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/contract_stats", params), &stats) } // GetIndexConstituent retrieves index constituents -func (g *Gateio) GetIndexConstituent(ctx context.Context, settle currency.Code, index string) (*IndexConstituent, error) { +func (e *Exchange) GetIndexConstituent(ctx context.Context, settle currency.Code, index string) (*IndexConstituent, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2016,11 +2016,11 @@ func (g *Gateio) GetIndexConstituent(ctx context.Context, settle currency.Code, } indexString := strings.ToUpper(index) var constituents *IndexConstituent - return constituents, g.SendHTTPRequest(ctx, exchange.RestSpot, publicIndexConstituentsEPL, futuresPath+settle.Item.Lower+"/index_constituents/"+indexString, &constituents) + return constituents, e.SendHTTPRequest(ctx, exchange.RestSpot, publicIndexConstituentsEPL, futuresPath+settle.Item.Lower+"/index_constituents/"+indexString, &constituents) } // GetLiquidationHistory retrieves liqudiation history -func (g *Gateio) GetLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, from, to time.Time, limit uint64) ([]LiquidationHistory, error) { +func (e *Exchange) GetLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, from, to time.Time, limit uint64) ([]LiquidationHistory, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2039,20 +2039,20 @@ func (g *Gateio) GetLiquidationHistory(ctx context.Context, settle currency.Code params.Set("limit", strconv.FormatUint(limit, 10)) } var histories []LiquidationHistory - return histories, g.SendHTTPRequest(ctx, exchange.RestSpot, publicLiquidationHistoryEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/liq_orders", params), &histories) + return histories, e.SendHTTPRequest(ctx, exchange.RestSpot, publicLiquidationHistoryEPL, common.EncodeURLValues(futuresPath+settle.Item.Lower+"/liq_orders", params), &histories) } // QueryFuturesAccount retrieves futures account -func (g *Gateio) QueryFuturesAccount(ctx context.Context, settle currency.Code) (*FuturesAccount, error) { +func (e *Exchange) QueryFuturesAccount(ctx context.Context, settle currency.Code) (*FuturesAccount, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var response *FuturesAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAccountEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/accounts", nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAccountEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/accounts", nil, nil, &response) } // GetFuturesAccountBooks retrieves account books -func (g *Gateio) GetFuturesAccountBooks(ctx context.Context, settle currency.Code, limit uint64, from, to time.Time, changingType string) ([]AccountBookItem, error) { +func (e *Exchange) GetFuturesAccountBooks(ctx context.Context, settle currency.Code, limit uint64, from, to time.Time, changingType string) ([]AccountBookItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2070,11 +2070,11 @@ func (g *Gateio) GetFuturesAccountBooks(ctx context.Context, settle currency.Cod params.Set("type", changingType) } var response []AccountBookItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAccountBooksEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/account_book", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAccountBooksEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/account_book", params, nil, &response) } // GetAllFuturesPositionsOfUsers list all positions of users. -func (g *Gateio) GetAllFuturesPositionsOfUsers(ctx context.Context, settle currency.Code, realPositionsOnly bool) ([]Position, error) { +func (e *Exchange) GetAllFuturesPositionsOfUsers(ctx context.Context, settle currency.Code, realPositionsOnly bool) ([]Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2083,11 +2083,11 @@ func (g *Gateio) GetAllFuturesPositionsOfUsers(ctx context.Context, settle curre params.Set("holding", "true") } var response []Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionsEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/positions", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionsEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/positions", params, nil, &response) } // GetSinglePosition returns a single position -func (g *Gateio) GetSinglePosition(ctx context.Context, settle currency.Code, contract currency.Pair) (*Position, error) { +func (e *Exchange) GetSinglePosition(ctx context.Context, settle currency.Code, contract currency.Pair) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2095,11 +2095,11 @@ func (g *Gateio) GetSinglePosition(ctx context.Context, settle currency.Code, co return nil, fmt.Errorf("%w, currency pair for contract must not be empty", errInvalidOrMissingContractParam) } var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String(), nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String(), nil, nil, &response) } // UpdateFuturesPositionMargin represents account position margin for a futures contract. -func (g *Gateio) UpdateFuturesPositionMargin(ctx context.Context, settle currency.Code, change float64, contract currency.Pair) (*Position, error) { +func (e *Exchange) UpdateFuturesPositionMargin(ctx context.Context, settle currency.Code, change float64, contract currency.Pair) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2112,11 +2112,11 @@ func (g *Gateio) UpdateFuturesPositionMargin(ctx context.Context, settle currenc params := url.Values{} params.Set("change", strconv.FormatFloat(change, 'f', -1, 64)) var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateMarginEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/margin", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateMarginEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/margin", params, nil, &response) } // UpdateFuturesPositionLeverage update position leverage -func (g *Gateio) UpdateFuturesPositionLeverage(ctx context.Context, settle currency.Code, contract currency.Pair, leverage, crossLeverageLimit float64) (*Position, error) { +func (e *Exchange) UpdateFuturesPositionLeverage(ctx context.Context, settle currency.Code, contract currency.Pair, leverage, crossLeverageLimit float64) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2132,11 +2132,11 @@ func (g *Gateio) UpdateFuturesPositionLeverage(ctx context.Context, settle curre params.Set("cross_leverage_limit", strconv.FormatFloat(crossLeverageLimit, 'f', -1, 64)) } var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateLeverageEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/leverage", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateLeverageEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/leverage", params, nil, &response) } // UpdateFuturesPositionRiskLimit updates the position risk limit -func (g *Gateio) UpdateFuturesPositionRiskLimit(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit uint64) (*Position, error) { +func (e *Exchange) UpdateFuturesPositionRiskLimit(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit uint64) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2146,23 +2146,23 @@ func (g *Gateio) UpdateFuturesPositionRiskLimit(ctx context.Context, settle curr params := url.Values{} params.Set("risk_limit", strconv.FormatUint(riskLimit, 10)) var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateRiskEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/risk_limit", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateRiskEPL, http.MethodPost, futuresPath+settle.Item.Lower+positionsPath+contract.String()+"/risk_limit", params, nil, &response) } // EnableOrDisableDualMode enable or disable dual mode // Before setting dual mode, make sure all positions are closed and no orders are open -func (g *Gateio) EnableOrDisableDualMode(ctx context.Context, settle currency.Code, dualMode bool) (*DualModeResponse, error) { +func (e *Exchange) EnableOrDisableDualMode(ctx context.Context, settle currency.Code, dualMode bool) (*DualModeResponse, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } params := url.Values{} params.Set("dual_mode", strconv.FormatBool(dualMode)) var response *DualModeResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualToggleDualModeEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/dual_mode", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualToggleDualModeEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/dual_mode", params, nil, &response) } // RetrivePositionDetailInDualMode retrieve position detail in dual mode -func (g *Gateio) RetrivePositionDetailInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair) ([]Position, error) { +func (e *Exchange) RetrivePositionDetailInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair) ([]Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2170,11 +2170,11 @@ func (g *Gateio) RetrivePositionDetailInDualMode(ctx context.Context, settle cur return nil, fmt.Errorf("%w, currency pair for contract must not be empty", errInvalidOrMissingContractParam) } var response []Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionsDualModeEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String(), nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualPositionsDualModeEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String(), nil, nil, &response) } // UpdatePositionMarginInDualMode update position margin in dual mode -func (g *Gateio) UpdatePositionMarginInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, change float64, dualSide string) ([]Position, error) { +func (e *Exchange) UpdatePositionMarginInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, change float64, dualSide string) ([]Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2188,11 +2188,11 @@ func (g *Gateio) UpdatePositionMarginInDualMode(ctx context.Context, settle curr } params.Set("dual_side", dualSide) var response []Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateMarginDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/margin", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateMarginDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/margin", params, nil, &response) } // UpdatePositionLeverageInDualMode update position leverage in dual mode -func (g *Gateio) UpdatePositionLeverageInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, leverage, crossLeverageLimit float64) (*Position, error) { +func (e *Exchange) UpdatePositionLeverageInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, leverage, crossLeverageLimit float64) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2208,11 +2208,11 @@ func (g *Gateio) UpdatePositionLeverageInDualMode(ctx context.Context, settle cu params.Set("cross_leverage_limit", strconv.FormatFloat(crossLeverageLimit, 'f', -1, 64)) } var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateLeverageDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/leverage", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateLeverageDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/leverage", params, nil, &response) } // UpdatePositionRiskLimitInDualMode update position risk limit in dual mode -func (g *Gateio) UpdatePositionRiskLimitInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit float64) ([]Position, error) { +func (e *Exchange) UpdatePositionRiskLimitInDualMode(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit float64) ([]Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2225,7 +2225,7 @@ func (g *Gateio) UpdatePositionRiskLimitInDualMode(ctx context.Context, settle c params := url.Values{} params.Set("risk_limit", strconv.FormatFloat(riskLimit, 'f', -1, 64)) var response []Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateRiskDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/risk_limit", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualUpdateRiskDualModeEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/dual_comp/positions/"+contract.String()+"/risk_limit", params, nil, &response) } // PlaceFuturesOrder creates futures order @@ -2235,7 +2235,7 @@ func (g *Gateio) UpdatePositionRiskLimitInDualMode(ctx context.Context, settle c // Set reduce_only to true can keep the position from changing side when reducing position size // In single position mode, to close a position, you need to set size to 0 and close to true // In dual position mode, to close one side position, you need to set auto_size side, reduce_only to true and size to 0 -func (g *Gateio) PlaceFuturesOrder(ctx context.Context, arg *ContractOrderCreateParams) (*Order, error) { +func (e *Exchange) PlaceFuturesOrder(ctx context.Context, arg *ContractOrderCreateParams) (*Order, error) { if arg == nil { return nil, errNilArgument } @@ -2262,12 +2262,12 @@ func (g *Gateio) PlaceFuturesOrder(ctx context.Context, arg *ContractOrderCreate } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitOrderEPL, http.MethodPost, futuresPath+arg.Settle.Item.Lower+ordersPath, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitOrderEPL, http.MethodPost, futuresPath+arg.Settle.Item.Lower+ordersPath, nil, &arg, &response) } // GetFuturesOrders retrieves list of futures orders // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) GetFuturesOrders(ctx context.Context, contract currency.Pair, status, lastID string, settle currency.Code, limit, offset uint64, countTotal int64) ([]Order, error) { +func (e *Exchange) GetFuturesOrders(ctx context.Context, contract currency.Pair, status, lastID string, settle currency.Code, limit, offset uint64, countTotal int64) ([]Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2294,12 +2294,12 @@ func (g *Gateio) GetFuturesOrders(ctx context.Context, contract currency.Pair, s return nil, errInvalidCountTotalValue } var response []Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetOrdersEPL, http.MethodGet, futuresPath+settle.Item.Lower+ordersPath, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetOrdersEPL, http.MethodGet, futuresPath+settle.Item.Lower+ordersPath, params, nil, &response) } // CancelMultipleFuturesOpenOrders ancel all open orders // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) CancelMultipleFuturesOpenOrders(ctx context.Context, contract currency.Pair, side string, settle currency.Code) ([]Order, error) { +func (e *Exchange) CancelMultipleFuturesOpenOrders(ctx context.Context, contract currency.Pair, side string, settle currency.Code) ([]Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2312,7 +2312,7 @@ func (g *Gateio) CancelMultipleFuturesOpenOrders(ctx context.Context, contract c } params.Set("contract", contract.String()) var response []Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetOrdersEPL, http.MethodDelete, futuresPath+settle.Item.Lower+ordersPath, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetOrdersEPL, http.MethodDelete, futuresPath+settle.Item.Lower+ordersPath, params, nil, &response) } // PlaceBatchFuturesOrders creates a list of futures orders @@ -2323,7 +2323,7 @@ func (g *Gateio) CancelMultipleFuturesOpenOrders(ctx context.Context, contract c // In the returned result, the succeeded field of type bool indicates whether the execution was successful or not // If the execution is successful, the normal order content is included; if the execution fails, the label field is included to indicate the cause of the error // In the rate limiting, each order is counted individually -func (g *Gateio) PlaceBatchFuturesOrders(ctx context.Context, settle currency.Code, args []ContractOrderCreateParams) ([]Order, error) { +func (e *Exchange) PlaceBatchFuturesOrders(ctx context.Context, settle currency.Code, args []ContractOrderCreateParams) ([]Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2354,11 +2354,11 @@ func (g *Gateio) PlaceBatchFuturesOrders(ctx context.Context, settle currency.Co } } var response []Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitBatchOrdersEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/batch_orders", nil, &args, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitBatchOrdersEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/batch_orders", nil, &args, &response) } // GetSingleFuturesOrder retrieves a single order by its identifier -func (g *Gateio) GetSingleFuturesOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { +func (e *Exchange) GetSingleFuturesOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2366,11 +2366,11 @@ func (g *Gateio) GetSingleFuturesOrder(ctx context.Context, settle currency.Code return nil, fmt.Errorf("%w, 'order_id' cannot be empty", errInvalidOrderID) } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualFetchOrderEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualFetchOrderEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) } // CancelSingleFuturesOrder cancel a single order -func (g *Gateio) CancelSingleFuturesOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { +func (e *Exchange) CancelSingleFuturesOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2378,11 +2378,11 @@ func (g *Gateio) CancelSingleFuturesOrder(ctx context.Context, settle currency.C return nil, fmt.Errorf("%w, 'order_id' cannot be empty", errInvalidOrderID) } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelOrderEPL, http.MethodDelete, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelOrderEPL, http.MethodDelete, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) } // AmendFuturesOrder amends an existing futures order -func (g *Gateio) AmendFuturesOrder(ctx context.Context, settle currency.Code, orderID string, arg AmendFuturesOrderParam) (*Order, error) { +func (e *Exchange) AmendFuturesOrder(ctx context.Context, settle currency.Code, orderID string, arg AmendFuturesOrderParam) (*Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2393,11 +2393,11 @@ func (g *Gateio) AmendFuturesOrder(ctx context.Context, settle currency.Code, or return nil, errors.New("missing update 'size' or 'price', please specify 'size' or 'price' or both information") } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAmendOrderEPL, http.MethodPut, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualAmendOrderEPL, http.MethodPut, futuresPath+settle.Item.Lower+"/orders/"+orderID, nil, &arg, &response) } // GetMyFuturesTradingHistory retrieves authenticated account's futures trading history -func (g *Gateio) GetMyFuturesTradingHistory(ctx context.Context, settle currency.Code, lastID, orderID string, contract currency.Pair, limit, offset, countTotal uint64) ([]TradingHistoryItem, error) { +func (e *Exchange) GetMyFuturesTradingHistory(ctx context.Context, settle currency.Code, lastID, orderID string, contract currency.Pair, limit, offset, countTotal uint64) ([]TradingHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2421,11 +2421,11 @@ func (g *Gateio) GetMyFuturesTradingHistory(ctx context.Context, settle currency params.Set("count_total", strconv.FormatUint(countTotal, 10)) } var response []TradingHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualTradingHistoryEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/my_trades", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualTradingHistoryEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/my_trades", params, nil, &response) } // GetFuturesPositionCloseHistory lists position close history -func (g *Gateio) GetFuturesPositionCloseHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, from, to time.Time) ([]PositionCloseHistoryResponse, error) { +func (e *Exchange) GetFuturesPositionCloseHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, from, to time.Time) ([]PositionCloseHistoryResponse, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2446,11 +2446,11 @@ func (g *Gateio) GetFuturesPositionCloseHistory(ctx context.Context, settle curr params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var response []PositionCloseHistoryResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualClosePositionEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/position_close", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualClosePositionEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/position_close", params, nil, &response) } // GetFuturesLiquidationHistory list liquidation history -func (g *Gateio) GetFuturesLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]LiquidationHistoryItem, error) { +func (e *Exchange) GetFuturesLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]LiquidationHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2465,11 +2465,11 @@ func (g *Gateio) GetFuturesLiquidationHistory(ctx context.Context, settle curren params.Set("at", strconv.FormatInt(at.Unix(), 10)) } var response []LiquidationHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualLiquidationHistoryEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/liquidates", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualLiquidationHistoryEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/liquidates", params, nil, &response) } // CountdownCancelOrders represents a trigger time response -func (g *Gateio) CountdownCancelOrders(ctx context.Context, settle currency.Code, arg CountdownParams) (*TriggerTimeResponse, error) { +func (e *Exchange) CountdownCancelOrders(ctx context.Context, settle currency.Code, arg CountdownParams) (*TriggerTimeResponse, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2477,11 +2477,11 @@ func (g *Gateio) CountdownCancelOrders(ctx context.Context, settle currency.Code return nil, errInvalidTimeout } var response *TriggerTimeResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelTriggerOrdersEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/countdown_cancel_all", nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelTriggerOrdersEPL, http.MethodPost, futuresPath+settle.Item.Lower+"/countdown_cancel_all", nil, &arg, &response) } // CreatePriceTriggeredFuturesOrder create a price-triggered order -func (g *Gateio) CreatePriceTriggeredFuturesOrder(ctx context.Context, settle currency.Code, arg *FuturesPriceTriggeredOrderParam) (*OrderID, error) { +func (e *Exchange) CreatePriceTriggeredFuturesOrder(ctx context.Context, settle currency.Code, arg *FuturesPriceTriggeredOrderParam) (*OrderID, error) { if arg == nil { return nil, errNilArgument } @@ -2516,11 +2516,11 @@ func (g *Gateio) CreatePriceTriggeredFuturesOrder(ctx context.Context, settle cu return nil, errors.New("invalid order type, only 'close-long-order', 'close-short-order', 'close-long-position', 'close-short-position', 'plan-close-long-position', and 'plan-close-short-position'") } var response *OrderID - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitTriggerOrderEPL, http.MethodPost, futuresPath+settle.Item.Lower+priceOrdersPaths, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualSubmitTriggerOrderEPL, http.MethodPost, futuresPath+settle.Item.Lower+priceOrdersPaths, nil, &arg, &response) } // ListAllFuturesAutoOrders lists all open orders -func (g *Gateio) ListAllFuturesAutoOrders(ctx context.Context, status string, settle currency.Code, contract currency.Pair, limit, offset uint64) ([]PriceTriggeredOrder, error) { +func (e *Exchange) ListAllFuturesAutoOrders(ctx context.Context, status string, settle currency.Code, contract currency.Pair, limit, offset uint64) ([]PriceTriggeredOrder, error) { if status != statusOpen && status != statusFinished { return nil, fmt.Errorf("%w status: %s", errInvalidOrderStatus, status) } @@ -2539,11 +2539,11 @@ func (g *Gateio) ListAllFuturesAutoOrders(ctx context.Context, status string, se params.Set("contract", contract.String()) } var response []PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualListOpenOrdersEPL, http.MethodGet, futuresPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualListOpenOrdersEPL, http.MethodGet, futuresPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) } // CancelAllFuturesOpenOrders cancels all futures open orders -func (g *Gateio) CancelAllFuturesOpenOrders(ctx context.Context, settle currency.Code, contract currency.Pair) ([]PriceTriggeredOrder, error) { +func (e *Exchange) CancelAllFuturesOpenOrders(ctx context.Context, settle currency.Code, contract currency.Pair) ([]PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2553,11 +2553,11 @@ func (g *Gateio) CancelAllFuturesOpenOrders(ctx context.Context, settle currency params := url.Values{} params.Set("contract", contract.String()) var response []PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelOpenOrdersEPL, http.MethodDelete, futuresPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelOpenOrdersEPL, http.MethodDelete, futuresPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) } // GetSingleFuturesPriceTriggeredOrder retrieves a single price triggered order -func (g *Gateio) GetSingleFuturesPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { +func (e *Exchange) GetSingleFuturesPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2565,11 +2565,11 @@ func (g *Gateio) GetSingleFuturesPriceTriggeredOrder(ctx context.Context, settle return nil, errInvalidOrderID } var response *PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetTriggerOrderEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualGetTriggerOrderEPL, http.MethodGet, futuresPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) } // CancelFuturesPriceTriggeredOrder cancel a price-triggered order -func (g *Gateio) CancelFuturesPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { +func (e *Exchange) CancelFuturesPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2577,31 +2577,31 @@ func (g *Gateio) CancelFuturesPriceTriggeredOrder(ctx context.Context, settle cu return nil, errInvalidOrderID } var response *PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelTriggerOrderEPL, http.MethodDelete, futuresPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, perpetualCancelTriggerOrderEPL, http.MethodDelete, futuresPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) } // *************************************** Delivery *************************************** // GetAllDeliveryContracts retrieves all futures contracts -func (g *Gateio) GetAllDeliveryContracts(ctx context.Context, settle currency.Code) ([]DeliveryContract, error) { +func (e *Exchange) GetAllDeliveryContracts(ctx context.Context, settle currency.Code) ([]DeliveryContract, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var contracts []DeliveryContract - return contracts, g.SendHTTPRequest(ctx, exchange.RestSpot, publicDeliveryContractsEPL, deliveryPath+settle.Item.Lower+"/contracts", &contracts) + return contracts, e.SendHTTPRequest(ctx, exchange.RestSpot, publicDeliveryContractsEPL, deliveryPath+settle.Item.Lower+"/contracts", &contracts) } // GetDeliveryContract retrieves a single delivery contract instance -func (g *Gateio) GetDeliveryContract(ctx context.Context, settle currency.Code, contract currency.Pair) (*DeliveryContract, error) { +func (e *Exchange) GetDeliveryContract(ctx context.Context, settle currency.Code, contract currency.Pair) (*DeliveryContract, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var deliveryContract *DeliveryContract - return deliveryContract, g.SendHTTPRequest(ctx, exchange.RestSpot, publicDeliveryContractsEPL, deliveryPath+settle.Item.Lower+"/contracts/"+contract.String(), &deliveryContract) + return deliveryContract, e.SendHTTPRequest(ctx, exchange.RestSpot, publicDeliveryContractsEPL, deliveryPath+settle.Item.Lower+"/contracts/"+contract.String(), &deliveryContract) } // GetDeliveryOrderbook delivery orderbook -func (g *Gateio) GetDeliveryOrderbook(ctx context.Context, settle currency.Code, interval string, contract currency.Pair, limit uint64, withOrderbookID bool) (*Orderbook, error) { +func (e *Exchange) GetDeliveryOrderbook(ctx context.Context, settle currency.Code, interval string, contract currency.Pair, limit uint64, withOrderbookID bool) (*Orderbook, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2620,11 +2620,11 @@ func (g *Gateio) GetDeliveryOrderbook(ctx context.Context, settle currency.Code, params.Set("with_id", strconv.FormatBool(withOrderbookID)) } var orderbook *Orderbook - return orderbook, g.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/order_book", params), &orderbook) + return orderbook, e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/order_book", params), &orderbook) } // GetDeliveryTradingHistory retrieves futures trading history -func (g *Gateio) GetDeliveryTradingHistory(ctx context.Context, settle currency.Code, lastID string, contract currency.Pair, limit uint64, from, to time.Time) ([]TradingHistoryItem, error) { +func (e *Exchange) GetDeliveryTradingHistory(ctx context.Context, settle currency.Code, lastID string, contract currency.Pair, limit uint64, from, to time.Time) ([]TradingHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2646,11 +2646,11 @@ func (g *Gateio) GetDeliveryTradingHistory(ctx context.Context, settle currency. params.Set("last_id", lastID) } var histories []TradingHistoryItem - return histories, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTradingHistoryDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/trades", params), &histories) + return histories, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTradingHistoryDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/trades", params), &histories) } // GetDeliveryFuturesCandlesticks retrieves specified contract candlesticks -func (g *Gateio) GetDeliveryFuturesCandlesticks(ctx context.Context, settle currency.Code, contract currency.Pair, from, to time.Time, limit uint64, interval kline.Interval) ([]FuturesCandlestick, error) { +func (e *Exchange) GetDeliveryFuturesCandlesticks(ctx context.Context, settle currency.Code, contract currency.Pair, from, to time.Time, limit uint64, interval kline.Interval) ([]FuturesCandlestick, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2676,11 +2676,11 @@ func (g *Gateio) GetDeliveryFuturesCandlesticks(ctx context.Context, settle curr params.Set("interval", intervalString) } var candlesticks []FuturesCandlestick - return candlesticks, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleSticksDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/candlesticks", params), &candlesticks) + return candlesticks, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleSticksDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/candlesticks", params), &candlesticks) } // GetDeliveryFutureTickers retrieves futures ticker information for a specific settle and contract info. -func (g *Gateio) GetDeliveryFutureTickers(ctx context.Context, settle currency.Code, contract currency.Pair) ([]FuturesTicker, error) { +func (e *Exchange) GetDeliveryFutureTickers(ctx context.Context, settle currency.Code, contract currency.Pair) ([]FuturesTicker, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2689,11 +2689,11 @@ func (g *Gateio) GetDeliveryFutureTickers(ctx context.Context, settle currency.C params.Set("contract", contract.String()) } var tickers []FuturesTicker - return tickers, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/tickers", params), &tickers) + return tickers, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTickersDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/tickers", params), &tickers) } // GetDeliveryInsuranceBalanceHistory retrieves delivery futures insurance balance history -func (g *Gateio) GetDeliveryInsuranceBalanceHistory(ctx context.Context, settle currency.Code, limit uint64) ([]InsuranceBalance, error) { +func (e *Exchange) GetDeliveryInsuranceBalanceHistory(ctx context.Context, settle currency.Code, limit uint64) ([]InsuranceBalance, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2702,20 +2702,20 @@ func (g *Gateio) GetDeliveryInsuranceBalanceHistory(ctx context.Context, settle params.Set("limit", strconv.FormatUint(limit, 10)) } var balances []InsuranceBalance - return balances, g.SendHTTPRequest(ctx, exchange.RestSpot, publicInsuranceDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/insurance", params), &balances) + return balances, e.SendHTTPRequest(ctx, exchange.RestSpot, publicInsuranceDeliveryEPL, common.EncodeURLValues(deliveryPath+settle.Item.Lower+"/insurance", params), &balances) } // GetDeliveryFuturesAccounts retrieves futures account -func (g *Gateio) GetDeliveryFuturesAccounts(ctx context.Context, settle currency.Code) (*FuturesAccount, error) { +func (e *Exchange) GetDeliveryFuturesAccounts(ctx context.Context, settle currency.Code) (*FuturesAccount, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var response *FuturesAccount - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAccountEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/accounts", nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAccountEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/accounts", nil, nil, &response) } // GetDeliveryAccountBooks retrieves account books -func (g *Gateio) GetDeliveryAccountBooks(ctx context.Context, settle currency.Code, limit uint64, from, to time.Time, changingType string) ([]AccountBookItem, error) { +func (e *Exchange) GetDeliveryAccountBooks(ctx context.Context, settle currency.Code, limit uint64, from, to time.Time, changingType string) ([]AccountBookItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2733,20 +2733,20 @@ func (g *Gateio) GetDeliveryAccountBooks(ctx context.Context, settle currency.Co params.Set("type", changingType) } var response []AccountBookItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAccountBooksEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/account_book", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAccountBooksEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/account_book", params, nil, &response) } // GetAllDeliveryPositionsOfUser retrieves all positions of user -func (g *Gateio) GetAllDeliveryPositionsOfUser(ctx context.Context, settle currency.Code) (*Position, error) { +func (e *Exchange) GetAllDeliveryPositionsOfUser(ctx context.Context, settle currency.Code) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryPositionsEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/positions", nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryPositionsEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/positions", nil, nil, &response) } // GetSingleDeliveryPosition get single position -func (g *Gateio) GetSingleDeliveryPosition(ctx context.Context, settle currency.Code, contract currency.Pair) (*Position, error) { +func (e *Exchange) GetSingleDeliveryPosition(ctx context.Context, settle currency.Code, contract currency.Pair) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2754,11 +2754,11 @@ func (g *Gateio) GetSingleDeliveryPosition(ctx context.Context, settle currency. return nil, fmt.Errorf("%w, currency pair for contract must not be empty", errInvalidOrMissingContractParam) } var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryPositionsEPL, http.MethodGet, deliveryPath+settle.Item.Lower+positionsPath+contract.String(), nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryPositionsEPL, http.MethodGet, deliveryPath+settle.Item.Lower+positionsPath+contract.String(), nil, nil, &response) } // UpdateDeliveryPositionMargin updates position margin -func (g *Gateio) UpdateDeliveryPositionMargin(ctx context.Context, settle currency.Code, change float64, contract currency.Pair) (*Position, error) { +func (e *Exchange) UpdateDeliveryPositionMargin(ctx context.Context, settle currency.Code, change float64, contract currency.Pair) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2771,11 +2771,11 @@ func (g *Gateio) UpdateDeliveryPositionMargin(ctx context.Context, settle curren params := url.Values{} params.Set("change", strconv.FormatFloat(change, 'f', -1, 64)) var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryUpdateMarginEPL, http.MethodPost, deliveryPath+settle.Item.Lower+positionsPath+contract.String()+"/margin", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryUpdateMarginEPL, http.MethodPost, deliveryPath+settle.Item.Lower+positionsPath+contract.String()+"/margin", params, nil, &response) } // UpdateDeliveryPositionLeverage updates position leverage -func (g *Gateio) UpdateDeliveryPositionLeverage(ctx context.Context, settle currency.Code, contract currency.Pair, leverage float64) (*Position, error) { +func (e *Exchange) UpdateDeliveryPositionLeverage(ctx context.Context, settle currency.Code, contract currency.Pair, leverage float64) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2788,12 +2788,12 @@ func (g *Gateio) UpdateDeliveryPositionLeverage(ctx context.Context, settle curr params := url.Values{} params.Set("leverage", strconv.FormatFloat(leverage, 'f', -1, 64)) var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryUpdateLeverageEPL, http.MethodPost, deliveryPath+settle.Item.Lower+positionsPath+contract.String()+"/leverage", params, nil, &response) } // UpdateDeliveryPositionRiskLimit update position risk limit -func (g *Gateio) UpdateDeliveryPositionRiskLimit(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit uint64) (*Position, error) { +func (e *Exchange) UpdateDeliveryPositionRiskLimit(ctx context.Context, settle currency.Code, contract currency.Pair, riskLimit uint64) (*Position, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2803,12 +2803,12 @@ func (g *Gateio) UpdateDeliveryPositionRiskLimit(ctx context.Context, settle cur params := url.Values{} params.Set("risk_limit", strconv.FormatUint(riskLimit, 10)) var response *Position - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryUpdateRiskLimitEPL, http.MethodPost, deliveryPath+settle.Item.Lower+positionsPath+contract.String()+"/risk_limit", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryUpdateRiskLimitEPL, http.MethodPost, deliveryPath+settle.Item.Lower+positionsPath+contract.String()+"/risk_limit", params, nil, &response) } // PlaceDeliveryOrder create a futures order // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) PlaceDeliveryOrder(ctx context.Context, arg *ContractOrderCreateParams) (*Order, error) { +func (e *Exchange) PlaceDeliveryOrder(ctx context.Context, arg *ContractOrderCreateParams) (*Order, error) { if arg == nil { return nil, errNilArgument } @@ -2831,12 +2831,12 @@ func (g *Gateio) PlaceDeliveryOrder(ctx context.Context, arg *ContractOrderCreat return nil, errEmptyOrInvalidSettlementCurrency } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliverySubmitOrderEPL, http.MethodPost, deliveryPath+arg.Settle.Item.Lower+ordersPath, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliverySubmitOrderEPL, http.MethodPost, deliveryPath+arg.Settle.Item.Lower+ordersPath, nil, &arg, &response) } // GetDeliveryOrders list futures orders // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) GetDeliveryOrders(ctx context.Context, contract currency.Pair, status string, settle currency.Code, lastID string, limit, offset uint64, countTotal int64) ([]Order, error) { +func (e *Exchange) GetDeliveryOrders(ctx context.Context, contract currency.Pair, status string, settle currency.Code, lastID string, limit, offset uint64, countTotal int64) ([]Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2863,12 +2863,12 @@ func (g *Gateio) GetDeliveryOrders(ctx context.Context, contract currency.Pair, return nil, errInvalidCountTotalValue } var response []Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetOrdersEPL, http.MethodGet, deliveryPath+settle.Item.Lower+ordersPath, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetOrdersEPL, http.MethodGet, deliveryPath+settle.Item.Lower+ordersPath, params, nil, &response) } // CancelMultipleDeliveryOrders cancel all open orders matched // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) CancelMultipleDeliveryOrders(ctx context.Context, contract currency.Pair, side string, settle currency.Code) ([]Order, error) { +func (e *Exchange) CancelMultipleDeliveryOrders(ctx context.Context, contract currency.Pair, side string, settle currency.Code) ([]Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2881,12 +2881,12 @@ func (g *Gateio) CancelMultipleDeliveryOrders(ctx context.Context, contract curr } params.Set("contract", contract.String()) var response []Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelOrdersEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+ordersPath, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelOrdersEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+ordersPath, params, nil, &response) } // GetSingleDeliveryOrder Get a single order // Zero-filled order cannot be retrieved 10 minutes after order cancellation -func (g *Gateio) GetSingleDeliveryOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { +func (e *Exchange) GetSingleDeliveryOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2894,11 +2894,11 @@ func (g *Gateio) GetSingleDeliveryOrder(ctx context.Context, settle currency.Cod return nil, fmt.Errorf("%w, 'order_id' cannot be empty", errInvalidOrderID) } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetOrderEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetOrderEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) } // CancelSingleDeliveryOrder cancel a single order -func (g *Gateio) CancelSingleDeliveryOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { +func (e *Exchange) CancelSingleDeliveryOrder(ctx context.Context, settle currency.Code, orderID string) (*Order, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2906,11 +2906,11 @@ func (g *Gateio) CancelSingleDeliveryOrder(ctx context.Context, settle currency. return nil, fmt.Errorf("%w, 'order_id' cannot be empty", errInvalidOrderID) } var response *Order - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelOrderEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelOrderEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+"/orders/"+orderID, nil, nil, &response) } // GetMyDeliveryTradingHistory retrieves authenticated account delivery futures trading history -func (g *Gateio) GetMyDeliveryTradingHistory(ctx context.Context, settle currency.Code, orderID string, contract currency.Pair, limit, offset, countTotal uint64, lastID string) ([]TradingHistoryItem, error) { +func (e *Exchange) GetMyDeliveryTradingHistory(ctx context.Context, settle currency.Code, orderID string, contract currency.Pair, limit, offset, countTotal uint64, lastID string) ([]TradingHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2934,11 +2934,11 @@ func (g *Gateio) GetMyDeliveryTradingHistory(ctx context.Context, settle currenc params.Set("count_total", strconv.FormatUint(countTotal, 10)) } var response []TradingHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryTradingHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/my_trades", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryTradingHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/my_trades", params, nil, &response) } // GetDeliveryPositionCloseHistory retrieves position history -func (g *Gateio) GetDeliveryPositionCloseHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, from, to time.Time) ([]PositionCloseHistoryResponse, error) { +func (e *Exchange) GetDeliveryPositionCloseHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit, offset uint64, from, to time.Time) ([]PositionCloseHistoryResponse, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2959,11 +2959,11 @@ func (g *Gateio) GetDeliveryPositionCloseHistory(ctx context.Context, settle cur params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var response []PositionCloseHistoryResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCloseHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/position_close", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCloseHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/position_close", params, nil, &response) } // GetDeliveryLiquidationHistory lists liquidation history -func (g *Gateio) GetDeliveryLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]LiquidationHistoryItem, error) { +func (e *Exchange) GetDeliveryLiquidationHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]LiquidationHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2978,11 +2978,11 @@ func (g *Gateio) GetDeliveryLiquidationHistory(ctx context.Context, settle curre params.Set("at", strconv.FormatInt(at.Unix(), 10)) } var response []LiquidationHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryLiquidationHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/liquidates", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryLiquidationHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/liquidates", params, nil, &response) } // GetDeliverySettlementHistory retrieves settlement history -func (g *Gateio) GetDeliverySettlementHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]SettlementHistoryItem, error) { +func (e *Exchange) GetDeliverySettlementHistory(ctx context.Context, settle currency.Code, contract currency.Pair, limit uint64, at time.Time) ([]SettlementHistoryItem, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -2997,11 +2997,11 @@ func (g *Gateio) GetDeliverySettlementHistory(ctx context.Context, settle curren params.Set("at", strconv.FormatInt(at.Unix(), 10)) } var response []SettlementHistoryItem - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliverySettlementHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/settlements", params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliverySettlementHistoryEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/settlements", params, nil, &response) } // GetDeliveryPriceTriggeredOrder creates a price-triggered order -func (g *Gateio) GetDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, arg *FuturesPriceTriggeredOrderParam) (*OrderID, error) { +func (e *Exchange) GetDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, arg *FuturesPriceTriggeredOrderParam) (*OrderID, error) { if arg == nil { return nil, errNilArgument } @@ -3043,11 +3043,11 @@ func (g *Gateio) GetDeliveryPriceTriggeredOrder(ctx context.Context, settle curr return nil, errors.New("invalid order type, only 'close-long-order', 'close-short-order', 'close-long-position', 'close-short-position', 'plan-close-long-position', and 'plan-close-short-position'") } var response *OrderID - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetTriggerOrderEPL, http.MethodPost, deliveryPath+settle.Item.Lower+priceOrdersPaths, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetTriggerOrderEPL, http.MethodPost, deliveryPath+settle.Item.Lower+priceOrdersPaths, nil, &arg, &response) } // GetDeliveryAllAutoOrder retrieves all auto orders -func (g *Gateio) GetDeliveryAllAutoOrder(ctx context.Context, status string, settle currency.Code, contract currency.Pair, limit, offset uint64) ([]PriceTriggeredOrder, error) { +func (e *Exchange) GetDeliveryAllAutoOrder(ctx context.Context, status string, settle currency.Code, contract currency.Pair, limit, offset uint64) ([]PriceTriggeredOrder, error) { if status != statusOpen && status != statusFinished { return nil, fmt.Errorf("%w status %s", errInvalidOrderStatus, status) } @@ -3066,11 +3066,11 @@ func (g *Gateio) GetDeliveryAllAutoOrder(ctx context.Context, status string, set params.Set("contract", contract.String()) } var response []PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAutoOrdersEPL, http.MethodGet, deliveryPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryAutoOrdersEPL, http.MethodGet, deliveryPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) } // CancelAllDeliveryPriceTriggeredOrder cancels all delivery price triggered orders -func (g *Gateio) CancelAllDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, contract currency.Pair) ([]PriceTriggeredOrder, error) { +func (e *Exchange) CancelAllDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, contract currency.Pair) ([]PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -3080,11 +3080,11 @@ func (g *Gateio) CancelAllDeliveryPriceTriggeredOrder(ctx context.Context, settl params := url.Values{} params.Set("contract", contract.String()) var response []PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelTriggerOrdersEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelTriggerOrdersEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+priceOrdersPaths, params, nil, &response) } // GetSingleDeliveryPriceTriggeredOrder retrieves a single price triggered order -func (g *Gateio) GetSingleDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { +func (e *Exchange) GetSingleDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -3092,11 +3092,11 @@ func (g *Gateio) GetSingleDeliveryPriceTriggeredOrder(ctx context.Context, settl return nil, errInvalidOrderID } var response *PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetTriggerOrderEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryGetTriggerOrderEPL, http.MethodGet, deliveryPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) } // CancelDeliveryPriceTriggeredOrder cancel a price-triggered order -func (g *Gateio) CancelDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { +func (e *Exchange) CancelDeliveryPriceTriggeredOrder(ctx context.Context, settle currency.Code, orderID string) (*PriceTriggeredOrder, error) { if settle.IsEmpty() { return nil, errEmptyOrInvalidSettlementCurrency } @@ -3104,24 +3104,24 @@ func (g *Gateio) CancelDeliveryPriceTriggeredOrder(ctx context.Context, settle c return nil, errInvalidOrderID } var response *PriceTriggeredOrder - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelTriggerOrderEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, deliveryCancelTriggerOrderEPL, http.MethodDelete, deliveryPath+settle.Item.Lower+"/price_orders/"+orderID, nil, nil, &response) } // ********************************** Options *************************************************** // GetAllOptionsUnderlyings retrieves all option underlyings -func (g *Gateio) GetAllOptionsUnderlyings(ctx context.Context) ([]OptionUnderlying, error) { +func (e *Exchange) GetAllOptionsUnderlyings(ctx context.Context) ([]OptionUnderlying, error) { var response []OptionUnderlying - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicUnderlyingOptionsEPL, gateioOptionUnderlyings, &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicUnderlyingOptionsEPL, gateioOptionUnderlyings, &response) } // GetExpirationTime return the expiration time for the provided underlying. -func (g *Gateio) GetExpirationTime(ctx context.Context, underlying string) (time.Time, error) { +func (e *Exchange) GetExpirationTime(ctx context.Context, underlying string) (time.Time, error) { if underlying == "" { return time.Time{}, errInvalidUnderlying } var timestamps []types.Time - err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicExpirationOptionsEPL, gateioOptionExpiration+"?underlying="+underlying, ×tamps) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicExpirationOptionsEPL, gateioOptionExpiration+"?underlying="+underlying, ×tamps) if err != nil { return time.Time{}, err } @@ -3132,7 +3132,7 @@ func (g *Gateio) GetExpirationTime(ctx context.Context, underlying string) (time } // GetAllContractOfUnderlyingWithinExpiryDate retrieves list of contracts of the specified underlying and expiry time. -func (g *Gateio) GetAllContractOfUnderlyingWithinExpiryDate(ctx context.Context, underlying string, expTime time.Time) ([]OptionContract, error) { +func (e *Exchange) GetAllContractOfUnderlyingWithinExpiryDate(ctx context.Context, underlying string, expTime time.Time) ([]OptionContract, error) { params := url.Values{} if underlying == "" { return nil, errInvalidUnderlying @@ -3142,20 +3142,20 @@ func (g *Gateio) GetAllContractOfUnderlyingWithinExpiryDate(ctx context.Context, params.Set("expires", strconv.FormatInt(expTime.Unix(), 10)) } var contracts []OptionContract - return contracts, g.SendHTTPRequest(ctx, exchange.RestSpot, publicContractsOptionsEPL, common.EncodeURLValues(gateioOptionContracts, params), &contracts) + return contracts, e.SendHTTPRequest(ctx, exchange.RestSpot, publicContractsOptionsEPL, common.EncodeURLValues(gateioOptionContracts, params), &contracts) } // GetOptionsSpecifiedContractDetail query specified contract detail -func (g *Gateio) GetOptionsSpecifiedContractDetail(ctx context.Context, contract currency.Pair) (*OptionContract, error) { +func (e *Exchange) GetOptionsSpecifiedContractDetail(ctx context.Context, contract currency.Pair) (*OptionContract, error) { if contract.IsInvalid() { return nil, errInvalidOrMissingContractParam } var contr *OptionContract - return contr, g.SendHTTPRequest(ctx, exchange.RestSpot, publicContractsOptionsEPL, gateioOptionContracts+"/"+contract.String(), &contr) + return contr, e.SendHTTPRequest(ctx, exchange.RestSpot, publicContractsOptionsEPL, gateioOptionContracts+"/"+contract.String(), &contr) } // GetSettlementHistory retrieves list of settlement history -func (g *Gateio) GetSettlementHistory(ctx context.Context, underlying string, offset, limit uint64, from, to time.Time) ([]OptionSettlement, error) { +func (e *Exchange) GetSettlementHistory(ctx context.Context, underlying string, offset, limit uint64, from, to time.Time) ([]OptionSettlement, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3174,11 +3174,11 @@ func (g *Gateio) GetSettlementHistory(ctx context.Context, underlying string, of params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var settlements []OptionSettlement - return settlements, g.SendHTTPRequest(ctx, exchange.RestSpot, publicSettlementOptionsEPL, common.EncodeURLValues(gateioOptionSettlement, params), &settlements) + return settlements, e.SendHTTPRequest(ctx, exchange.RestSpot, publicSettlementOptionsEPL, common.EncodeURLValues(gateioOptionSettlement, params), &settlements) } // GetOptionsSpecifiedContractsSettlement retrieve a single contract settlement detail passing the underlying and contract name -func (g *Gateio) GetOptionsSpecifiedContractsSettlement(ctx context.Context, contract currency.Pair, underlying string, at int64) (*OptionSettlement, error) { +func (e *Exchange) GetOptionsSpecifiedContractsSettlement(ctx context.Context, contract currency.Pair, underlying string, at int64) (*OptionSettlement, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3189,11 +3189,11 @@ func (g *Gateio) GetOptionsSpecifiedContractsSettlement(ctx context.Context, con params.Set("underlying", underlying) params.Set("at", strconv.FormatInt(at, 10)) var settlement *OptionSettlement - return settlement, g.SendHTTPRequest(ctx, exchange.RestSpot, publicSettlementOptionsEPL, common.EncodeURLValues(gateioOptionSettlement+"/"+contract.String(), params), &settlement) + return settlement, e.SendHTTPRequest(ctx, exchange.RestSpot, publicSettlementOptionsEPL, common.EncodeURLValues(gateioOptionSettlement+"/"+contract.String(), params), &settlement) } // GetMyOptionsSettlements retrieves accounts option settlements. -func (g *Gateio) GetMyOptionsSettlements(ctx context.Context, underlying string, contract currency.Pair, offset, limit uint64, to time.Time) ([]MyOptionSettlement, error) { +func (e *Exchange) GetMyOptionsSettlements(ctx context.Context, underlying string, contract currency.Pair, offset, limit uint64, to time.Time) ([]MyOptionSettlement, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3212,11 +3212,11 @@ func (g *Gateio) GetMyOptionsSettlements(ctx context.Context, underlying string, params.Set("limit", strconv.FormatUint(limit, 10)) } var settlements []MyOptionSettlement - return settlements, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsSettlementsEPL, http.MethodGet, gateioOptionMySettlements, params, nil, &settlements) + return settlements, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsSettlementsEPL, http.MethodGet, gateioOptionMySettlements, params, nil, &settlements) } // GetOptionsOrderbook returns the orderbook data for the given contract. -func (g *Gateio) GetOptionsOrderbook(ctx context.Context, contract currency.Pair, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { +func (e *Exchange) GetOptionsOrderbook(ctx context.Context, contract currency.Pair, interval string, limit uint64, withOrderbookID bool) (*Orderbook, error) { if contract.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -3230,17 +3230,17 @@ func (g *Gateio) GetOptionsOrderbook(ctx context.Context, contract currency.Pair } params.Set("with_id", strconv.FormatBool(withOrderbookID)) var response *Orderbook - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookOptionsEPL, common.EncodeURLValues(gateioOptionsOrderbook, params), &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderbookOptionsEPL, common.EncodeURLValues(gateioOptionsOrderbook, params), &response) } // GetOptionAccounts lists option accounts -func (g *Gateio) GetOptionAccounts(ctx context.Context) (*OptionAccount, error) { +func (e *Exchange) GetOptionAccounts(ctx context.Context) (*OptionAccount, error) { var resp *OptionAccount - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsAccountsEPL, http.MethodGet, gateioOptionAccounts, nil, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsAccountsEPL, http.MethodGet, gateioOptionAccounts, nil, nil, &resp) } // GetAccountChangingHistory retrieves list of account changing history -func (g *Gateio) GetAccountChangingHistory(ctx context.Context, offset, limit uint64, from, to time.Time, changingType string) ([]AccountBook, error) { +func (e *Exchange) GetAccountChangingHistory(ctx context.Context, offset, limit uint64, from, to time.Time, changingType string) ([]AccountBook, error) { params := url.Values{} if changingType != "" { params.Set("type", changingType) @@ -3258,30 +3258,30 @@ func (g *Gateio) GetAccountChangingHistory(ctx context.Context, offset, limit ui params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var accountBook []AccountBook - return accountBook, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsAccountBooksEPL, http.MethodGet, gateioOptionsAccountbook, params, nil, &accountBook) + return accountBook, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsAccountBooksEPL, http.MethodGet, gateioOptionsAccountbook, params, nil, &accountBook) } // GetUsersPositionSpecifiedUnderlying lists user's positions of specified underlying -func (g *Gateio) GetUsersPositionSpecifiedUnderlying(ctx context.Context, underlying string) ([]UsersPositionForUnderlying, error) { +func (e *Exchange) GetUsersPositionSpecifiedUnderlying(ctx context.Context, underlying string) ([]UsersPositionForUnderlying, error) { params := url.Values{} if underlying != "" { params.Set("underlying", underlying) } var response []UsersPositionForUnderlying - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsPositions, http.MethodGet, gateioOptionsPosition, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsPositions, http.MethodGet, gateioOptionsPosition, params, nil, &response) } // GetSpecifiedContractPosition retrieves specified contract position -func (g *Gateio) GetSpecifiedContractPosition(ctx context.Context, contract currency.Pair) (*UsersPositionForUnderlying, error) { +func (e *Exchange) GetSpecifiedContractPosition(ctx context.Context, contract currency.Pair) (*UsersPositionForUnderlying, error) { if contract.IsInvalid() { return nil, errInvalidOrMissingContractParam } var response *UsersPositionForUnderlying - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsPositions, http.MethodGet, gateioOptionsPosition+"/"+contract.String(), nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsPositions, http.MethodGet, gateioOptionsPosition+"/"+contract.String(), nil, nil, &response) } // GetUsersLiquidationHistoryForSpecifiedUnderlying retrieves user's liquidation history of specified underlying -func (g *Gateio) GetUsersLiquidationHistoryForSpecifiedUnderlying(ctx context.Context, underlying string, contract currency.Pair) ([]ContractClosePosition, error) { +func (e *Exchange) GetUsersLiquidationHistoryForSpecifiedUnderlying(ctx context.Context, underlying string, contract currency.Pair) ([]ContractClosePosition, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3291,11 +3291,11 @@ func (g *Gateio) GetUsersLiquidationHistoryForSpecifiedUnderlying(ctx context.Co params.Set("contract", contract.String()) } var response []ContractClosePosition - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsLiquidationHistoryEPL, http.MethodGet, gateioOptionsPositionClose, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsLiquidationHistoryEPL, http.MethodGet, gateioOptionsPositionClose, params, nil, &response) } // PlaceOptionOrder creates an options order -func (g *Gateio) PlaceOptionOrder(ctx context.Context, arg *OptionOrderParam) (*OptionOrderResponse, error) { +func (e *Exchange) PlaceOptionOrder(ctx context.Context, arg *OptionOrderParam) (*OptionOrderResponse, error) { if arg.Contract == "" { return nil, errInvalidOrMissingContractParam } @@ -3312,11 +3312,11 @@ func (g *Gateio) PlaceOptionOrder(ctx context.Context, arg *OptionOrderParam) (* arg.Price = 0 } var response *OptionOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsSubmitOrderEPL, http.MethodPost, gateioOptionsOrders, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsSubmitOrderEPL, http.MethodPost, gateioOptionsOrders, nil, &arg, &response) } // GetOptionFuturesOrders retrieves futures orders -func (g *Gateio) GetOptionFuturesOrders(ctx context.Context, contract currency.Pair, underlying, status string, offset, limit uint64, from, to time.Time) ([]OptionOrderResponse, error) { +func (e *Exchange) GetOptionFuturesOrders(ctx context.Context, contract currency.Pair, underlying, status string, offset, limit uint64, from, to time.Time) ([]OptionOrderResponse, error) { params := url.Values{} if contract.IsPopulated() { params.Set("contract", contract.String()) @@ -3341,11 +3341,11 @@ func (g *Gateio) GetOptionFuturesOrders(ctx context.Context, contract currency.P params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var response []OptionOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsOrdersEPL, http.MethodGet, gateioOptionsOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsOrdersEPL, http.MethodGet, gateioOptionsOrders, params, nil, &response) } // CancelMultipleOptionOpenOrders cancels all open orders matched -func (g *Gateio) CancelMultipleOptionOpenOrders(ctx context.Context, contract currency.Pair, underlying, side string) ([]OptionOrderResponse, error) { +func (e *Exchange) CancelMultipleOptionOpenOrders(ctx context.Context, contract currency.Pair, underlying, side string) ([]OptionOrderResponse, error) { params := url.Values{} if contract.IsPopulated() { params.Set("contract", contract.String()) @@ -3357,29 +3357,29 @@ func (g *Gateio) CancelMultipleOptionOpenOrders(ctx context.Context, contract cu params.Set("side", side) } var response []OptionOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsCancelOrdersEPL, http.MethodDelete, gateioOptionsOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsCancelOrdersEPL, http.MethodDelete, gateioOptionsOrders, params, nil, &response) } // GetSingleOptionOrder retrieves a single option order -func (g *Gateio) GetSingleOptionOrder(ctx context.Context, orderID string) (*OptionOrderResponse, error) { +func (e *Exchange) GetSingleOptionOrder(ctx context.Context, orderID string) (*OptionOrderResponse, error) { if orderID == "" { return nil, errInvalidOrderID } var o *OptionOrderResponse - return o, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsOrderEPL, http.MethodGet, gateioOptionsOrders+"/"+orderID, nil, nil, &o) + return o, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsOrderEPL, http.MethodGet, gateioOptionsOrders+"/"+orderID, nil, nil, &o) } // CancelOptionSingleOrder cancel a single order. -func (g *Gateio) CancelOptionSingleOrder(ctx context.Context, orderID string) (*OptionOrderResponse, error) { +func (e *Exchange) CancelOptionSingleOrder(ctx context.Context, orderID string) (*OptionOrderResponse, error) { if orderID == "" { return nil, errInvalidOrderID } var response *OptionOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsCancelOrderEPL, http.MethodDelete, "options/orders/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsCancelOrderEPL, http.MethodDelete, "options/orders/"+orderID, nil, nil, &response) } // GetMyOptionsTradingHistory retrieves authenticated account's option trading history -func (g *Gateio) GetMyOptionsTradingHistory(ctx context.Context, underlying string, contract currency.Pair, offset, limit uint64, from, to time.Time) ([]OptionTradingHistory, error) { +func (e *Exchange) GetMyOptionsTradingHistory(ctx context.Context, underlying string, contract currency.Pair, offset, limit uint64, from, to time.Time) ([]OptionTradingHistory, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3401,30 +3401,30 @@ func (g *Gateio) GetMyOptionsTradingHistory(ctx context.Context, underlying stri params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var resp []OptionTradingHistory - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsTradingHistoryEPL, http.MethodGet, gateioOptionsMyTrades, params, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, optionsTradingHistoryEPL, http.MethodGet, gateioOptionsMyTrades, params, nil, &resp) } // GetOptionsTickers lists tickers of options contracts -func (g *Gateio) GetOptionsTickers(ctx context.Context, underlying string) ([]OptionsTicker, error) { +func (e *Exchange) GetOptionsTickers(ctx context.Context, underlying string) ([]OptionsTicker, error) { if underlying == "" { return nil, errInvalidUnderlying } underlying = strings.ToUpper(underlying) var response []OptionsTicker - return response, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTickerOptionsEPL, gateioOptionsTickers+"?underlying="+underlying, &response) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTickerOptionsEPL, gateioOptionsTickers+"?underlying="+underlying, &response) } // GetOptionUnderlyingTickers retrieves options underlying ticker -func (g *Gateio) GetOptionUnderlyingTickers(ctx context.Context, underlying string) (*OptionsUnderlyingTicker, error) { +func (e *Exchange) GetOptionUnderlyingTickers(ctx context.Context, underlying string) (*OptionsUnderlyingTicker, error) { if underlying == "" { return nil, errInvalidUnderlying } var respos *OptionsUnderlyingTicker - return respos, g.SendHTTPRequest(ctx, exchange.RestSpot, publicUnderlyingTickerOptionsEPL, "options/underlying/tickers/"+underlying, &respos) + return respos, e.SendHTTPRequest(ctx, exchange.RestSpot, publicUnderlyingTickerOptionsEPL, "options/underlying/tickers/"+underlying, &respos) } // GetOptionFuturesCandlesticks retrieves option futures candlesticks -func (g *Gateio) GetOptionFuturesCandlesticks(ctx context.Context, contract currency.Pair, limit uint64, from, to time.Time, interval kline.Interval) ([]FuturesCandlestick, error) { +func (e *Exchange) GetOptionFuturesCandlesticks(ctx context.Context, contract currency.Pair, limit uint64, from, to time.Time, interval kline.Interval) ([]FuturesCandlestick, error) { if contract.IsInvalid() { return nil, errInvalidOrMissingContractParam } @@ -3445,11 +3445,11 @@ func (g *Gateio) GetOptionFuturesCandlesticks(ctx context.Context, contract curr } params.Set("interval", intervalString) var candles []FuturesCandlestick - return candles, g.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleSticksOptionsEPL, common.EncodeURLValues(gateioOptionCandlesticks, params), &candles) + return candles, e.SendHTTPRequest(ctx, exchange.RestSpot, publicCandleSticksOptionsEPL, common.EncodeURLValues(gateioOptionCandlesticks, params), &candles) } // GetOptionFuturesMarkPriceCandlesticks retrieves mark price candlesticks of an underlying -func (g *Gateio) GetOptionFuturesMarkPriceCandlesticks(ctx context.Context, underlying string, limit uint64, from, to time.Time, interval kline.Interval) ([]FuturesCandlestick, error) { +func (e *Exchange) GetOptionFuturesMarkPriceCandlesticks(ctx context.Context, underlying string, limit uint64, from, to time.Time, interval kline.Interval) ([]FuturesCandlestick, error) { if underlying == "" { return nil, errInvalidUnderlying } @@ -3472,11 +3472,11 @@ func (g *Gateio) GetOptionFuturesMarkPriceCandlesticks(ctx context.Context, unde params.Set("interval", intervalString) } var candles []FuturesCandlestick - return candles, g.SendHTTPRequest(ctx, exchange.RestSpot, publicMarkpriceCandleSticksOptionsEPL, common.EncodeURLValues(gateioOptionUnderlyingCandlesticks, params), &candles) + return candles, e.SendHTTPRequest(ctx, exchange.RestSpot, publicMarkpriceCandleSticksOptionsEPL, common.EncodeURLValues(gateioOptionUnderlyingCandlesticks, params), &candles) } // GetOptionsTradeHistory retrieves options trade history -func (g *Gateio) GetOptionsTradeHistory(ctx context.Context, contract currency.Pair, callType string, offset, limit uint64, from, to time.Time) ([]TradingHistoryItem, error) { +func (e *Exchange) GetOptionsTradeHistory(ctx context.Context, contract currency.Pair, callType string, offset, limit uint64, from, to time.Time) ([]TradingHistoryItem, error) { params := url.Values{} callType = strings.ToUpper(callType) if callType == "C" || callType == "P" { @@ -3498,20 +3498,20 @@ func (g *Gateio) GetOptionsTradeHistory(ctx context.Context, contract currency.P params.Set("to", strconv.FormatInt(to.Unix(), 10)) } var trades []TradingHistoryItem - return trades, g.SendHTTPRequest(ctx, exchange.RestSpot, publicTradeHistoryOptionsEPL, common.EncodeURLValues(gateioOptionsTrades, params), &trades) + return trades, e.SendHTTPRequest(ctx, exchange.RestSpot, publicTradeHistoryOptionsEPL, common.EncodeURLValues(gateioOptionsTrades, params), &trades) } // ********************************** Flash_SWAP ************************* // GetSupportedFlashSwapCurrencies retrieves all supported currencies in flash swap -func (g *Gateio) GetSupportedFlashSwapCurrencies(ctx context.Context) ([]SwapCurrencies, error) { +func (e *Exchange) GetSupportedFlashSwapCurrencies(ctx context.Context) ([]SwapCurrencies, error) { var currencies []SwapCurrencies - return currencies, g.SendHTTPRequest(ctx, exchange.RestSpot, publicFlashSwapEPL, gateioFlashSwapCurrencies, ¤cies) + return currencies, e.SendHTTPRequest(ctx, exchange.RestSpot, publicFlashSwapEPL, gateioFlashSwapCurrencies, ¤cies) } // CreateFlashSwapOrder creates a new flash swap order // initiate a flash swap preview in advance because order creation requires a preview result -func (g *Gateio) CreateFlashSwapOrder(ctx context.Context, arg FlashSwapOrderParams) (*FlashSwapOrderResponse, error) { +func (e *Exchange) CreateFlashSwapOrder(ctx context.Context, arg FlashSwapOrderParams) (*FlashSwapOrderResponse, error) { if arg.PreviewID == "" { return nil, errMissingPreviewID } @@ -3528,11 +3528,11 @@ func (g *Gateio) CreateFlashSwapOrder(ctx context.Context, arg FlashSwapOrderPar return nil, fmt.Errorf("%w, buy_amount amount can not be less than or equal to 0", errInvalidAmount) } var response *FlashSwapOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashSwapOrderEPL, http.MethodPost, gateioFlashSwapOrders, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashSwapOrderEPL, http.MethodPost, gateioFlashSwapOrders, nil, &arg, &response) } // GetAllFlashSwapOrders retrieves list of flash swap orders filtered by the params -func (g *Gateio) GetAllFlashSwapOrders(ctx context.Context, status int, sellCurrency, buyCurrency currency.Code, reverse bool, limit, page uint64) ([]FlashSwapOrderResponse, error) { +func (e *Exchange) GetAllFlashSwapOrders(ctx context.Context, status int, sellCurrency, buyCurrency currency.Code, reverse bool, limit, page uint64) ([]FlashSwapOrderResponse, error) { params := url.Values{} if status == 1 || status == 2 { params.Set("status", strconv.Itoa(status)) @@ -3551,20 +3551,20 @@ func (g *Gateio) GetAllFlashSwapOrders(ctx context.Context, status int, sellCurr params.Set("limit", strconv.FormatUint(limit, 10)) } var response []FlashSwapOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashGetOrdersEPL, http.MethodGet, gateioFlashSwapOrders, params, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashGetOrdersEPL, http.MethodGet, gateioFlashSwapOrders, params, nil, &response) } // GetSingleFlashSwapOrder get a single flash swap order's detail -func (g *Gateio) GetSingleFlashSwapOrder(ctx context.Context, orderID string) (*FlashSwapOrderResponse, error) { +func (e *Exchange) GetSingleFlashSwapOrder(ctx context.Context, orderID string) (*FlashSwapOrderResponse, error) { if orderID == "" { return nil, fmt.Errorf("%w, flash order order_id must not be empty", errInvalidOrderID) } var response *FlashSwapOrderResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashGetOrderEPL, http.MethodGet, gateioFlashSwapOrders+"/"+orderID, nil, nil, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashGetOrderEPL, http.MethodGet, gateioFlashSwapOrders+"/"+orderID, nil, nil, &response) } // InitiateFlashSwapOrderReview initiate a flash swap order preview -func (g *Gateio) InitiateFlashSwapOrderReview(ctx context.Context, arg FlashSwapOrderParams) (*InitFlashSwapOrderPreviewResponse, error) { +func (e *Exchange) InitiateFlashSwapOrderReview(ctx context.Context, arg FlashSwapOrderParams) (*InitFlashSwapOrderPreviewResponse, error) { if arg.PreviewID == "" { return nil, errMissingPreviewID } @@ -3575,15 +3575,15 @@ func (g *Gateio) InitiateFlashSwapOrderReview(ctx context.Context, arg FlashSwap return nil, fmt.Errorf("%w, sell currency can not empty", currency.ErrCurrencyCodeEmpty) } var response *InitFlashSwapOrderPreviewResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashOrderReviewEPL, http.MethodPost, gateioFlashSwapOrdersPreview, nil, &arg, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, flashOrderReviewEPL, http.MethodPost, gateioFlashSwapOrdersPreview, nil, &arg, &response) } // IsValidPairString returns true if the string represents a valid currency pair -func (g *Gateio) IsValidPairString(currencyPair string) bool { +func (e *Exchange) IsValidPairString(currencyPair string) bool { if len(currencyPair) < 3 { return false } - pf, err := g.CurrencyPairs.GetFormat(asset.Spot, true) + pf, err := e.CurrencyPairs.GetFormat(asset.Spot, true) if err != nil { return false } @@ -3597,10 +3597,10 @@ func (g *Gateio) IsValidPairString(currencyPair string) bool { // ********************************* Trading Fee calculation ******************************** // GetFee returns an estimate of fee based on type of transaction -func (g *Gateio) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (fee float64, err error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (fee float64, err error) { switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feePairs, err := g.GetPersonalTradingFee(ctx, feeBuilder.Pair, currency.EMPTYCODE) + feePairs, err := e.GetPersonalTradingFee(ctx, feeBuilder.Pair, currency.EMPTYCODE) if err != nil { return 0, err } @@ -3638,7 +3638,7 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 { } // GetUnderlyingFromCurrencyPair returns an underlying string from a currency pair -func (g *Gateio) GetUnderlyingFromCurrencyPair(p currency.Pair) (currency.Pair, error) { +func (e *Exchange) GetUnderlyingFromCurrencyPair(p currency.Pair) (currency.Pair, error) { pairString := strings.ReplaceAll(p.Upper().String(), currency.DashDelimiter, currency.UnderscoreDelimiter) ccies := strings.Split(pairString, currency.UnderscoreDelimiter) if len(ccies) < 2 { @@ -3648,13 +3648,13 @@ func (g *Gateio) GetUnderlyingFromCurrencyPair(p currency.Pair) (currency.Pair, } // GetAccountDetails retrieves account details -func (g *Gateio) GetAccountDetails(ctx context.Context) (*AccountDetails, error) { +func (e *Exchange) GetAccountDetails(ctx context.Context) (*AccountDetails, error) { var resp *AccountDetails - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, "account/detail", nil, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, "account/detail", nil, nil, &resp) } // GetUserTransactionRateLimitInfo retrieves user transaction rate limit info -func (g *Gateio) GetUserTransactionRateLimitInfo(ctx context.Context) ([]UserTransactionRateLimitInfo, error) { +func (e *Exchange) GetUserTransactionRateLimitInfo(ctx context.Context) ([]UserTransactionRateLimitInfo, error) { var resp []UserTransactionRateLimitInfo - return resp, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, "account/rate_limit", nil, nil, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, spotAccountsEPL, http.MethodGet, "account/rate_limit", nil, nil, &resp) } diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index 264a47db801..f4743f5781c 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -44,18 +44,18 @@ const ( canManipulateRealOrders = false ) -var g *Gateio +var e *Exchange func TestMain(m *testing.M) { - g = new(Gateio) - if err := testexch.Setup(g); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Gateio Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - g.API.AuthenticatedSupport = true - g.API.AuthenticatedWebsocketSupport = true - g.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -63,13 +63,13 @@ func TestMain(m *testing.M) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, g) + testexch.UpdatePairsOnce(t, e) } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelAllOrders(t.Context(), nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllOrders(t.Context(), nil) require.ErrorIs(t, err, order.ErrCancelOrderIsNil) r := &order.Cancel{ @@ -77,35 +77,35 @@ func TestCancelAllExchangeOrders(t *testing.T) { AccountID: "1", } - for _, a := range g.GetAssetTypes(false) { + for _, a := range e.GetAssetTypes(false) { r.AssetType = a r.Pair = currency.EMPTYPAIR - _, err = g.CancelAllOrders(t.Context(), r) + _, err = e.CancelAllOrders(t.Context(), r) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) r.Pair = getPair(t, a) - _, err = g.CancelAllOrders(t.Context(), r) + _, err = e.CancelAllOrders(t.Context(), r) require.NoError(t, err) } } func TestGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - for _, a := range g.GetAssetTypes(false) { - _, err := g.UpdateAccountInfo(t.Context(), a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + for _, a := range e.GetAssetTypes(false) { + _, err := e.UpdateAccountInfo(t.Context(), a) assert.NoErrorf(t, err, "UpdateAccountInfo should not error for asset %s", a) } } func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - cryptocurrencyChains, err := g.GetAvailableTransferChains(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + cryptocurrencyChains, err := e.GetAvailableTransferChains(t.Context(), currency.BTC) require.NoError(t, err, "GetAvailableTransferChains must not error") require.NotEmpty(t, cryptocurrencyChains, "GetAvailableTransferChains must return some chains") withdrawCryptoRequest := withdraw.Request{ - Exchange: g.Name, + Exchange: e.Name, Amount: 1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -114,79 +114,79 @@ func TestWithdraw(t *testing.T) { Chain: cryptocurrencyChains[0], }, } - _, err = g.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) + _, err = e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) require.NoError(t, err) } func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - for _, a := range g.GetAssetTypes(false) { - _, err := g.GetOrderInfo(t.Context(), "917591554", getPair(t, a), a) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + for _, a := range e.GetAssetTypes(false) { + _, err := e.GetOrderInfo(t.Context(), "917591554", getPair(t, a), a) require.NoErrorf(t, err, "GetOrderInfo must not error for asset %s", a) } } func TestUpdateTicker(t *testing.T) { t.Parallel() - for _, a := range g.GetAssetTypes(false) { - _, err := g.UpdateTicker(t.Context(), getPair(t, a), a) + for _, a := range e.GetAssetTypes(false) { + _, err := e.UpdateTicker(t.Context(), getPair(t, a), a) assert.NoErrorf(t, err, "UpdateTicker should not error for %s", a) } } func TestListSpotCurrencies(t *testing.T) { t.Parallel() - if _, err := g.ListSpotCurrencies(t.Context()); err != nil { - t.Errorf("%s ListAllCurrencies() error %v", g.Name, err) + if _, err := e.ListSpotCurrencies(t.Context()); err != nil { + t.Errorf("%s ListAllCurrencies() error %v", e.Name, err) } } func TestGetCurrencyDetail(t *testing.T) { t.Parallel() - if _, err := g.GetCurrencyDetail(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetCurrencyDetail() error %v", g.Name, err) + if _, err := e.GetCurrencyDetail(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetCurrencyDetail() error %v", e.Name, err) } } func TestListAllCurrencyPairs(t *testing.T) { t.Parallel() - if _, err := g.ListSpotCurrencyPairs(t.Context()); err != nil { - t.Errorf("%s ListAllCurrencyPairs() error %v", g.Name, err) + if _, err := e.ListSpotCurrencyPairs(t.Context()); err != nil { + t.Errorf("%s ListAllCurrencyPairs() error %v", e.Name, err) } } func TestGetCurrencyPairDetal(t *testing.T) { t.Parallel() - if _, err := g.GetCurrencyPairDetail(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}.String()); err != nil { - t.Errorf("%s GetCurrencyPairDetal() error %v", g.Name, err) + if _, err := e.GetCurrencyPairDetail(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}.String()); err != nil { + t.Errorf("%s GetCurrencyPairDetal() error %v", e.Name, err) } } func TestGetTickers(t *testing.T) { t.Parallel() - if _, err := g.GetTickers(t.Context(), "BTC_USDT", ""); err != nil { - t.Errorf("%s GetTickers() error %v", g.Name, err) + if _, err := e.GetTickers(t.Context(), "BTC_USDT", ""); err != nil { + t.Errorf("%s GetTickers() error %v", e.Name, err) } } func TestGetTicker(t *testing.T) { t.Parallel() - if _, err := g.GetTicker(t.Context(), currency.Pair{Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT}.String(), utc8TimeZone); err != nil { - t.Errorf("%s GetTicker() error %v", g.Name, err) + if _, err := e.GetTicker(t.Context(), currency.Pair{Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT}.String(), utc8TimeZone); err != nil { + t.Errorf("%s GetTicker() error %v", e.Name, err) } } func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetOrderbook(t.Context(), getPair(t, asset.Spot).String(), "0.1", 10, false) + _, err := e.GetOrderbook(t.Context(), getPair(t, asset.Spot).String(), "0.1", 10, false) assert.NoError(t, err, "GetOrderbook should not error") } func TestGetMarketTrades(t *testing.T) { t.Parallel() - if _, err := g.GetMarketTrades(t.Context(), getPair(t, asset.Spot), 0, "", true, time.Time{}, time.Time{}, 1); err != nil { - t.Errorf("%s GetMarketTrades() error %v", g.Name, err) + if _, err := e.GetMarketTrades(t.Context(), getPair(t, asset.Spot), 0, "", true, time.Time{}, time.Time{}, 1); err != nil { + t.Errorf("%s GetMarketTrades() error %v", e.Name, err) } } @@ -211,37 +211,37 @@ func TestCandlestickUnmarshalJSON(t *testing.T) { func TestGetCandlesticks(t *testing.T) { t.Parallel() - if _, err := g.GetCandlesticks(t.Context(), getPair(t, asset.Spot), 0, time.Time{}, time.Time{}, kline.OneDay); err != nil { - t.Errorf("%s GetCandlesticks() error %v", g.Name, err) + if _, err := e.GetCandlesticks(t.Context(), getPair(t, asset.Spot), 0, time.Time{}, time.Time{}, kline.OneDay); err != nil { + t.Errorf("%s GetCandlesticks() error %v", e.Name, err) } } func TestGetTradingFeeRatio(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetTradingFeeRatio(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}); err != nil { - t.Errorf("%s GetTradingFeeRatio() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetTradingFeeRatio(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}); err != nil { + t.Errorf("%s GetTradingFeeRatio() error %v", e.Name, err) } } func TestGetSpotAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSpotAccounts(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetSpotAccounts() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSpotAccounts(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetSpotAccounts() error %v", e.Name, err) } } func TestCreateBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CreateBatchOrders(t.Context(), []CreateOrderRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CreateBatchOrders(t.Context(), []CreateOrderRequest{ { CurrencyPair: getPair(t, asset.Spot), Side: "sell", Amount: 0.001, Price: 12349, - Account: g.assetTypeToString(asset.Spot), + Account: e.assetTypeToString(asset.Spot), Type: "limit", }, { @@ -249,7 +249,7 @@ func TestCreateBatchOrders(t *testing.T) { Side: "buy", Amount: 1, Price: 1234567789, - Account: g.assetTypeToString(asset.Spot), + Account: e.assetTypeToString(asset.Spot), Type: "limit", }, }) @@ -258,33 +258,33 @@ func TestCreateBatchOrders(t *testing.T) { func TestGetSpotOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSpotOpenOrders(t.Context(), 0, 0, false); err != nil { - t.Errorf("%s GetSpotOpenOrders() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSpotOpenOrders(t.Context(), 0, 0, false); err != nil { + t.Errorf("%s GetSpotOpenOrders() error %v", e.Name, err) } } func TestSpotClosePositionWhenCrossCurrencyDisabled(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.SpotClosePositionWhenCrossCurrencyDisabled(t.Context(), &ClosePositionRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.SpotClosePositionWhenCrossCurrencyDisabled(t.Context(), &ClosePositionRequestParam{ Amount: 0.1, Price: 1234567384, CurrencyPair: getPair(t, asset.Spot), }); err != nil { - t.Errorf("%s SpotClosePositionWhenCrossCurrencyDisabled() error %v", g.Name, err) + t.Errorf("%s SpotClosePositionWhenCrossCurrencyDisabled() error %v", e.Name, err) } } func TestCreateSpotOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.PlaceSpotOrder(t.Context(), &CreateOrderRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceSpotOrder(t.Context(), &CreateOrderRequest{ CurrencyPair: getPair(t, asset.Spot), Side: "buy", Amount: 1, Price: 900000, - Account: g.assetTypeToString(asset.Spot), + Account: e.assetTypeToString(asset.Spot), Type: "limit", }) assert.NoError(t, err, "PlaceSpotOrder should not error") @@ -292,23 +292,23 @@ func TestCreateSpotOrder(t *testing.T) { func TestGetSpotOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSpotOrders(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, statusOpen, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSpotOrders(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, statusOpen, 0, 0) assert.NoError(t, err, "GetSpotOrders should not error") } func TestCancelAllOpenOrdersSpecifiedCurrencyPair(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelAllOpenOrdersSpecifiedCurrencyPair(t.Context(), getPair(t, asset.Spot), order.Sell, asset.Empty); err != nil { - t.Errorf("%s CancelAllOpenOrdersSpecifiedCurrencyPair() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelAllOpenOrdersSpecifiedCurrencyPair(t.Context(), getPair(t, asset.Spot), order.Sell, asset.Empty); err != nil { + t.Errorf("%s CancelAllOpenOrdersSpecifiedCurrencyPair() error %v", e.Name, err) } } func TestCancelBatchOrdersWithIDList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelBatchOrdersWithIDList(t.Context(), []CancelOrderByIDParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelBatchOrdersWithIDList(t.Context(), []CancelOrderByIDParam{ { CurrencyPair: getPair(t, asset.Spot), ID: "1234567", @@ -318,36 +318,36 @@ func TestCancelBatchOrdersWithIDList(t *testing.T) { ID: "something", }, }); err != nil { - t.Errorf("%s CancelBatchOrderWithIDList() error %v", g.Name, err) + t.Errorf("%s CancelBatchOrderWithIDList() error %v", e.Name, err) } } func TestGetSpotOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSpotOrder(t.Context(), "1234", currency.Pair{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSpotOrder(t.Context(), "1234", currency.Pair{ Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT, }, asset.Spot); err != nil { - t.Errorf("%s GetSpotOrder() error %v", g.Name, err) + t.Errorf("%s GetSpotOrder() error %v", e.Name, err) } } func TestAmendSpotOrder(t *testing.T) { t.Parallel() - _, err := g.AmendSpotOrder(t.Context(), "", getPair(t, asset.Spot), false, &PriceAndAmount{ + _, err := e.AmendSpotOrder(t.Context(), "", getPair(t, asset.Spot), false, &PriceAndAmount{ Price: 1000, }) assert.ErrorIs(t, err, errInvalidOrderID) - _, err = g.AmendSpotOrder(t.Context(), "123", currency.EMPTYPAIR, false, &PriceAndAmount{ + _, err = e.AmendSpotOrder(t.Context(), "123", currency.EMPTYPAIR, false, &PriceAndAmount{ Price: 1000, }) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err = g.AmendSpotOrder(t.Context(), "123", getPair(t, asset.Spot), false, &PriceAndAmount{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.AmendSpotOrder(t.Context(), "123", getPair(t, asset.Spot), false, &PriceAndAmount{ Price: 1000, }) if err != nil { @@ -357,42 +357,42 @@ func TestAmendSpotOrder(t *testing.T) { func TestCancelSingleSpotOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelSingleSpotOrder(t.Context(), "1234", + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelSingleSpotOrder(t.Context(), "1234", getPair(t, asset.Spot).String(), false); err != nil { - t.Errorf("%s CancelSingleSpotOrder() error %v", g.Name, err) + t.Errorf("%s CancelSingleSpotOrder() error %v", e.Name, err) } } func TestGetMySpotTradingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetMySpotTradingHistory(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, "", 0, 0, false, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMySpotTradingHistory(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, "", 0, 0, false, time.Time{}, time.Time{}) require.NoError(t, err) } func TestGetServerTime(t *testing.T) { t.Parallel() - if _, err := g.GetServerTime(t.Context(), asset.Spot); err != nil { - t.Errorf("%s GetServerTime() error %v", g.Name, err) + if _, err := e.GetServerTime(t.Context(), asset.Spot); err != nil { + t.Errorf("%s GetServerTime() error %v", e.Name, err) } } func TestCountdownCancelorder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CountdownCancelorders(t.Context(), CountdownCancelOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CountdownCancelorders(t.Context(), CountdownCancelOrderParam{ Timeout: 10, CurrencyPair: currency.Pair{Base: currency.BTC, Quote: currency.ETH, Delimiter: currency.UnderscoreDelimiter}, }); err != nil { - t.Errorf("%s CountdownCancelorder() error %v", g.Name, err) + t.Errorf("%s CountdownCancelorder() error %v", e.Name, err) } } func TestCreatePriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CreatePriceTriggeredOrder(t.Context(), &PriceTriggeredOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CreatePriceTriggeredOrder(t.Context(), &PriceTriggeredOrderParam{ Trigger: TriggerPriceInfo{ Price: 123, Rule: ">=", @@ -407,73 +407,73 @@ func TestCreatePriceTriggeredOrder(t *testing.T) { }, Market: currency.Pair{Base: currency.GT, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, }); err != nil { - t.Errorf("%s CreatePriceTriggeredOrder() error %v", g.Name, err) + t.Errorf("%s CreatePriceTriggeredOrder() error %v", e.Name, err) } } func TestGetPriceTriggeredOrderList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetPriceTriggeredOrderList(t.Context(), statusOpen, currency.EMPTYPAIR, asset.Empty, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPriceTriggeredOrderList(t.Context(), statusOpen, currency.EMPTYPAIR, asset.Empty, 0, 0) assert.NoError(t, err, "GetPriceTriggeredOrderList should not error") } func TestCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelMultipleSpotOpenOrders(t.Context(), currency.EMPTYPAIR, asset.CrossMargin); err != nil { - t.Errorf("%s CancelAllOpenOrders() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelMultipleSpotOpenOrders(t.Context(), currency.EMPTYPAIR, asset.CrossMargin); err != nil { + t.Errorf("%s CancelAllOpenOrders() error %v", e.Name, err) } } func TestGetSinglePriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSinglePriceTriggeredOrder(t.Context(), "1234"); err != nil { - t.Errorf("%s GetSinglePriceTriggeredOrder() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSinglePriceTriggeredOrder(t.Context(), "1234"); err != nil { + t.Errorf("%s GetSinglePriceTriggeredOrder() error %v", e.Name, err) } } func TestCancelPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.CancelPriceTriggeredOrder(t.Context(), "1234"); err != nil { - t.Errorf("%s CancelPriceTriggeredOrder() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CancelPriceTriggeredOrder(t.Context(), "1234"); err != nil { + t.Errorf("%s CancelPriceTriggeredOrder() error %v", e.Name, err) } } func TestGetMarginAccountList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMarginAccountList(t.Context(), currency.EMPTYPAIR); err != nil { - t.Errorf("%s GetMarginAccountList() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMarginAccountList(t.Context(), currency.EMPTYPAIR); err != nil { + t.Errorf("%s GetMarginAccountList() error %v", e.Name, err) } } func TestListMarginAccountBalanceChangeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.ListMarginAccountBalanceChangeHistory(t.Context(), currency.BTC, currency.Pair{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.ListMarginAccountBalanceChangeHistory(t.Context(), currency.BTC, currency.Pair{ Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT, }, time.Time{}, time.Time{}, 0, 0); err != nil { - t.Errorf("%s ListMarginAccountBalanceChangeHistory() error %v", g.Name, err) + t.Errorf("%s ListMarginAccountBalanceChangeHistory() error %v", e.Name, err) } } func TestGetMarginFundingAccountList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMarginFundingAccountList(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetMarginFundingAccountList %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMarginFundingAccountList(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetMarginFundingAccountList %v", e.Name, err) } } func TestMarginLoan(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.MarginLoan(t.Context(), &MarginLoanRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.MarginLoan(t.Context(), &MarginLoanRequestParam{ Side: "borrow", Amount: 1, Currency: currency.BTC, @@ -481,172 +481,172 @@ func TestMarginLoan(t *testing.T) { Days: 10, Rate: 0.0002, }); err != nil { - t.Errorf("%s MarginLoan() error %v", g.Name, err) + t.Errorf("%s MarginLoan() error %v", e.Name, err) } } func TestGetMarginAllLoans(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetMarginAllLoans(t.Context(), statusOpen, "lend", "", currency.BTC, currency.Pair{Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT}, false, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginAllLoans(t.Context(), statusOpen, "lend", "", currency.BTC, currency.Pair{Base: currency.BTC, Delimiter: currency.UnderscoreDelimiter, Quote: currency.USDT}, false, 0, 0) assert.NoError(t, err, "GetMarginAllLoans should not error") } func TestMergeMultipleLendingLoans(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.MergeMultipleLendingLoans(t.Context(), currency.USDT, []string{"123", "23423"}); err != nil { - t.Errorf("%s MergeMultipleLendingLoans() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.MergeMultipleLendingLoans(t.Context(), currency.USDT, []string{"123", "23423"}); err != nil { + t.Errorf("%s MergeMultipleLendingLoans() error %v", e.Name, err) } } func TestRetriveOneSingleLoanDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.RetriveOneSingleLoanDetail(t.Context(), "borrow", "123"); err != nil { - t.Errorf("%s RetriveOneSingleLoanDetail() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.RetriveOneSingleLoanDetail(t.Context(), "borrow", "123"); err != nil { + t.Errorf("%s RetriveOneSingleLoanDetail() error %v", e.Name, err) } } func TestModifyALoan(t *testing.T) { t.Parallel() - _, err := g.ModifyALoan(t.Context(), "1234", &ModifyLoanRequestParam{ + _, err := e.ModifyALoan(t.Context(), "1234", &ModifyLoanRequestParam{ Currency: currency.BTC, Side: "borrow", AutoRenew: false, }) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.ModifyALoan(t.Context(), "1234", &ModifyLoanRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.ModifyALoan(t.Context(), "1234", &ModifyLoanRequestParam{ Currency: currency.BTC, Side: "borrow", AutoRenew: false, CurrencyPair: currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, }); err != nil { - t.Errorf("%s ModifyALoan() error %v", g.Name, err) + t.Errorf("%s ModifyALoan() error %v", e.Name, err) } } func TestCancelLendingLoan(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.CancelLendingLoan(t.Context(), currency.BTC, "1234"); err != nil { - t.Errorf("%s CancelLendingLoan() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CancelLendingLoan(t.Context(), currency.BTC, "1234"); err != nil { + t.Errorf("%s CancelLendingLoan() error %v", e.Name, err) } } func TestRepayALoan(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.RepayALoan(t.Context(), "1234", &RepayLoanRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.RepayALoan(t.Context(), "1234", &RepayLoanRequestParam{ CurrencyPair: currency.NewBTCUSDT(), Currency: currency.BTC, Mode: "all", }); err != nil { - t.Errorf("%s RepayALoan() error %v", g.Name, err) + t.Errorf("%s RepayALoan() error %v", e.Name, err) } } func TestListLoanRepaymentRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.ListLoanRepaymentRecords(t.Context(), "1234"); err != nil { - t.Errorf("%s LoanRepaymentRecord() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.ListLoanRepaymentRecords(t.Context(), "1234"); err != nil { + t.Errorf("%s LoanRepaymentRecord() error %v", e.Name, err) } } func TestListRepaymentRecordsOfSpecificLoan(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.ListRepaymentRecordsOfSpecificLoan(t.Context(), "1234", "", 0, 0); err != nil { - t.Errorf("%s error while ListRepaymentRecordsOfSpecificLoan() %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.ListRepaymentRecordsOfSpecificLoan(t.Context(), "1234", "", 0, 0); err != nil { + t.Errorf("%s error while ListRepaymentRecordsOfSpecificLoan() %v", e.Name, err) } } func TestGetOneSingleloanRecord(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetOneSingleLoanRecord(t.Context(), "1234", "123"); err != nil { - t.Errorf("%s error while GetOneSingleloanRecord() %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetOneSingleLoanRecord(t.Context(), "1234", "123"); err != nil { + t.Errorf("%s error while GetOneSingleloanRecord() %v", e.Name, err) } } func TestModifyALoanRecord(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.ModifyALoanRecord(t.Context(), "1234", &ModifyLoanRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.ModifyALoanRecord(t.Context(), "1234", &ModifyLoanRequestParam{ Currency: currency.USDT, CurrencyPair: currency.NewBTCUSDT(), Side: "lend", AutoRenew: true, LoanID: "1234", }); err != nil { - t.Errorf("%s ModifyALoanRecord() error %v", g.Name, err) + t.Errorf("%s ModifyALoanRecord() error %v", e.Name, err) } } func TestUpdateUsersAutoRepaymentSetting(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.UpdateUsersAutoRepaymentSetting(t.Context(), true); err != nil { - t.Errorf("%s UpdateUsersAutoRepaymentSetting() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.UpdateUsersAutoRepaymentSetting(t.Context(), true); err != nil { + t.Errorf("%s UpdateUsersAutoRepaymentSetting() error %v", e.Name, err) } } func TestGetUserAutoRepaymentSetting(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetUserAutoRepaymentSetting(t.Context()); err != nil { - t.Errorf("%s GetUserAutoRepaymentSetting() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetUserAutoRepaymentSetting(t.Context()); err != nil { + t.Errorf("%s GetUserAutoRepaymentSetting() error %v", e.Name, err) } } func TestGetMaxTransferableAmountForSpecificMarginCurrency(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMaxTransferableAmountForSpecificMarginCurrency(t.Context(), currency.BTC, currency.EMPTYPAIR); err != nil { - t.Errorf("%s GetMaxTransferableAmountForSpecificMarginCurrency() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMaxTransferableAmountForSpecificMarginCurrency(t.Context(), currency.BTC, currency.EMPTYPAIR); err != nil { + t.Errorf("%s GetMaxTransferableAmountForSpecificMarginCurrency() error %v", e.Name, err) } } func TestGetMaxBorrowableAmountForSpecificMarginCurrency(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMaxBorrowableAmountForSpecificMarginCurrency(t.Context(), currency.BTC, currency.EMPTYPAIR); err != nil { - t.Errorf("%s GetMaxBorrowableAmountForSpecificMarginCurrency() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMaxBorrowableAmountForSpecificMarginCurrency(t.Context(), currency.BTC, currency.EMPTYPAIR); err != nil { + t.Errorf("%s GetMaxBorrowableAmountForSpecificMarginCurrency() error %v", e.Name, err) } } func TestCurrencySupportedByCrossMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.CurrencySupportedByCrossMargin(t.Context()); err != nil { - t.Errorf("%s CurrencySupportedByCrossMargin() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.CurrencySupportedByCrossMargin(t.Context()); err != nil { + t.Errorf("%s CurrencySupportedByCrossMargin() error %v", e.Name, err) } } func TestGetCrossMarginSupportedCurrencyDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetCrossMarginSupportedCurrencyDetail(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetCrossMarginSupportedCurrencyDetail() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetCrossMarginSupportedCurrencyDetail(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetCrossMarginSupportedCurrencyDetail() error %v", e.Name, err) } } func TestGetCrossMarginAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetCrossMarginAccounts(t.Context()); err != nil { - t.Errorf("%s GetCrossMarginAccounts() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetCrossMarginAccounts(t.Context()); err != nil { + t.Errorf("%s GetCrossMarginAccounts() error %v", e.Name, err) } } func TestGetCrossMarginAccountChangeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetCrossMarginAccountChangeHistory(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 6, "in"); err != nil { - t.Errorf("%s GetCrossMarginAccountChangeHistory() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetCrossMarginAccountChangeHistory(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 6, "in"); err != nil { + t.Errorf("%s GetCrossMarginAccountChangeHistory() error %v", e.Name, err) } } @@ -656,110 +656,110 @@ func TestCreateCrossMarginBorrowLoan(t *testing.T) { t.Parallel() var response CrossMarginLoanResponse if err := json.Unmarshal([]byte(createCrossMarginBorrowLoanJSON), &response); err != nil { - t.Errorf("%s error while deserializing to CrossMarginBorrowLoanResponse %v", g.Name, err) + t.Errorf("%s error while deserializing to CrossMarginBorrowLoanResponse %v", e.Name, err) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CreateCrossMarginBorrowLoan(t.Context(), CrossMarginBorrowLoanParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CreateCrossMarginBorrowLoan(t.Context(), CrossMarginBorrowLoanParams{ Currency: currency.BTC, Amount: 3, }); err != nil { - t.Errorf("%s CreateCrossMarginBorrowLoan() error %v", g.Name, err) + t.Errorf("%s CreateCrossMarginBorrowLoan() error %v", e.Name, err) } } func TestGetCrossMarginBorrowHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetCrossMarginBorrowHistory(t.Context(), 1, currency.BTC, 0, 0, false); err != nil { - t.Errorf("%s GetCrossMarginBorrowHistory() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetCrossMarginBorrowHistory(t.Context(), 1, currency.BTC, 0, 0, false); err != nil { + t.Errorf("%s GetCrossMarginBorrowHistory() error %v", e.Name, err) } } func TestGetSingleBorrowLoanDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSingleBorrowLoanDetail(t.Context(), "1234"); err != nil { - t.Errorf("%s GetSingleBorrowLoanDetail() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSingleBorrowLoanDetail(t.Context(), "1234"); err != nil { + t.Errorf("%s GetSingleBorrowLoanDetail() error %v", e.Name, err) } } func TestExecuteRepayment(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.ExecuteRepayment(t.Context(), CurrencyAndAmount{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.ExecuteRepayment(t.Context(), CurrencyAndAmount{ Currency: currency.USD, Amount: 1234.55, }); err != nil { - t.Errorf("%s ExecuteRepayment() error %v", g.Name, err) + t.Errorf("%s ExecuteRepayment() error %v", e.Name, err) } } func TestGetCrossMarginRepayments(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetCrossMarginRepayments(t.Context(), currency.BTC, "123", 0, 0, false); err != nil { - t.Errorf("%s GetCrossMarginRepayments() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetCrossMarginRepayments(t.Context(), currency.BTC, "123", 0, 0, false); err != nil { + t.Errorf("%s GetCrossMarginRepayments() error %v", e.Name, err) } } func TestGetMaxTransferableAmountForSpecificCrossMarginCurrency(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMaxTransferableAmountForSpecificCrossMarginCurrency(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetMaxTransferableAmountForSpecificCrossMarginCurrency() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMaxTransferableAmountForSpecificCrossMarginCurrency(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetMaxTransferableAmountForSpecificCrossMarginCurrency() error %v", e.Name, err) } } func TestGetMaxBorrowableAmountForSpecificCrossMarginCurrency(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMaxBorrowableAmountForSpecificCrossMarginCurrency(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetMaxBorrowableAmountForSpecificCrossMarginCurrency() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMaxBorrowableAmountForSpecificCrossMarginCurrency(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetMaxBorrowableAmountForSpecificCrossMarginCurrency() error %v", e.Name, err) } } func TestListCurrencyChain(t *testing.T) { t.Parallel() - if _, err := g.ListCurrencyChain(t.Context(), currency.BTC); err != nil { - t.Errorf("%s ListCurrencyChain() error %v", g.Name, err) + if _, err := e.ListCurrencyChain(t.Context(), currency.BTC); err != nil { + t.Errorf("%s ListCurrencyChain() error %v", e.Name, err) } } func TestGenerateCurrencyDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GenerateCurrencyDepositAddress(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GenerateCurrencyDepositAddress() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GenerateCurrencyDepositAddress(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GenerateCurrencyDepositAddress() error %v", e.Name, err) } } func TestGetWithdrawalRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetWithdrawalRecords(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { - t.Errorf("%s GetWithdrawalRecords() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetWithdrawalRecords(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { + t.Errorf("%s GetWithdrawalRecords() error %v", e.Name, err) } } func TestGetDepositRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetDepositRecords(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { - t.Errorf("%s GetDepositRecords() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetDepositRecords(t.Context(), currency.BTC, time.Time{}, time.Time{}, 0, 0); err != nil { + t.Errorf("%s GetDepositRecords() error %v", e.Name, err) } } func TestTransferCurrency(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.TransferCurrency(t.Context(), &TransferCurrencyParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.TransferCurrency(t.Context(), &TransferCurrencyParam{ Currency: currency.BTC, - From: g.assetTypeToString(asset.Spot), - To: g.assetTypeToString(asset.Margin), + From: e.assetTypeToString(asset.Spot), + To: e.assetTypeToString(asset.Margin), Amount: 1202.000, CurrencyPair: getPair(t, asset.Spot), }); err != nil { - t.Errorf("%s TransferCurrency() error %v", g.Name, err) + t.Errorf("%s TransferCurrency() error %v", e.Name, err) } } @@ -767,32 +767,32 @@ func TestSubAccountTransfer(t *testing.T) { t.Parallel() ctx := t.Context() req := SubAccountTransferParam{SubAccountType: "index"} - require.ErrorIs(t, g.SubAccountTransfer(ctx, req), currency.ErrCurrencyCodeEmpty) + require.ErrorIs(t, e.SubAccountTransfer(ctx, req), currency.ErrCurrencyCodeEmpty) req.Currency = currency.BTC - require.ErrorIs(t, g.SubAccountTransfer(ctx, req), errInvalidSubAccount) + require.ErrorIs(t, e.SubAccountTransfer(ctx, req), errInvalidSubAccount) req.SubAccount = "1337" - require.ErrorIs(t, g.SubAccountTransfer(ctx, req), errInvalidTransferDirection) + require.ErrorIs(t, e.SubAccountTransfer(ctx, req), errInvalidTransferDirection) req.Direction = "to" - require.ErrorIs(t, g.SubAccountTransfer(ctx, req), errInvalidAmount) + require.ErrorIs(t, e.SubAccountTransfer(ctx, req), errInvalidAmount) req.Amount = 1.337 - require.ErrorIs(t, g.SubAccountTransfer(ctx, req), asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + require.ErrorIs(t, e.SubAccountTransfer(ctx, req), asset.ErrNotSupported) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req.SubAccountType = "spot" - require.NoError(t, g.SubAccountTransfer(ctx, req)) + require.NoError(t, e.SubAccountTransfer(ctx, req)) } func TestGetSubAccountTransferHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.GetSubAccountTransferHistory(t.Context(), "", time.Time{}, time.Time{}, 0, 0); err != nil { - t.Errorf("%s GetSubAccountTransferHistory() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.GetSubAccountTransferHistory(t.Context(), "", time.Time{}, time.Time{}, 0, 0); err != nil { + t.Errorf("%s GetSubAccountTransferHistory() error %v", e.Name, err) } } func TestSubAccountTransferToSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if err := g.SubAccountTransferToSubAccount(t.Context(), &InterSubAccountTransferParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if err := e.SubAccountTransferToSubAccount(t.Context(), &InterSubAccountTransferParams{ Currency: currency.BTC, SubAccountFromUserID: "1234", SubAccountFromAssetType: asset.Spot, @@ -806,84 +806,84 @@ func TestSubAccountTransferToSubAccount(t *testing.T) { func TestGetWithdrawalStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetWithdrawalStatus(t.Context(), currency.NewCode("")); err != nil { - t.Errorf("%s GetWithdrawalStatus() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetWithdrawalStatus(t.Context(), currency.NewCode("")); err != nil { + t.Errorf("%s GetWithdrawalStatus() error %v", e.Name, err) } } func TestGetSubAccountBalances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSubAccountBalances(t.Context(), ""); err != nil { - t.Errorf("%s GetSubAccountBalances() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSubAccountBalances(t.Context(), ""); err != nil { + t.Errorf("%s GetSubAccountBalances() error %v", e.Name, err) } } func TestGetSubAccountMarginBalances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSubAccountMarginBalances(t.Context(), ""); err != nil { - t.Errorf("%s GetSubAccountMarginBalances() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSubAccountMarginBalances(t.Context(), ""); err != nil { + t.Errorf("%s GetSubAccountMarginBalances() error %v", e.Name, err) } } func TestGetSubAccountFuturesBalances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSubAccountFuturesBalances(t.Context(), "", currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubAccountFuturesBalances(t.Context(), "", currency.EMPTYCODE) assert.Error(t, err, "GetSubAccountFuturesBalances should not error") } func TestGetSubAccountCrossMarginBalances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSubAccountCrossMarginBalances(t.Context(), ""); err != nil { - t.Errorf("%s GetSubAccountCrossMarginBalances() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSubAccountCrossMarginBalances(t.Context(), ""); err != nil { + t.Errorf("%s GetSubAccountCrossMarginBalances() error %v", e.Name, err) } } func TestGetSavedAddresses(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSavedAddresses(t.Context(), currency.BTC, "", 0); err != nil { - t.Errorf("%s GetSavedAddresses() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSavedAddresses(t.Context(), currency.BTC, "", 0); err != nil { + t.Errorf("%s GetSavedAddresses() error %v", e.Name, err) } } func TestGetPersonalTradingFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetPersonalTradingFee(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetPersonalTradingFee(t.Context(), currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}, currency.EMPTYCODE) assert.NoError(t, err, "GetPersonalTradingFee should not error") } func TestGetUsersTotalBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetUsersTotalBalance(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetUsersTotalBalance() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetUsersTotalBalance(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetUsersTotalBalance() error %v", e.Name, err) } } func TestGetMarginSupportedCurrencyPairs(t *testing.T) { t.Parallel() - if _, err := g.GetMarginSupportedCurrencyPairs(t.Context()); err != nil { - t.Errorf("%s GetMarginSupportedCurrencyPair() error %v", g.Name, err) + if _, err := e.GetMarginSupportedCurrencyPairs(t.Context()); err != nil { + t.Errorf("%s GetMarginSupportedCurrencyPair() error %v", e.Name, err) } } func TestGetMarginSupportedCurrencyPair(t *testing.T) { t.Parallel() - if _, err := g.GetSingleMarginSupportedCurrencyPair(t.Context(), getPair(t, asset.Margin)); err != nil { - t.Errorf("%s GetMarginSupportedCurrencyPair() error %v", g.Name, err) + if _, err := e.GetSingleMarginSupportedCurrencyPair(t.Context(), getPair(t, asset.Margin)); err != nil { + t.Errorf("%s GetMarginSupportedCurrencyPair() error %v", e.Name, err) } } func TestGetOrderbookOfLendingLoans(t *testing.T) { t.Parallel() - if _, err := g.GetOrderbookOfLendingLoans(t.Context(), currency.BTC); err != nil { - t.Errorf("%s GetOrderbookOfLendingLoans() error %v", g.Name, err) + if _, err := e.GetOrderbookOfLendingLoans(t.Context(), currency.BTC); err != nil { + t.Errorf("%s GetOrderbookOfLendingLoans() error %v", e.Name, err) } } @@ -891,154 +891,154 @@ func TestGetAllFutureContracts(t *testing.T) { t.Parallel() for _, c := range []currency.Code{currency.BTC, currency.USDT} { - _, err := g.GetAllFutureContracts(t.Context(), c) + _, err := e.GetAllFutureContracts(t.Context(), c) assert.NoErrorf(t, err, "GetAllFutureContracts %s should not error", c) } } func TestGetFuturesContract(t *testing.T) { t.Parallel() - _, err := g.GetFuturesContract(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String()) + _, err := e.GetFuturesContract(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String()) assert.NoError(t, err, "GetFuturesContract should not error") - _, err = g.GetFuturesContract(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String()) + _, err = e.GetFuturesContract(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String()) assert.NoError(t, err, "GetFuturesContract should not error") } func TestGetFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetFuturesOrderbook(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String(), "", 10, false) + _, err := e.GetFuturesOrderbook(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String(), "", 10, false) assert.NoError(t, err, "GetFuturesOrderbook should not error for CoinMarginedFutures") - _, err = g.GetFuturesOrderbook(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String(), "", 10, false) + _, err = e.GetFuturesOrderbook(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String(), "", 10, false) assert.NoError(t, err, "GetFuturesOrderbook should not error for USDTMarginedFutures") } func TestGetFuturesTradingHistory(t *testing.T) { t.Parallel() - _, err := g.GetFuturesTradingHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, 0, "", time.Time{}, time.Time{}) + _, err := e.GetFuturesTradingHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, 0, "", time.Time{}, time.Time{}) assert.NoError(t, err, "GetFuturesTradingHistory should not error for CoinMarginedFutures") - _, err = g.GetFuturesTradingHistory(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0, 0, "", time.Time{}, time.Time{}) + _, err = e.GetFuturesTradingHistory(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0, 0, "", time.Time{}, time.Time{}) assert.NoError(t, err, "GetFuturesTradingHistory should not error for USDTMarginedFutures") } func TestGetFuturesCandlesticks(t *testing.T) { t.Parallel() - _, err := g.GetFuturesCandlesticks(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String(), time.Time{}, time.Time{}, 0, kline.OneWeek) + _, err := e.GetFuturesCandlesticks(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures).String(), time.Time{}, time.Time{}, 0, kline.OneWeek) assert.NoError(t, err, "GetFuturesCandlesticks should not error for CoinMarginedFutures") - _, err = g.GetFuturesCandlesticks(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String(), time.Time{}, time.Time{}, 0, kline.OneWeek) + _, err = e.GetFuturesCandlesticks(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures).String(), time.Time{}, time.Time{}, 0, kline.OneWeek) assert.NoError(t, err, "GetFuturesCandlesticks should not error for USDTMarginedFutures") } func TestPremiumIndexKLine(t *testing.T) { t.Parallel() - _, err := g.PremiumIndexKLine(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) + _, err := e.PremiumIndexKLine(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) assert.NoError(t, err, "PremiumIndexKLine should not error for CoinMarginedFutures") - _, err = g.PremiumIndexKLine(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) + _, err = e.PremiumIndexKLine(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) assert.NoError(t, err, "PremiumIndexKLine should not error for USDTMarginedFutures") } func TestGetFutureTickers(t *testing.T) { t.Parallel() - _, err := g.GetFuturesTickers(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) + _, err := e.GetFuturesTickers(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) assert.NoError(t, err, "GetFutureTickers should not error for CoinMarginedFutures") - _, err = g.GetFuturesTickers(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) + _, err = e.GetFuturesTickers(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) assert.NoError(t, err, "GetFutureTickers should not error for USDTMarginedFutures") } func TestGetFutureFundingRates(t *testing.T) { t.Parallel() - _, err := g.GetFutureFundingRates(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0) + _, err := e.GetFutureFundingRates(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0) assert.NoError(t, err, "GetFutureFundingRates should not error for CoinMarginedFutures") - _, err = g.GetFutureFundingRates(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0) + _, err = e.GetFutureFundingRates(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0) assert.NoError(t, err, "GetFutureFundingRates should not error for USDTMarginedFutures") } func TestGetFuturesInsuranceBalanceHistory(t *testing.T) { t.Parallel() - _, err := g.GetFuturesInsuranceBalanceHistory(t.Context(), currency.USDT, 0) + _, err := e.GetFuturesInsuranceBalanceHistory(t.Context(), currency.USDT, 0) assert.NoError(t, err, "GetFuturesInsuranceBalanceHistory should not error") } func TestGetFutureStats(t *testing.T) { t.Parallel() - _, err := g.GetFutureStats(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, 0, 0) + _, err := e.GetFutureStats(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, 0, 0) assert.NoError(t, err, "GetFutureStats should not error for CoinMarginedFutures") - _, err = g.GetFutureStats(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, 0, 0) + _, err = e.GetFutureStats(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, 0, 0) assert.NoError(t, err, "GetFutureStats should not error for USDTMarginedFutures") } func TestGetIndexConstituent(t *testing.T) { t.Parallel() - _, err := g.GetIndexConstituent(t.Context(), currency.USDT, currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}.String()) + _, err := e.GetIndexConstituent(t.Context(), currency.USDT, currency.Pair{Base: currency.BTC, Quote: currency.USDT, Delimiter: currency.UnderscoreDelimiter}.String()) assert.NoError(t, err, "GetIndexConstituent should not error") } func TestGetLiquidationHistory(t *testing.T) { t.Parallel() - _, err := g.GetLiquidationHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, time.Time{}, 0) + _, err := e.GetLiquidationHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), time.Time{}, time.Time{}, 0) assert.NoError(t, err, "GetLiquidationHistory should not error for CoinMarginedFutures") - _, err = g.GetLiquidationHistory(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, time.Time{}, 0) + _, err = e.GetLiquidationHistory(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), time.Time{}, time.Time{}, 0) assert.NoError(t, err, "GetLiquidationHistory should not error for USDTMarginedFutures") } func TestQueryFuturesAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.QueryFuturesAccount(t.Context(), currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.QueryFuturesAccount(t.Context(), currency.USDT) assert.NoError(t, err, "QueryFuturesAccount should not error") } func TestGetFuturesAccountBooks(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetFuturesAccountBooks(t.Context(), currency.USDT, 0, time.Time{}, time.Time{}, "dnw") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesAccountBooks(t.Context(), currency.USDT, 0, time.Time{}, time.Time{}, "dnw") assert.NoError(t, err, "GetFuturesAccountBooks should not error") } func TestGetAllFuturesPositionsOfUsers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetAllFuturesPositionsOfUsers(t.Context(), currency.USDT, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAllFuturesPositionsOfUsers(t.Context(), currency.USDT, true) assert.NoError(t, err, "GetAllPositionsOfUsers should not error") } func TestGetSinglePosition(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSinglePosition(t.Context(), currency.USDT, currency.Pair{Quote: currency.BTC, Base: currency.USDT}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSinglePosition(t.Context(), currency.USDT, currency.Pair{Quote: currency.BTC, Base: currency.USDT}) assert.NoError(t, err, "GetSinglePosition should not error") } func TestUpdateFuturesPositionMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdateFuturesPositionMargin(t.Context(), currency.BTC, 0.01, getPair(t, asset.CoinMarginedFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdateFuturesPositionMargin(t.Context(), currency.BTC, 0.01, getPair(t, asset.CoinMarginedFutures)) assert.NoError(t, err, "UpdateFuturesPositionMargin should not error for CoinMarginedFutures") - _, err = g.UpdateFuturesPositionMargin(t.Context(), currency.USDT, 0.01, getPair(t, asset.USDTMarginedFutures)) + _, err = e.UpdateFuturesPositionMargin(t.Context(), currency.USDT, 0.01, getPair(t, asset.USDTMarginedFutures)) assert.NoError(t, err, "UpdateFuturesPositionMargin should not error for USDTMarginedFutures") } func TestUpdateFuturesPositionLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdateFuturesPositionLeverage(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 1, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdateFuturesPositionLeverage(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 1, 0) assert.NoError(t, err, "UpdateFuturesPositionLeverage should not error for CoinMarginedFutures") - _, err = g.UpdateFuturesPositionLeverage(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 1, 0) + _, err = e.UpdateFuturesPositionLeverage(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 1, 0) assert.NoError(t, err, "UpdateFuturesPositionLeverage should not error for USDTMarginedFutures") } func TestUpdateFuturesPositionRiskLimit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdateFuturesPositionRiskLimit(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdateFuturesPositionRiskLimit(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 10) assert.NoError(t, err, "UpdateFuturesPositionRiskLimit should not error for CoinMarginedFutures") - _, err = g.UpdateFuturesPositionRiskLimit(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 10) + _, err = e.UpdateFuturesPositionRiskLimit(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 10) assert.NoError(t, err, "UpdateFuturesPositionRiskLimit should not error for USDTMarginedFutures") } func TestPlaceDeliveryOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.PlaceDeliveryOrder(t.Context(), &ContractOrderCreateParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceDeliveryOrder(t.Context(), &ContractOrderCreateParams{ Contract: getPair(t, asset.DeliveryFutures), Size: 6024, Iceberg: 0, @@ -1052,66 +1052,66 @@ func TestPlaceDeliveryOrder(t *testing.T) { func TestGetDeliveryOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryOrders(t.Context(), getPair(t, asset.DeliveryFutures), statusOpen, currency.USDT, "", 0, 0, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryOrders(t.Context(), getPair(t, asset.DeliveryFutures), statusOpen, currency.USDT, "", 0, 0, 1) assert.NoError(t, err, "GetDeliveryOrders should not error") } func TestCancelMultipleDeliveryOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelMultipleDeliveryOrders(t.Context(), getPair(t, asset.DeliveryFutures), "ask", currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelMultipleDeliveryOrders(t.Context(), getPair(t, asset.DeliveryFutures), "ask", currency.USDT) assert.NoError(t, err, "CancelMultipleDeliveryOrders should not error") } func TestGetSingleDeliveryOrder(t *testing.T) { t.Parallel() - _, err := g.GetSingleDeliveryOrder(t.Context(), currency.EMPTYCODE, "123456") + _, err := e.GetSingleDeliveryOrder(t.Context(), currency.EMPTYCODE, "123456") assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency, "GetSingleDeliveryOrder should return errEmptyOrInvalidSettlementCurrency") - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err = g.GetSingleDeliveryOrder(t.Context(), currency.USDT, "123456") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetSingleDeliveryOrder(t.Context(), currency.USDT, "123456") assert.NoError(t, err, "GetSingleDeliveryOrder should not error") } func TestCancelSingleDeliveryOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelSingleDeliveryOrder(t.Context(), currency.USDT, "123456") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelSingleDeliveryOrder(t.Context(), currency.USDT, "123456") assert.NoError(t, err, "CancelSingleDeliveryOrder should not error") } func TestGetMyDeliveryTradingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetMyDeliveryTradingHistory(t.Context(), currency.USDT, "", getPair(t, asset.DeliveryFutures), 0, 0, 1, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMyDeliveryTradingHistory(t.Context(), currency.USDT, "", getPair(t, asset.DeliveryFutures), 0, 0, 1, "") assert.NoError(t, err, "GetMyDeliveryTradingHistory should not error") } func TestGetDeliveryPositionCloseHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryPositionCloseHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, 0, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryPositionCloseHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, 0, time.Time{}, time.Time{}) assert.NoError(t, err, "GetDeliveryPositionCloseHistory should not error") } func TestGetDeliveryLiquidationHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryLiquidationHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryLiquidationHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, time.Now()) assert.NoError(t, err, "GetDeliveryLiquidationHistory should not error") } func TestGetDeliverySettlementHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliverySettlementHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliverySettlementHistory(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0, time.Now()) assert.NoError(t, err, "GetDeliverySettlementHistory should not error") } func TestGetDeliveryPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, &FuturesPriceTriggeredOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, &FuturesPriceTriggeredOrderParam{ Initial: FuturesInitial{ Price: 1234., Size: 12, @@ -1128,79 +1128,79 @@ func TestGetDeliveryPriceTriggeredOrder(t *testing.T) { func TestGetDeliveryAllAutoOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryAllAutoOrder(t.Context(), statusOpen, currency.USDT, getPair(t, asset.DeliveryFutures), 0, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryAllAutoOrder(t.Context(), statusOpen, currency.USDT, getPair(t, asset.DeliveryFutures), 0, 1) assert.NoError(t, err, "GetDeliveryAllAutoOrder should not error") } func TestCancelAllDeliveryPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelAllDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) assert.NoError(t, err, "CancelAllDeliveryPriceTriggeredOrder should not error") } func TestGetSingleDeliveryPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSingleDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSingleDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, "12345") assert.NoError(t, err, "GetSingleDeliveryPriceTriggeredOrder should not error") } func TestCancelDeliveryPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelDeliveryPriceTriggeredOrder(t.Context(), currency.USDT, "12345") assert.NoError(t, err, "CancelDeliveryPriceTriggeredOrder should not error") } func TestEnableOrDisableDualMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.EnableOrDisableDualMode(t.Context(), currency.BTC, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.EnableOrDisableDualMode(t.Context(), currency.BTC, true) assert.NoError(t, err, "EnableOrDisableDualMode should not error") } func TestRetrivePositionDetailInDualMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.RetrivePositionDetailInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.RetrivePositionDetailInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) assert.NoError(t, err, "RetrivePositionDetailInDualMode should not error for CoinMarginedFutures") - _, err = g.RetrivePositionDetailInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) + _, err = e.RetrivePositionDetailInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) assert.NoError(t, err, "RetrivePositionDetailInDualMode should not error for USDTMarginedFutures") } func TestUpdatePositionMarginInDualMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdatePositionMarginInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0.001, "dual_long") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdatePositionMarginInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0.001, "dual_long") assert.NoError(t, err, "UpdatePositionMarginInDualMode should not error for CoinMarginedFutures") - _, err = g.UpdatePositionMarginInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0.001, "dual_long") + _, err = e.UpdatePositionMarginInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0.001, "dual_long") assert.NoError(t, err, "UpdatePositionMarginInDualMode should not error for USDTMarginedFutures") } func TestUpdatePositionLeverageInDualMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdatePositionLeverageInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0.001, 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdatePositionLeverageInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0.001, 0.001) assert.NoError(t, err, "UpdatePositionLeverageInDualMode should not error for CoinMarginedFutures") - _, err = g.UpdatePositionLeverageInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0.001, 0.001) + _, err = e.UpdatePositionLeverageInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 0.001, 0.001) assert.NoError(t, err, "UpdatePositionLeverageInDualMode should not error for USDTMarginedFutures") } func TestUpdatePositionRiskLimitInDualMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.UpdatePositionRiskLimitInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.UpdatePositionRiskLimitInDualMode(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 10) assert.NoError(t, err, "UpdatePositionRiskLimitInDualMode should not error for CoinMarginedFutures") - _, err = g.UpdatePositionRiskLimitInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 10) + _, err = e.UpdatePositionRiskLimitInDualMode(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures), 10) assert.NoError(t, err, "UpdatePositionRiskLimitInDualMode should not error for USDTMarginedFutures") } func TestPlaceFuturesOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.PlaceFuturesOrder(t.Context(), &ContractOrderCreateParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceFuturesOrder(t.Context(), &ContractOrderCreateParams{ Contract: getPair(t, asset.CoinMarginedFutures), Size: 6024, Iceberg: 0, @@ -1214,36 +1214,36 @@ func TestPlaceFuturesOrder(t *testing.T) { func TestGetFuturesOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetFuturesOrders(t.Context(), currency.NewBTCUSD(), statusOpen, "", currency.BTC, 0, 0, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesOrders(t.Context(), currency.NewBTCUSD(), statusOpen, "", currency.BTC, 0, 0, 1) assert.NoError(t, err, "GetFuturesOrders should not error") } func TestCancelMultipleFuturesOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelMultipleFuturesOpenOrders(t.Context(), getPair(t, asset.USDTMarginedFutures), "ask", currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelMultipleFuturesOpenOrders(t.Context(), getPair(t, asset.USDTMarginedFutures), "ask", currency.USDT) assert.NoError(t, err, "CancelMultipleFuturesOpenOrders should not error") } func TestGetSingleFuturesPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSingleFuturesPriceTriggeredOrder(t.Context(), currency.BTC, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSingleFuturesPriceTriggeredOrder(t.Context(), currency.BTC, "12345") assert.NoError(t, err, "GetSingleFuturesPriceTriggeredOrder should not error") } func TestCancelFuturesPriceTriggeredOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelFuturesPriceTriggeredOrder(t.Context(), currency.USDT, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelFuturesPriceTriggeredOrder(t.Context(), currency.USDT, "12345") assert.NoError(t, err, "CancelFuturesPriceTriggeredOrder should not error") } func TestPlaceBatchFuturesOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.PlaceBatchFuturesOrders(t.Context(), currency.BTC, []ContractOrderCreateParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceBatchFuturesOrders(t.Context(), currency.BTC, []ContractOrderCreateParams{ { Contract: getPair(t, asset.CoinMarginedFutures), Size: 6024, @@ -1268,22 +1268,22 @@ func TestPlaceBatchFuturesOrders(t *testing.T) { func TestGetSingleFuturesOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSingleFuturesOrder(t.Context(), currency.BTC, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSingleFuturesOrder(t.Context(), currency.BTC, "12345") assert.NoError(t, err, "GetSingleFuturesOrder should not error") } func TestCancelSingleFuturesOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelSingleFuturesOrder(t.Context(), currency.BTC, "12345") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelSingleFuturesOrder(t.Context(), currency.BTC, "12345") assert.NoError(t, err, "CancelSingleFuturesOrder should not error") } func TestAmendFuturesOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.AmendFuturesOrder(t.Context(), currency.BTC, "1234", AmendFuturesOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.AmendFuturesOrder(t.Context(), currency.BTC, "1234", AmendFuturesOrderParam{ Price: 12345.990, }) assert.NoError(t, err, "AmendFuturesOrder should not error") @@ -1291,29 +1291,29 @@ func TestAmendFuturesOrder(t *testing.T) { func TestGetMyFuturesTradingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetMyFuturesTradingHistory(t.Context(), currency.BTC, "", "", getPair(t, asset.CoinMarginedFutures), 0, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMyFuturesTradingHistory(t.Context(), currency.BTC, "", "", getPair(t, asset.CoinMarginedFutures), 0, 0, 0) assert.NoError(t, err, "GetMyFuturesTradingHistory should not error") } func TestGetFuturesPositionCloseHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetFuturesPositionCloseHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, 0, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesPositionCloseHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, 0, time.Time{}, time.Time{}) assert.NoError(t, err, "GetFuturesPositionCloseHistory should not error") } func TestGetFuturesLiquidationHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetFuturesLiquidationHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetFuturesLiquidationHistory(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures), 0, time.Time{}) assert.NoError(t, err, "GetFuturesLiquidationHistory should not error") } func TestCountdownCancelOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CountdownCancelOrders(t.Context(), currency.BTC, CountdownParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CountdownCancelOrders(t.Context(), currency.BTC, CountdownParams{ Timeout: 8, }) assert.NoError(t, err, "CountdownCancelOrders should not error") @@ -1321,7 +1321,7 @@ func TestCountdownCancelOrders(t *testing.T) { func TestCreatePriceTriggeredFuturesOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) for _, tc := range []struct { c currency.Code a asset.Item @@ -1329,7 +1329,7 @@ func TestCreatePriceTriggeredFuturesOrder(t *testing.T) { {currency.BTC, asset.CoinMarginedFutures}, {currency.USDT, asset.USDTMarginedFutures}, } { - _, err := g.CreatePriceTriggeredFuturesOrder(t.Context(), tc.c, &FuturesPriceTriggeredOrderParam{ + _, err := e.CreatePriceTriggeredFuturesOrder(t.Context(), tc.c, &FuturesPriceTriggeredOrderParam{ Initial: FuturesInitial{ Price: 1234., Size: 2, @@ -1346,26 +1346,26 @@ func TestCreatePriceTriggeredFuturesOrder(t *testing.T) { func TestListAllFuturesAutoOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.ListAllFuturesAutoOrders(t.Context(), statusOpen, currency.BTC, currency.EMPTYPAIR, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.ListAllFuturesAutoOrders(t.Context(), statusOpen, currency.BTC, currency.EMPTYPAIR, 0, 0) assert.NoError(t, err, "ListAllFuturesAutoOrders should not error") } func TestCancelAllFuturesOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.CancelAllFuturesOpenOrders(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllFuturesOpenOrders(t.Context(), currency.BTC, getPair(t, asset.CoinMarginedFutures)) assert.NoError(t, err, "CancelAllFuturesOpenOrders should not error for CoinMarginedFutures") - _, err = g.CancelAllFuturesOpenOrders(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) + _, err = e.CancelAllFuturesOpenOrders(t.Context(), currency.USDT, getPair(t, asset.USDTMarginedFutures)) assert.NoError(t, err, "CancelAllFuturesOpenOrders should not error for USDTMarginedFutures") } func TestGetAllDeliveryContracts(t *testing.T) { t.Parallel() - r, err := g.GetAllDeliveryContracts(t.Context(), currency.USDT) + r, err := e.GetAllDeliveryContracts(t.Context(), currency.USDT) require.NoError(t, err, "GetAllDeliveryContracts must not error") assert.NotEmpty(t, r, "GetAllDeliveryContracts should return data") - r, err = g.GetAllDeliveryContracts(t.Context(), currency.BTC) + r, err = e.GetAllDeliveryContracts(t.Context(), currency.BTC) require.NoError(t, err, "GetAllDeliveryContracts must not error") // The test below will fail if support for BTC settlement is added. This is intentional, as it ensures we are alerted when it's time to reintroduce support if !assert.Empty(t, r, "GetAllDeliveryContracts should not return any data with unsupported settlement currency BTC") { @@ -1375,135 +1375,135 @@ func TestGetAllDeliveryContracts(t *testing.T) { func TestGetDeliveryContract(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryContract(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) + _, err := e.GetDeliveryContract(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) assert.NoError(t, err, "GetDeliveryContract should not error") } func TestGetDeliveryOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryOrderbook(t.Context(), currency.USDT, "0", getPair(t, asset.DeliveryFutures), 0, false) + _, err := e.GetDeliveryOrderbook(t.Context(), currency.USDT, "0", getPair(t, asset.DeliveryFutures), 0, false) assert.NoError(t, err, "GetDeliveryOrderbook should not error") } func TestGetDeliveryTradingHistory(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryTradingHistory(t.Context(), currency.USDT, "", getPair(t, asset.DeliveryFutures), 0, time.Time{}, time.Time{}) + _, err := e.GetDeliveryTradingHistory(t.Context(), currency.USDT, "", getPair(t, asset.DeliveryFutures), 0, time.Time{}, time.Time{}) assert.NoError(t, err, "GetDeliveryTradingHistory should not error") } func TestGetDeliveryFuturesCandlesticks(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryFuturesCandlesticks(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) + _, err := e.GetDeliveryFuturesCandlesticks(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), time.Time{}, time.Time{}, 0, kline.OneWeek) assert.NoError(t, err, "GetDeliveryFuturesCandlesticks should not error") } func TestGetDeliveryFutureTickers(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryFutureTickers(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) + _, err := e.GetDeliveryFutureTickers(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) assert.NoError(t, err, "GetDeliveryFutureTickers should not error") } func TestGetDeliveryInsuranceBalanceHistory(t *testing.T) { t.Parallel() - _, err := g.GetDeliveryInsuranceBalanceHistory(t.Context(), currency.BTC, 0) + _, err := e.GetDeliveryInsuranceBalanceHistory(t.Context(), currency.BTC, 0) assert.NoError(t, err, "GetDeliveryInsuranceBalanceHistory should not error") } func TestQueryDeliveryFuturesAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryFuturesAccounts(t.Context(), currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryFuturesAccounts(t.Context(), currency.USDT) assert.NoError(t, err, "GetDeliveryFuturesAccounts should not error") } func TestGetDeliveryAccountBooks(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetDeliveryAccountBooks(t.Context(), currency.USDT, 0, time.Time{}, time.Now(), "dnw") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDeliveryAccountBooks(t.Context(), currency.USDT, 0, time.Time{}, time.Now(), "dnw") assert.NoError(t, err, "GetDeliveryAccountBooks should not error") } func TestGetAllDeliveryPositionsOfUser(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetAllDeliveryPositionsOfUser(t.Context(), currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAllDeliveryPositionsOfUser(t.Context(), currency.USDT) assert.NoError(t, err, "GetAllDeliveryPositionsOfUser should not error") } func TestGetSingleDeliveryPosition(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetSingleDeliveryPosition(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSingleDeliveryPosition(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures)) assert.NoError(t, err, "GetSingleDeliveryPosition should not error") } func TestUpdateDeliveryPositionMargin(t *testing.T) { t.Parallel() - _, err := g.UpdateDeliveryPositionMargin(t.Context(), currency.EMPTYCODE, 0.001, currency.Pair{}) + _, err := e.UpdateDeliveryPositionMargin(t.Context(), currency.EMPTYCODE, 0.001, currency.Pair{}) assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err = g.UpdateDeliveryPositionMargin(t.Context(), currency.USDT, 0.001, getPair(t, asset.DeliveryFutures)) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.UpdateDeliveryPositionMargin(t.Context(), currency.USDT, 0.001, getPair(t, asset.DeliveryFutures)) assert.NoError(t, err, "UpdateDeliveryPositionMargin should not error") } func TestUpdateDeliveryPositionLeverage(t *testing.T) { t.Parallel() - _, err := g.UpdateDeliveryPositionLeverage(t.Context(), currency.EMPTYCODE, currency.Pair{}, 0.001) + _, err := e.UpdateDeliveryPositionLeverage(t.Context(), currency.EMPTYCODE, currency.Pair{}, 0.001) assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err = g.UpdateDeliveryPositionLeverage(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0.001) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.UpdateDeliveryPositionLeverage(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 0.001) assert.NoError(t, err, "UpdateDeliveryPositionLeverage should not error") } func TestUpdateDeliveryPositionRiskLimit(t *testing.T) { t.Parallel() - _, err := g.UpdateDeliveryPositionRiskLimit(t.Context(), currency.EMPTYCODE, currency.Pair{}, 0) + _, err := e.UpdateDeliveryPositionRiskLimit(t.Context(), currency.EMPTYCODE, currency.Pair{}, 0) assert.ErrorIs(t, err, errEmptyOrInvalidSettlementCurrency) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err = g.UpdateDeliveryPositionRiskLimit(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.UpdateDeliveryPositionRiskLimit(t.Context(), currency.USDT, getPair(t, asset.DeliveryFutures), 30) assert.NoError(t, err, "UpdateDeliveryPositionRiskLimit should not error") } func TestGetAllOptionsUnderlyings(t *testing.T) { t.Parallel() - if _, err := g.GetAllOptionsUnderlyings(t.Context()); err != nil { - t.Errorf("%s GetAllOptionsUnderlyings() error %v", g.Name, err) + if _, err := e.GetAllOptionsUnderlyings(t.Context()); err != nil { + t.Errorf("%s GetAllOptionsUnderlyings() error %v", e.Name, err) } } func TestGetExpirationTime(t *testing.T) { t.Parallel() - _, err := g.GetExpirationTime(t.Context(), "") + _, err := e.GetExpirationTime(t.Context(), "") assert.ErrorIs(t, err, errInvalidUnderlying) - _, err = g.GetExpirationTime(t.Context(), "BTC_USDT") + _, err = e.GetExpirationTime(t.Context(), "BTC_USDT") assert.NoError(t, err, "GetExpirationTime should not error") } func TestGetAllContractOfUnderlyingWithinExpiryDate(t *testing.T) { t.Parallel() - if _, err := g.GetAllContractOfUnderlyingWithinExpiryDate(t.Context(), "BTC_USDT", time.Time{}); err != nil { - t.Errorf("%s GetAllContractOfUnderlyingWithinExpiryDate() error %v", g.Name, err) + if _, err := e.GetAllContractOfUnderlyingWithinExpiryDate(t.Context(), "BTC_USDT", time.Time{}); err != nil { + t.Errorf("%s GetAllContractOfUnderlyingWithinExpiryDate() error %v", e.Name, err) } } func TestGetOptionsSpecifiedContractDetail(t *testing.T) { t.Parallel() - if _, err := g.GetOptionsSpecifiedContractDetail(t.Context(), getPair(t, asset.Options)); err != nil { - t.Errorf("%s GetOptionsSpecifiedContractDetail() error %v", g.Name, err) + if _, err := e.GetOptionsSpecifiedContractDetail(t.Context(), getPair(t, asset.Options)); err != nil { + t.Errorf("%s GetOptionsSpecifiedContractDetail() error %v", e.Name, err) } } func TestGetSettlementHistory(t *testing.T) { t.Parallel() - if _, err := g.GetSettlementHistory(t.Context(), "BTC_USDT", 0, 0, time.Time{}, time.Time{}); err != nil { - t.Errorf("%s GetSettlementHistory() error %v", g.Name, err) + if _, err := e.GetSettlementHistory(t.Context(), "BTC_USDT", 0, 0, time.Time{}, time.Time{}); err != nil { + t.Errorf("%s GetSettlementHistory() error %v", e.Name, err) } } func TestGetOptionsSpecifiedSettlementHistory(t *testing.T) { t.Parallel() underlying := "BTC_USDT" - optionsSettlement, err := g.GetSettlementHistory(t.Context(), underlying, 0, 1, time.Time{}, time.Time{}) + optionsSettlement, err := e.GetSettlementHistory(t.Context(), underlying, 0, 1, time.Time{}, time.Time{}) if err != nil { t.Fatal(err) } @@ -1511,15 +1511,15 @@ func TestGetOptionsSpecifiedSettlementHistory(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := g.GetOptionsSpecifiedContractsSettlement(t.Context(), cp, underlying, optionsSettlement[0].Timestamp.Time().Unix()); err != nil { - t.Errorf("%s GetOptionsSpecifiedContractsSettlement() error %s", g.Name, err) + if _, err := e.GetOptionsSpecifiedContractsSettlement(t.Context(), cp, underlying, optionsSettlement[0].Timestamp.Time().Unix()); err != nil { + t.Errorf("%s GetOptionsSpecifiedContractsSettlement() error %s", e.Name, err) } } func TestGetSupportedFlashSwapCurrencies(t *testing.T) { t.Parallel() - if _, err := g.GetSupportedFlashSwapCurrencies(t.Context()); err != nil { - t.Errorf("%s GetSupportedFlashSwapCurrencies() error %v", g.Name, err) + if _, err := e.GetSupportedFlashSwapCurrencies(t.Context()); err != nil { + t.Errorf("%s GetSupportedFlashSwapCurrencies() error %v", e.Name, err) } } @@ -1529,104 +1529,104 @@ func TestCreateFlashSwapOrder(t *testing.T) { t.Parallel() var response FlashSwapOrderResponse if err := json.Unmarshal([]byte(flashSwapOrderResponseJSON), &response); err != nil { - t.Errorf("%s error while deserializing to FlashSwapOrderResponse %v", g.Name, err) + t.Errorf("%s error while deserializing to FlashSwapOrderResponse %v", e.Name, err) } - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CreateFlashSwapOrder(t.Context(), FlashSwapOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CreateFlashSwapOrder(t.Context(), FlashSwapOrderParams{ PreviewID: "1234", SellCurrency: currency.USDT, BuyCurrency: currency.BTC, BuyAmount: 34234, SellAmount: 34234, }); err != nil { - t.Errorf("%s CreateFlashSwapOrder() error %v", g.Name, err) + t.Errorf("%s CreateFlashSwapOrder() error %v", e.Name, err) } } func TestGetAllFlashSwapOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetAllFlashSwapOrders(t.Context(), 1, currency.EMPTYCODE, currency.EMPTYCODE, true, 0, 0); err != nil { - t.Errorf("%s GetAllFlashSwapOrders() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetAllFlashSwapOrders(t.Context(), 1, currency.EMPTYCODE, currency.EMPTYCODE, true, 0, 0); err != nil { + t.Errorf("%s GetAllFlashSwapOrders() error %v", e.Name, err) } } func TestGetSingleFlashSwapOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSingleFlashSwapOrder(t.Context(), "1234"); err != nil { - t.Errorf("%s GetSingleFlashSwapOrder() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSingleFlashSwapOrder(t.Context(), "1234"); err != nil { + t.Errorf("%s GetSingleFlashSwapOrder() error %v", e.Name, err) } } func TestInitiateFlashSwapOrderReview(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.InitiateFlashSwapOrderReview(t.Context(), FlashSwapOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.InitiateFlashSwapOrderReview(t.Context(), FlashSwapOrderParams{ PreviewID: "1234", SellCurrency: currency.USDT, BuyCurrency: currency.BTC, SellAmount: 100, }); err != nil { - t.Errorf("%s InitiateFlashSwapOrderReview() error %v", g.Name, err) + t.Errorf("%s InitiateFlashSwapOrderReview() error %v", e.Name, err) } } func TestGetMyOptionsSettlements(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetMyOptionsSettlements(t.Context(), "BTC_USDT", currency.EMPTYPAIR, 0, 0, time.Time{}); err != nil { - t.Errorf("%s GetMyOptionsSettlements() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetMyOptionsSettlements(t.Context(), "BTC_USDT", currency.EMPTYPAIR, 0, 0, time.Time{}); err != nil { + t.Errorf("%s GetMyOptionsSettlements() error %v", e.Name, err) } } func TestGetOptionAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetOptionAccounts(t.Context()); err != nil { - t.Errorf("%s GetOptionAccounts() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetOptionAccounts(t.Context()); err != nil { + t.Errorf("%s GetOptionAccounts() error %v", e.Name, err) } } func TestGetAccountChangingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetAccountChangingHistory(t.Context(), 0, 0, time.Time{}, time.Time{}, ""); err != nil { - t.Errorf("%s GetAccountChangingHistory() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetAccountChangingHistory(t.Context(), 0, 0, time.Time{}, time.Time{}, ""); err != nil { + t.Errorf("%s GetAccountChangingHistory() error %v", e.Name, err) } } func TestGetUsersPositionSpecifiedUnderlying(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetUsersPositionSpecifiedUnderlying(t.Context(), ""); err != nil { - t.Errorf("%s GetUsersPositionSpecifiedUnderlying() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetUsersPositionSpecifiedUnderlying(t.Context(), ""); err != nil { + t.Errorf("%s GetUsersPositionSpecifiedUnderlying() error %v", e.Name, err) } } func TestGetSpecifiedContractPosition(t *testing.T) { t.Parallel() - _, err := g.GetSpecifiedContractPosition(t.Context(), currency.EMPTYPAIR) + _, err := e.GetSpecifiedContractPosition(t.Context(), currency.EMPTYPAIR) assert.ErrorIs(t, err, errInvalidOrMissingContractParam) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = g.GetSpecifiedContractPosition(t.Context(), getPair(t, asset.Options)) + _, err = e.GetSpecifiedContractPosition(t.Context(), getPair(t, asset.Options)) assert.NoError(t, err, "GetSpecifiedContractPosition should not error") } func TestGetUsersLiquidationHistoryForSpecifiedUnderlying(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetUsersLiquidationHistoryForSpecifiedUnderlying(t.Context(), "BTC_USDT", currency.EMPTYPAIR); err != nil { - t.Errorf("%s GetUsersLiquidationHistoryForSpecifiedUnderlying() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetUsersLiquidationHistoryForSpecifiedUnderlying(t.Context(), "BTC_USDT", currency.EMPTYPAIR); err != nil { + t.Errorf("%s GetUsersLiquidationHistoryForSpecifiedUnderlying() error %v", e.Name, err) } } func TestPlaceOptionOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err := g.PlaceOptionOrder(t.Context(), &OptionOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceOptionOrder(t.Context(), &OptionOrderParam{ Contract: getPair(t, asset.Options).String(), OrderSize: -1, Iceberg: 0, @@ -1635,115 +1635,115 @@ func TestPlaceOptionOrder(t *testing.T) { Price: 100, }) if err != nil { - t.Errorf("%s PlaceOptionOrder() error %v", g.Name, err) + t.Errorf("%s PlaceOptionOrder() error %v", e.Name, err) } } func TestGetOptionFuturesOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetOptionFuturesOrders(t.Context(), currency.EMPTYPAIR, "", "", 0, 0, time.Time{}, time.Time{}); err != nil { - t.Errorf("%s GetOptionFuturesOrders() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetOptionFuturesOrders(t.Context(), currency.EMPTYPAIR, "", "", 0, 0, time.Time{}, time.Time{}); err != nil { + t.Errorf("%s GetOptionFuturesOrders() error %v", e.Name, err) } } func TestCancelOptionOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelMultipleOptionOpenOrders(t.Context(), getPair(t, asset.Options), "", ""); err != nil { - t.Errorf("%s CancelOptionOpenOrders() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelMultipleOptionOpenOrders(t.Context(), getPair(t, asset.Options), "", ""); err != nil { + t.Errorf("%s CancelOptionOpenOrders() error %v", e.Name, err) } } func TestGetSingleOptionOrder(t *testing.T) { t.Parallel() - _, err := g.GetSingleOptionOrder(t.Context(), "") + _, err := e.GetSingleOptionOrder(t.Context(), "") assert.ErrorIs(t, err, errInvalidOrderID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err = g.GetSingleOptionOrder(t.Context(), "1234") + _, err = e.GetSingleOptionOrder(t.Context(), "1234") assert.NoError(t, err, "GetSingleOptionOrder should not error") } func TestCancelSingleOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelOptionSingleOrder(t.Context(), "1234"); err != nil { - t.Errorf("%s CancelSingleOrder() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelOptionSingleOrder(t.Context(), "1234"); err != nil { + t.Errorf("%s CancelSingleOrder() error %v", e.Name, err) } } func TestGetMyOptionsTradingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetMyOptionsTradingHistory(t.Context(), "BTC_USDT", currency.EMPTYPAIR, 0, 0, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMyOptionsTradingHistory(t.Context(), "BTC_USDT", currency.EMPTYPAIR, 0, 0, time.Time{}, time.Time{}) require.NoError(t, err) } func TestWithdrawCurrency(t *testing.T) { t.Parallel() - _, err := g.WithdrawCurrency(t.Context(), WithdrawalRequestParam{}) + _, err := e.WithdrawCurrency(t.Context(), WithdrawalRequestParam{}) assert.ErrorIs(t, err, errInvalidAmount) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - _, err = g.WithdrawCurrency(t.Context(), WithdrawalRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.WithdrawCurrency(t.Context(), WithdrawalRequestParam{ Currency: currency.BTC, Amount: 0.00000001, Chain: "BTC", Address: core.BitcoinDonationAddress, }) if err != nil { - t.Errorf("%s WithdrawCurrency() expecting error %v, but found %v", g.Name, errInvalidAmount, err) + t.Errorf("%s WithdrawCurrency() expecting error %v, but found %v", e.Name, errInvalidAmount, err) } } func TestCancelWithdrawalWithSpecifiedID(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CancelWithdrawalWithSpecifiedID(t.Context(), "1234567"); err != nil { - t.Errorf("%s CancelWithdrawalWithSpecifiedID() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CancelWithdrawalWithSpecifiedID(t.Context(), "1234567"); err != nil { + t.Errorf("%s CancelWithdrawalWithSpecifiedID() error %v", e.Name, err) } } func TestGetOptionsOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetOptionsOrderbook(t.Context(), getPair(t, asset.Options), "0.1", 9, true) + _, err := e.GetOptionsOrderbook(t.Context(), getPair(t, asset.Options), "0.1", 9, true) assert.NoError(t, err, "GetOptionsOrderbook should not error") } func TestGetOptionsTickers(t *testing.T) { t.Parallel() - if _, err := g.GetOptionsTickers(t.Context(), "BTC_USDT"); err != nil { - t.Errorf("%s GetOptionsTickers() error %v", g.Name, err) + if _, err := e.GetOptionsTickers(t.Context(), "BTC_USDT"); err != nil { + t.Errorf("%s GetOptionsTickers() error %v", e.Name, err) } } func TestGetOptionUnderlyingTickers(t *testing.T) { t.Parallel() - if _, err := g.GetOptionUnderlyingTickers(t.Context(), "BTC_USDT"); err != nil { - t.Errorf("%s GetOptionUnderlyingTickers() error %v", g.Name, err) + if _, err := e.GetOptionUnderlyingTickers(t.Context(), "BTC_USDT"); err != nil { + t.Errorf("%s GetOptionUnderlyingTickers() error %v", e.Name, err) } } func TestGetOptionFuturesCandlesticks(t *testing.T) { t.Parallel() - if _, err := g.GetOptionFuturesCandlesticks(t.Context(), getPair(t, asset.Options), 0, time.Now().Add(-time.Hour*10), time.Time{}, kline.ThirtyMin); err != nil { + if _, err := e.GetOptionFuturesCandlesticks(t.Context(), getPair(t, asset.Options), 0, time.Now().Add(-time.Hour*10), time.Time{}, kline.ThirtyMin); err != nil { t.Error(err) } } func TestGetOptionFuturesMarkPriceCandlesticks(t *testing.T) { t.Parallel() - if _, err := g.GetOptionFuturesMarkPriceCandlesticks(t.Context(), "BTC_USDT", 0, time.Time{}, time.Time{}, kline.OneMonth); err != nil { - t.Errorf("%s GetOptionFuturesMarkPriceCandlesticks() error %v", g.Name, err) + if _, err := e.GetOptionFuturesMarkPriceCandlesticks(t.Context(), "BTC_USDT", 0, time.Time{}, time.Time{}, kline.OneMonth); err != nil { + t.Errorf("%s GetOptionFuturesMarkPriceCandlesticks() error %v", e.Name, err) } } func TestGetOptionsTradeHistory(t *testing.T) { t.Parallel() - if _, err := g.GetOptionsTradeHistory(t.Context(), getPair(t, asset.Options), "C", 0, 0, time.Time{}, time.Time{}); err != nil { - t.Errorf("%s GetOptionsTradeHistory() error %v", g.Name, err) + if _, err := e.GetOptionsTradeHistory(t.Context(), getPair(t, asset.Options), "C", 0, 0, time.Time{}, time.Time{}); err != nil { + t.Errorf("%s GetOptionsTradeHistory() error %v", e.Name, err) } } @@ -1751,27 +1751,27 @@ func TestGetOptionsTradeHistory(t *testing.T) { func TestCreateNewSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CreateNewSubAccount(t.Context(), SubAccountParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CreateNewSubAccount(t.Context(), SubAccountParams{ LoginName: "Sub_Account_for_testing", }); err != nil { - t.Errorf("%s CreateNewSubAccount() error %v", g.Name, err) + t.Errorf("%s CreateNewSubAccount() error %v", e.Name, err) } } func TestGetSubAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSubAccounts(t.Context()); err != nil { - t.Errorf("%s GetSubAccounts() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSubAccounts(t.Context()); err != nil { + t.Errorf("%s GetSubAccounts() error %v", e.Name, err) } } func TestGetSingleSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetSingleSubAccount(t.Context(), "123423"); err != nil { - t.Errorf("%s GetSingleSubAccount() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetSingleSubAccount(t.Context(), "123423"); err != nil { + t.Errorf("%s GetSingleSubAccount() error %v", e.Name, err) } } @@ -1779,8 +1779,8 @@ func TestGetSingleSubAccount(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - for _, a := range g.GetAssetTypes(false) { - pairs, err := g.FetchTradablePairs(t.Context(), a) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.FetchTradablePairs(t.Context(), a) require.NoErrorf(t, err, "FetchTradablePairs must not error for %s", a) require.NotEmptyf(t, pairs, "FetchTradablePairs must return some pairs for %s", a) if a == asset.USDTMarginedFutures || a == asset.CoinMarginedFutures { @@ -1794,19 +1794,19 @@ func TestFetchTradablePairs(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - for _, a := range g.GetAssetTypes(false) { - err := g.UpdateTickers(t.Context(), a) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateTickers(t.Context(), a) assert.NoErrorf(t, err, "UpdateTickers should not error for %s", a) } } func TestUpdateOrderbook(t *testing.T) { t.Parallel() - for _, a := range g.GetAssetTypes(false) { + for _, a := range e.GetAssetTypes(false) { pair := getPair(t, a) t.Run(a.String()+" "+pair.String(), func(t *testing.T) { t.Parallel() - o, err := g.UpdateOrderbook(t.Context(), pair, a) + o, err := e.UpdateOrderbook(t.Context(), pair, a) require.NoError(t, err) if a != asset.Options { // Options orderbooks can be empty assert.NotEmpty(t, o.Bids) @@ -1818,27 +1818,27 @@ func TestUpdateOrderbook(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if _, err := g.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Empty); err != nil { - t.Errorf("%s GetWithdrawalsHistory() error %v", g.Name, err) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Empty); err != nil { + t.Errorf("%s GetWithdrawalsHistory() error %v", e.Name, err) } } func TestGetRecentTrades(t *testing.T) { t.Parallel() - for _, a := range g.GetAssetTypes(false) { + for _, a := range e.GetAssetTypes(false) { if a != asset.CoinMarginedFutures { - _, err := g.GetRecentTrades(t.Context(), getPair(t, a), a) + _, err := e.GetRecentTrades(t.Context(), getPair(t, a), a) assert.NoErrorf(t, err, "GetRecentTrades should not error for %s", a) } } } func TestSubmitOrder(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - for _, a := range g.GetAssetTypes(false) { - _, err := g.SubmitOrder(t.Context(), &order.Submit{ - Exchange: g.Name, + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + for _, a := range e.GetAssetTypes(false) { + _, err := e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Pair: getPair(t, a), Side: order.Buy, Type: order.Limit, @@ -1852,23 +1852,23 @@ func TestSubmitOrder(t *testing.T) { } func TestCancelExchangeOrder(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - for _, a := range g.GetAssetTypes(false) { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + for _, a := range e.GetAssetTypes(false) { orderCancellation := &order.Cancel{ OrderID: "1", AccountID: "1", Pair: getPair(t, a), AssetType: a, } - err := g.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) assert.NoErrorf(t, err, "CancelOrder should not error for %s", a) } } func TestCancelBatchOrders(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - for _, a := range g.GetAssetTypes(false) { - _, err := g.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + for _, a := range e.GetAssetTypes(false) { + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1", AccountID: "1", @@ -1886,13 +1886,13 @@ func TestCancelBatchOrders(t *testing.T) { } func TestGetDepositAddress(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - chains, err := g.GetAvailableTransferChains(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + chains, err := e.GetAvailableTransferChains(t.Context(), currency.BTC) if err != nil { t.Fatal(err) } for i := range chains { - _, err = g.GetDepositAddress(t.Context(), currency.BTC, "", chains[i]) + _, err = e.GetDepositAddress(t.Context(), currency.BTC, "", chains[i]) if err != nil { t.Error("Test Fail - GetDepositAddress error", err) } @@ -1900,13 +1900,13 @@ func TestGetDepositAddress(t *testing.T) { } func TestGetActiveOrders(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - for _, a := range g.GetAssetTypes(false) { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + for _, a := range e.GetAssetTypes(false) { enabledPairs := getPairs(t, a) if len(enabledPairs) > 2 { enabledPairs = enabledPairs[:2] } - _, err := g.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ + _, err := e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ Pairs: enabledPairs, Type: order.AnyType, Side: order.AnySide, @@ -1917,8 +1917,8 @@ func TestGetActiveOrders(t *testing.T) { } func TestGetOrderHistory(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - for _, a := range g.GetAssetTypes(false) { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + for _, a := range e.GetAssetTypes(false) { enabledPairs := getPairs(t, a) if len(enabledPairs) > 4 { enabledPairs = enabledPairs[:4] @@ -1929,7 +1929,7 @@ func TestGetOrderHistory(t *testing.T) { Pairs: enabledPairs, AssetType: a, } - _, err := g.GetOrderHistory(t.Context(), &multiOrderRequest) + _, err := e.GetOrderHistory(t.Context(), &multiOrderRequest) assert.NoErrorf(t, err, "GetOrderHistory should not error for %s", a) } } @@ -1937,8 +1937,8 @@ func TestGetOrderHistory(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() startTime := time.Now().Add(-time.Hour * 10) - for _, a := range g.GetAssetTypes(false) { - _, err := g.GetHistoricCandles(t.Context(), getPair(t, a), a, kline.OneDay, startTime, time.Now()) + for _, a := range e.GetAssetTypes(false) { + _, err := e.GetHistoricCandles(t.Context(), getPair(t, a), a, kline.OneDay, startTime, time.Now()) if a == asset.Options { assert.ErrorIs(t, err, asset.ErrNotSupported, "GetHistoricCandles should error correctly for options") } else { @@ -1950,8 +1950,8 @@ func TestGetHistoricCandles(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() startTime := time.Now().Add(-time.Hour * 5) - for _, a := range g.GetAssetTypes(false) { - _, err := g.GetHistoricCandlesExtended(t.Context(), getPair(t, a), a, kline.OneMin, startTime, time.Now()) + for _, a := range e.GetAssetTypes(false) { + _, err := e.GetHistoricCandlesExtended(t.Context(), getPair(t, a), a, kline.OneMin, startTime, time.Now()) if a == asset.Options { assert.ErrorIs(t, err, asset.ErrNotSupported, "GetHistoricCandlesExtended should error correctly for options") } else { @@ -1962,7 +1962,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { func TestGetAvailableTransferTrains(t *testing.T) { t.Parallel() - _, err := g.GetAvailableTransferChains(t.Context(), currency.USDT) + _, err := e.GetAvailableTransferChains(t.Context(), currency.USDT) if err != nil { t.Error(err) } @@ -1970,7 +1970,7 @@ func TestGetAvailableTransferTrains(t *testing.T) { func TestGetUnderlyingFromCurrencyPair(t *testing.T) { t.Parallel() - if uly, err := g.GetUnderlyingFromCurrencyPair(currency.Pair{Delimiter: currency.UnderscoreDelimiter, Base: currency.BTC, Quote: currency.NewCode("USDT_LLK")}); err != nil { + if uly, err := e.GetUnderlyingFromCurrencyPair(currency.Pair{Delimiter: currency.UnderscoreDelimiter, Base: currency.BTC, Quote: currency.NewCode("USDT_LLK")}); err != nil { t.Error(err) } else if !uly.Equal(currency.NewBTCUSDT()) { t.Error("unexpected underlying") @@ -1981,8 +1981,8 @@ const wsTickerPushDataJSON = `{"time": 1606291803, "channel": "spot.tickers", "e func TestWsTickerPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsTickerPushDataJSON)); err != nil { - t.Errorf("%s websocket ticker push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsTickerPushDataJSON)); err != nil { + t.Errorf("%s websocket ticker push data error: %v", e.Name, err) } } @@ -1990,8 +1990,8 @@ const wsTradePushDataJSON = `{ "time": 1606292218, "channel": "spot.trades", "ev func TestWsTradePushData(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsTradePushDataJSON)); err != nil { - t.Errorf("%s websocket trade push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsTradePushDataJSON)); err != nil { + t.Errorf("%s websocket trade push data error: %v", e.Name, err) } } @@ -1999,8 +1999,8 @@ const wsCandlestickPushDataJSON = `{"time": 1606292600, "channel": "spot.candles func TestWsCandlestickPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsCandlestickPushDataJSON)); err != nil { - t.Errorf("%s websocket candlestick push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsCandlestickPushDataJSON)); err != nil { + t.Errorf("%s websocket candlestick push data error: %v", e.Name, err) } } @@ -2008,8 +2008,8 @@ const wsOrderbookTickerJSON = `{"time": 1606293275, "channel": "spot.book_ticker func TestWsOrderbookTickerPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsOrderbookTickerJSON)); err != nil { - t.Errorf("%s websocket orderbook push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsOrderbookTickerJSON)); err != nil { + t.Errorf("%s websocket orderbook push data error: %v", e.Name, err) } } @@ -2020,12 +2020,12 @@ const ( func TestWsOrderbookSnapshotPushData(t *testing.T) { t.Parallel() - err := g.WsHandleSpotData(t.Context(), []byte(wsOrderbookSnapshotPushDataJSON)) + err := e.WsHandleSpotData(t.Context(), []byte(wsOrderbookSnapshotPushDataJSON)) if err != nil { - t.Errorf("%s websocket orderbook snapshot push data error: %v", g.Name, err) + t.Errorf("%s websocket orderbook snapshot push data error: %v", e.Name, err) } - if err = g.WsHandleSpotData(t.Context(), []byte(wsOrderbookUpdatePushDataJSON)); err != nil { - t.Errorf("%s websocket orderbook update push data error: %v", g.Name, err) + if err = e.WsHandleSpotData(t.Context(), []byte(wsOrderbookUpdatePushDataJSON)); err != nil { + t.Errorf("%s websocket orderbook update push data error: %v", e.Name, err) } } @@ -2033,8 +2033,8 @@ const wsSpotOrderPushDataJSON = `{"time": 1605175506, "channel": "spot.orders", func TestWsPushOrders(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsSpotOrderPushDataJSON)); err != nil { - t.Errorf("%s websocket orders push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsSpotOrderPushDataJSON)); err != nil { + t.Errorf("%s websocket orders push data error: %v", e.Name, err) } } @@ -2042,8 +2042,8 @@ const wsUserTradePushDataJSON = `{"time": 1605176741, "channel": "spot.usertrade func TestWsUserTradesPushDataJSON(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsUserTradePushDataJSON)); err != nil { - t.Errorf("%s websocket users trade push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsUserTradePushDataJSON)); err != nil { + t.Errorf("%s websocket users trade push data error: %v", e.Name, err) } } @@ -2052,8 +2052,8 @@ const wsBalancesPushDataJSON = `{"time": 1605248616, "channel": "spot.balances", func TestBalancesPushData(t *testing.T) { t.Parallel() ctx := account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: "test"}) - if err := g.WsHandleSpotData(ctx, []byte(wsBalancesPushDataJSON)); err != nil { - t.Errorf("%s websocket balances push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(ctx, []byte(wsBalancesPushDataJSON)); err != nil { + t.Errorf("%s websocket balances push data error: %v", e.Name, err) } } @@ -2061,8 +2061,8 @@ const wsMarginBalancePushDataJSON = `{"time": 1605248616, "channel": "spot.fundi func TestMarginBalancePushData(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsMarginBalancePushDataJSON)); err != nil { - t.Errorf("%s websocket margin balance push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsMarginBalancePushDataJSON)); err != nil { + t.Errorf("%s websocket margin balance push data error: %v", e.Name, err) } } @@ -2071,8 +2071,8 @@ const wsCrossMarginBalancePushDataJSON = `{"time": 1605248616,"channel": "spot.c func TestCrossMarginBalancePushData(t *testing.T) { t.Parallel() ctx := account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: "test"}) - if err := g.WsHandleSpotData(ctx, []byte(wsCrossMarginBalancePushDataJSON)); err != nil { - t.Errorf("%s websocket cross margin balance push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(ctx, []byte(wsCrossMarginBalancePushDataJSON)); err != nil { + t.Errorf("%s websocket cross margin balance push data error: %v", e.Name, err) } } @@ -2080,25 +2080,25 @@ const wsCrossMarginBalanceLoan = `{ "time":1658289372, "channel":"spot.cross_loa func TestCrossMarginBalanceLoan(t *testing.T) { t.Parallel() - if err := g.WsHandleSpotData(t.Context(), []byte(wsCrossMarginBalanceLoan)); err != nil { - t.Errorf("%s websocket cross margin loan push data error: %v", g.Name, err) + if err := e.WsHandleSpotData(t.Context(), []byte(wsCrossMarginBalanceLoan)); err != nil { + t.Errorf("%s websocket cross margin loan push data error: %v", e.Name, err) } } // TestFuturesDataHandler ensures that messages from various futures channels do not error func TestFuturesDataHandler(t *testing.T) { t.Parallel() - g := new(Gateio) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(g), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") testexch.FixtureToDataHandler(t, "testdata/wsFutures.json", func(ctx context.Context, m []byte) error { if strings.Contains(string(m), "futures.balances") { ctx = account.DeployCredentialsToContext(ctx, &account.Credentials{Key: "test", Secret: "test"}) } - return g.WsHandleFuturesData(ctx, m, asset.CoinMarginedFutures) + return e.WsHandleFuturesData(ctx, m, asset.CoinMarginedFutures) }) - close(g.Websocket.DataHandler) - assert.Len(t, g.Websocket.DataHandler, 14, "Should see the correct number of messages") - for resp := range g.Websocket.DataHandler { + close(e.Websocket.DataHandler) + assert.Len(t, e.Websocket.DataHandler, 14, "Should see the correct number of messages") + for resp := range e.Websocket.DataHandler { if err, isErr := resp.(error); isErr { assert.NoError(t, err, "Should not get any errors down the data handler") } @@ -2111,8 +2111,8 @@ const optionsContractTickerPushDataJSON = `{"time": 1630576352, "channel": "opti func TestOptionsContractTickerPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsContractTickerPushDataJSON)); err != nil { - t.Errorf("%s websocket options contract ticker push data failed with error %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsContractTickerPushDataJSON)); err != nil { + t.Errorf("%s websocket options contract ticker push data failed with error %v", e.Name, err) } } @@ -2120,8 +2120,8 @@ const optionsUnderlyingTickerPushDataJSON = `{"time": 1630576352, "channel": "op func TestOptionsUnderlyingTickerPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingTickerPushDataJSON)); err != nil { - t.Errorf("%s websocket options underlying ticker push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingTickerPushDataJSON)); err != nil { + t.Errorf("%s websocket options underlying ticker push data error: %v", e.Name, err) } } @@ -2129,8 +2129,8 @@ const optionsContractTradesPushDataJSON = `{"time": 1630576356, "channel": "opti func TestOptionsContractTradesPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsContractTradesPushDataJSON)); err != nil { - t.Errorf("%s websocket contract trades push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsContractTradesPushDataJSON)); err != nil { + t.Errorf("%s websocket contract trades push data error: %v", e.Name, err) } } @@ -2138,8 +2138,8 @@ const optionsUnderlyingTradesPushDataJSON = `{"time": 1630576356, "channel": "op func TestOptionsUnderlyingTradesPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingTradesPushDataJSON)); err != nil { - t.Errorf("%s websocket underlying trades push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingTradesPushDataJSON)); err != nil { + t.Errorf("%s websocket underlying trades push data error: %v", e.Name, err) } } @@ -2147,8 +2147,8 @@ const optionsUnderlyingPricePushDataJSON = `{ "time": 1630576356, "channel": "op func TestOptionsUnderlyingPricePushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingPricePushDataJSON)); err != nil { - t.Errorf("%s websocket underlying price push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingPricePushDataJSON)); err != nil { + t.Errorf("%s websocket underlying price push data error: %v", e.Name, err) } } @@ -2156,8 +2156,8 @@ const optionsMarkPricePushDataJSON = `{ "time": 1630576356, "channel": "options. func TestOptionsMarkPricePushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsMarkPricePushDataJSON)); err != nil { - t.Errorf("%s websocket mark price push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsMarkPricePushDataJSON)); err != nil { + t.Errorf("%s websocket mark price push data error: %v", e.Name, err) } } @@ -2165,8 +2165,8 @@ const optionsSettlementsPushDataJSON = `{ "time": 1630576356, "channel": "option func TestSettlementsPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsSettlementsPushDataJSON)); err != nil { - t.Errorf("%s websocket options settlements push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsSettlementsPushDataJSON)); err != nil { + t.Errorf("%s websocket options settlements push data error: %v", e.Name, err) } } @@ -2174,8 +2174,8 @@ const optionsContractPushDataJSON = `{"time": 1630576356, "channel": "options.co func TestOptionsContractPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsContractPushDataJSON)); err != nil { - t.Errorf("%s websocket options contracts push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsContractPushDataJSON)); err != nil { + t.Errorf("%s websocket options contracts push data error: %v", e.Name, err) } } @@ -2186,11 +2186,11 @@ const ( func TestOptionsCandlesticksPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsContractCandlesticksPushDataJSON)); err != nil { - t.Errorf("%s websocket options contracts candlestick push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsContractCandlesticksPushDataJSON)); err != nil { + t.Errorf("%s websocket options contracts candlestick push data error: %v", e.Name, err) } - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingCandlesticksPushDataJSON)); err != nil { - t.Errorf("%s websocket options underlying candlestick push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsUnderlyingCandlesticksPushDataJSON)); err != nil { + t.Errorf("%s websocket options underlying candlestick push data error: %v", e.Name, err) } } @@ -2204,18 +2204,18 @@ const ( func TestOptionsOrderbookPushData(t *testing.T) { t.Parallel() p := getPair(t, asset.Options) - assert.NoError(t, g.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookTickerPushDataJSON))) - assert.NoError(t, g.WsHandleOptionsData(t.Context(), fmt.Appendf(nil, optionsOrderbookUpdatePushDataJSON, p.Upper().String()))) - assert.NoError(t, g.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookSnapshotPushDataJSON))) - assert.NoError(t, g.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookSnapshotUpdateEventPushDataJSON))) + assert.NoError(t, e.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookTickerPushDataJSON))) + assert.NoError(t, e.WsHandleOptionsData(t.Context(), fmt.Appendf(nil, optionsOrderbookUpdatePushDataJSON, p.Upper().String()))) + assert.NoError(t, e.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookSnapshotPushDataJSON))) + assert.NoError(t, e.WsHandleOptionsData(t.Context(), []byte(optionsOrderbookSnapshotUpdateEventPushDataJSON))) } const optionsOrderPushDataJSON = `{"time": 1630654851,"channel": "options.orders", "event": "update", "result": [ { "contract": "BTC_USDT-20211130-65000-C", "create_time": 1637897000, "fill_price": 0, "finish_as": "cancelled", "iceberg": 0, "id": 106, "is_close": false, "is_liq": false, "is_reduce_only": false, "left": -10, "mkfr": 0.0004, "price": 15000, "refr": 0, "refu": 0, "size": -10, "status": "finished", "text": "web", "tif": "gtc", "tkfr": 0.0004, "underlying": "BTC_USDT", "user": "9xxx", "time": 1639051907,"time_ms": 1639051907000}]}` func TestOptionsOrderPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsOrderPushDataJSON)); err != nil { - t.Errorf("%s websocket options orders push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsOrderPushDataJSON)); err != nil { + t.Errorf("%s websocket options orders push data error: %v", e.Name, err) } } @@ -2223,8 +2223,8 @@ const optionsUsersTradesPushDataJSON = `{ "time": 1639144214, "channel": "option func TestOptionUserTradesPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsUsersTradesPushDataJSON)); err != nil { - t.Errorf("%s websocket options orders push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsUsersTradesPushDataJSON)); err != nil { + t.Errorf("%s websocket options orders push data error: %v", e.Name, err) } } @@ -2232,8 +2232,8 @@ const optionsLiquidatesPushDataJSON = `{ "channel": "options.liquidates", "event func TestOptionsLiquidatesPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsLiquidatesPushDataJSON)); err != nil { - t.Errorf("%s websocket options liquidates push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsLiquidatesPushDataJSON)); err != nil { + t.Errorf("%s websocket options liquidates push data error: %v", e.Name, err) } } @@ -2241,8 +2241,8 @@ const optionsSettlementPushDataJSON = `{ "channel": "options.user_settlements", func TestOptionsSettlementPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsSettlementPushDataJSON)); err != nil { - t.Errorf("%s websocket options settlement push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsSettlementPushDataJSON)); err != nil { + t.Errorf("%s websocket options settlement push data error: %v", e.Name, err) } } @@ -2250,8 +2250,8 @@ const optionsPositionClosePushDataJSON = `{"channel": "options.position_closes", func TestOptionsPositionClosePushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsPositionClosePushDataJSON)); err != nil { - t.Errorf("%s websocket options position close push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsPositionClosePushDataJSON)); err != nil { + t.Errorf("%s websocket options position close push data error: %v", e.Name, err) } } @@ -2260,8 +2260,8 @@ const optionsBalancePushDataJSON = `{ "channel": "options.balances", "event": "u func TestOptionsBalancePushData(t *testing.T) { t.Parallel() ctx := account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: "test"}) - if err := g.WsHandleOptionsData(ctx, []byte(optionsBalancePushDataJSON)); err != nil { - t.Errorf("%s websocket options balance push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(ctx, []byte(optionsBalancePushDataJSON)); err != nil { + t.Errorf("%s websocket options balance push data error: %v", e.Name, err) } } @@ -2269,28 +2269,28 @@ const optionsPositionPushDataJSON = `{"time": 1630654851, "channel": "options.po func TestOptionsPositionPushData(t *testing.T) { t.Parallel() - if err := g.WsHandleOptionsData(t.Context(), []byte(optionsPositionPushDataJSON)); err != nil { - t.Errorf("%s websocket options position push data error: %v", g.Name, err) + if err := e.WsHandleOptionsData(t.Context(), []byte(optionsPositionPushDataJSON)); err != nil { + t.Errorf("%s websocket options position push data error: %v", e.Name, err) } } func TestGenerateSubscriptionsSpot(t *testing.T) { t.Parallel() - g := new(Gateio) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(g), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - g.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := g.generateSubscriptionsSpot() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptionsSpot() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - assets := slices.DeleteFunc(g.GetAssetTypes(true), func(a asset.Item) bool { return !g.IsAssetWebsocketSupported(a) }) - for _, s := range g.Features.Subscriptions { + assets := slices.DeleteFunc(e.GetAssetTypes(true), func(a asset.Item) bool { return !e.IsAssetWebsocketSupported(a) }) + for _, s := range e.Features.Subscriptions { for _, a := range assets { if s.Asset != asset.All && s.Asset != a { continue } - pairs, err := g.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) pairs = common.SortStrings(pairs).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}) s := s.Clone() //nolint:govet // Intentional lexical scope shadow @@ -2321,47 +2321,47 @@ func TestGenerateSubscriptionsSpot(t *testing.T) { func TestSubscribe(t *testing.T) { t.Parallel() - subs, err := g.Features.Subscriptions.ExpandTemplates(g) + subs, err := e.Features.Subscriptions.ExpandTemplates(e) require.NoError(t, err, "ExpandTemplates must not error") - g.Features.Subscriptions = subscription.List{} - err = g.Subscribe(t.Context(), &DummyConnection{}, subs) + e.Features.Subscriptions = subscription.List{} + err = e.Subscribe(t.Context(), &DummyConnection{}, subs) require.NoError(t, err, "Subscribe must not error") } func TestGenerateDeliveryFuturesDefaultSubscriptions(t *testing.T) { t.Parallel() - if _, err := g.GenerateDeliveryFuturesDefaultSubscriptions(); err != nil { + if _, err := e.GenerateDeliveryFuturesDefaultSubscriptions(); err != nil { t.Error(err) } } func TestGenerateFuturesDefaultSubscriptions(t *testing.T) { t.Parallel() - g := new(Gateio) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(g), "Test instance Setup must not error") - subs, err := g.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + subs, err := e.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) require.NoError(t, err) require.NotEmpty(t, subs) - subs, err = g.GenerateFuturesDefaultSubscriptions(asset.CoinMarginedFutures) + subs, err = e.GenerateFuturesDefaultSubscriptions(asset.CoinMarginedFutures) require.NoError(t, err) require.NotEmpty(t, subs) - require.NoError(t, g.CurrencyPairs.SetAssetEnabled(asset.USDTMarginedFutures, false), "SetAssetEnabled must not error") - subs, err = g.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) + require.NoError(t, e.CurrencyPairs.SetAssetEnabled(asset.USDTMarginedFutures, false), "SetAssetEnabled must not error") + subs, err = e.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) require.NoError(t, err, "Disabled asset must not error") require.Empty(t, subs, "Disabled asset must return no pairs") } func TestGenerateOptionsDefaultSubscriptions(t *testing.T) { t.Parallel() - if _, err := g.GenerateOptionsDefaultSubscriptions(); err != nil { + if _, err := e.GenerateOptionsDefaultSubscriptions(); err != nil { t.Error(err) } } func TestCreateAPIKeysOfSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if _, err := g.CreateAPIKeysOfSubAccount(t.Context(), CreateAPIKeySubAccountParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if _, err := e.CreateAPIKeysOfSubAccount(t.Context(), CreateAPIKeySubAccountParams{ SubAccountUserID: 12345, Body: &SubAccountKey{ APIKeyName: "12312mnfsndfsfjsdklfjsdlkfj", @@ -2399,8 +2399,8 @@ func TestCreateAPIKeysOfSubAccount(t *testing.T) { func TestListAllAPIKeyOfSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetAllAPIKeyOfSubAccount(t.Context(), 1234) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAllAPIKeyOfSubAccount(t.Context(), 1234) if err != nil { t.Error(err) } @@ -2408,8 +2408,8 @@ func TestListAllAPIKeyOfSubAccount(t *testing.T) { func TestUpdateAPIKeyOfSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) - if err := g.UpdateAPIKeyOfSubAccount(t.Context(), apiKey, CreateAPIKeySubAccountParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + if err := e.UpdateAPIKeyOfSubAccount(t.Context(), apiKey, CreateAPIKeySubAccountParams{ SubAccountUserID: 12345, Body: &SubAccountKey{ APIKeyName: "12312mnfsndfsfjsdklfjsdlkfj", @@ -2447,8 +2447,8 @@ func TestUpdateAPIKeyOfSubAccount(t *testing.T) { func TestGetAPIKeyOfSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - _, err := g.GetAPIKeyOfSubAccount(t.Context(), 1234, "target_api_key") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAPIKeyOfSubAccount(t.Context(), 1234, "target_api_key") if err != nil { t.Error(err) } @@ -2456,16 +2456,16 @@ func TestGetAPIKeyOfSubAccount(t *testing.T) { func TestLockSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if err := g.LockSubAccount(t.Context(), 1234); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if err := e.LockSubAccount(t.Context(), 1234); err != nil { t.Error(err) } } func TestUnlockSubAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - if err := g.UnlockSubAccount(t.Context(), 1234); err != nil { + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + if err := e.UnlockSubAccount(t.Context(), 1234); err != nil { t.Error(err) } } @@ -2561,26 +2561,26 @@ func TestParseTimeUnmarshal(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, g) + testexch.UpdatePairsOnce(t, e) - err := g.UpdateOrderExecutionLimits(t.Context(), 1336) + err := e.UpdateOrderExecutionLimits(t.Context(), 1336) require.ErrorIs(t, err, asset.ErrNotSupported) - err = g.UpdateOrderExecutionLimits(t.Context(), asset.Options) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Options) require.ErrorIs(t, err, common.ErrNotYetImplemented) - err = g.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) if err != nil { t.Fatal(err) } - avail, err := g.GetAvailablePairs(asset.Spot) + avail, err := e.GetAvailablePairs(asset.Spot) if err != nil { t.Fatal(err) } for i := range avail { - mm, err := g.GetOrderExecutionLimits(asset.Spot, avail[i]) + mm, err := e.GetOrderExecutionLimits(asset.Spot, avail[i]) if err != nil { t.Fatal(err) } @@ -2618,20 +2618,20 @@ func TestForceFileStandard(t *testing.T) { func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := g.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = g.GetFuturesContractDetails(t.Context(), asset.PerpetualContract) + _, err = e.GetFuturesContractDetails(t.Context(), asset.PerpetualContract) require.ErrorIs(t, err, asset.ErrNotSupported) - exp, err := g.GetAllDeliveryContracts(t.Context(), currency.USDT) + exp, err := e.GetAllDeliveryContracts(t.Context(), currency.USDT) require.NoError(t, err, "GetAllDeliveryContracts must not error") - c, err := g.GetFuturesContractDetails(t.Context(), asset.DeliveryFutures) + c, err := e.GetFuturesContractDetails(t.Context(), asset.DeliveryFutures) require.NoError(t, err, "GetFuturesContractDetails must not error for DeliveryFutures") assert.Equal(t, len(exp), len(c), "GetFuturesContractDetails should return same number of Delivery contracts as exist") for _, a := range []asset.Item{asset.CoinMarginedFutures, asset.USDTMarginedFutures} { - c, err = g.GetFuturesContractDetails(t.Context(), a) + c, err = e.GetFuturesContractDetails(t.Context(), a) require.NoErrorf(t, err, "GetFuturesContractDetails must not error for %s", a) assert.NotEmptyf(t, c, "GetFuturesContractDetails should return some contracts for %s", a) } @@ -2639,46 +2639,46 @@ func TestGetFuturesContractDetails(t *testing.T) { func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := g.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSDT(), IncludePredictedRate: true, }) assert.NoError(t, err) - _, err = g.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.CoinMarginedFutures, Pair: currency.NewBTCUSD(), }) assert.NoError(t, err) - _, err = g.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{Asset: asset.CoinMarginedFutures}) + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{Asset: asset.CoinMarginedFutures}) assert.NoError(t, err) - _, err = g.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{Asset: asset.USDTMarginedFutures}) + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{Asset: asset.USDTMarginedFutures}) assert.NoError(t, err) } func TestGetHistoricalFundingRates(t *testing.T) { t.Parallel() - _, err := g.GetHistoricalFundingRates(t.Context(), nil) + _, err := e.GetHistoricalFundingRates(t.Context(), nil) assert.ErrorIs(t, err, common.ErrNilPointer) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{}) + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{}) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{Asset: asset.CoinMarginedFutures}) + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{Asset: asset.CoinMarginedFutures}) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{Asset: asset.Futures}) + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{Asset: asset.Futures}) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), }) assert.ErrorIs(t, err, fundingrate.ErrPaymentCurrencyCannotBeEmpty) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), PaymentCurrency: currency.USDT, @@ -2686,7 +2686,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { }) assert.ErrorIs(t, err, common.ErrNotYetImplemented) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), PaymentCurrency: currency.USDT, @@ -2694,7 +2694,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { }) assert.ErrorIs(t, err, common.ErrNotYetImplemented) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), PaymentCurrency: currency.USDT, @@ -2703,7 +2703,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { }) assert.ErrorIs(t, err, common.ErrStartAfterEnd) - _, err = g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + _, err = e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), PaymentCurrency: currency.USDT, @@ -2712,7 +2712,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { }) assert.ErrorIs(t, err, fundingrate.ErrFundingRateOutsideLimits) - history, err := g.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ + history, err := e.GetHistoricalFundingRates(t.Context(), &fundingrate.HistoricalRatesRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewPair(currency.ENJ, currency.USDT), PaymentCurrency: currency.USDT, @@ -2723,7 +2723,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { func TestGetOpenInterest(t *testing.T) { t.Parallel() - _, err := g.GetOpenInterest(t.Context(), key.PairAsset{ + _, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.NewCode("GOLDFISH").Item, Quote: currency.USDT.Item, Asset: asset.USDTMarginedFutures, @@ -2733,7 +2733,7 @@ func TestGetOpenInterest(t *testing.T) { var resp []futures.OpenInterest for _, a := range []asset.Item{asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.DeliveryFutures} { p := getPair(t, a) - resp, err = g.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, @@ -2742,7 +2742,7 @@ func TestGetOpenInterest(t *testing.T) { assert.Lenf(t, resp, 1, "GetOpenInterest should return 1 item for %s asset", a) } - resp, err = g.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) assert.NoError(t, err, "GetOpenInterest should not error") assert.NotEmpty(t, resp, "GetOpenInterest should return some items") } @@ -2800,7 +2800,7 @@ func TestProcessFuturesOrdersPushData(t *testing.T) { for _, tc := range testCases { t.Run("", func(t *testing.T) { t.Parallel() - processed, err := g.processFuturesOrdersPushData([]byte(tc.incoming), asset.CoinMarginedFutures) + processed, err := e.processFuturesOrdersPushData([]byte(tc.incoming), asset.CoinMarginedFutures) require.NoError(t, err) require.NotNil(t, processed) for i := range processed { @@ -2812,12 +2812,12 @@ func TestProcessFuturesOrdersPushData(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, g) - for _, a := range g.GetAssetTypes(false) { - pairs, err := g.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := g.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) if a == asset.Options { require.ErrorIs(t, err, asset.ErrNotSupported) } else { @@ -2829,9 +2829,9 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGetUnifiedAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) // Requires unified account to be enabled for this to function. - payload, err := g.GetUnifiedAccount(t.Context(), currency.EMPTYCODE) + payload, err := e.GetUnifiedAccount(t.Context(), currency.EMPTYCODE) require.NoError(t, err) require.NotEmpty(t, payload) } @@ -2868,7 +2868,7 @@ func TestGetSettlementCurrency(t *testing.T) { func TestGenerateWebsocketMessageID(t *testing.T) { t.Parallel() - require.NotEmpty(t, g.GenerateWebsocketMessageID(false)) + require.NotEmpty(t, e.GenerateWebsocketMessageID(false)) } type DummyConnection struct{ websocket.Connection } @@ -2883,12 +2883,12 @@ func TestHandleSubscriptions(t *testing.T) { subs := subscription.List{{Channel: subscription.OrderbookChannel}} - err := g.handleSubscription(t.Context(), &DummyConnection{}, subscribeEvent, subs, func(context.Context, websocket.Connection, string, subscription.List) ([]WsInput, error) { + err := e.handleSubscription(t.Context(), &DummyConnection{}, subscribeEvent, subs, func(context.Context, websocket.Connection, string, subscription.List) ([]WsInput, error) { return []WsInput{{}}, nil }) require.NoError(t, err) - err = g.handleSubscription(t.Context(), &DummyConnection{}, unsubscribeEvent, subs, func(context.Context, websocket.Connection, string, subscription.List) ([]WsInput, error) { + err = e.handleSubscription(t.Context(), &DummyConnection{}, unsubscribeEvent, subs, func(context.Context, websocket.Connection, string, subscription.List) ([]WsInput, error) { return []WsInput{{}}, nil }) require.NoError(t, err) @@ -2925,10 +2925,10 @@ func TestDeriveSpotWebsocketOrderResponse(t *testing.T) { var resp *WebsocketOrderResponse require.NoError(t, json.Unmarshal([]byte(`{"left":"0","update_time":"1735720637","amount":"0.0001","create_time":"1735720637","price":"0","finish_as":"filled","time_in_force":"ioc","currency_pair":"BTC_USDT","type":"market","account":"spot","side":"sell","amend_text":"-","text":"t-1735720637181634009","status":"closed","iceberg":"0","avg_deal_price":"93503.3","filled_total":"9.35033","id":"766075454481","fill_price":"9.35033","update_time_ms":1735720637188,"create_time_ms":1735720637188}`), &resp), "unmarshal must not error") - got, err := g.deriveSpotWebsocketOrderResponse(resp) + got, err := e.deriveSpotWebsocketOrderResponse(resp) require.NoError(t, err) assert.Equal(t, &order.SubmitResponse{ - Exchange: g.Name, + Exchange: e.Name, OrderID: "766075454481", AssetType: asset.Spot, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -2971,7 +2971,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { }, expected: []*order.SubmitResponse{ { - Exchange: g.Name, + Exchange: e.Name, OrderID: "766075454481", AssetType: asset.Spot, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -2988,7 +2988,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { Purchased: 9.35033, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "766075454188", AssetType: asset.Spot, Pair: currency.NewPair(currency.HNS, currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3006,7 +3006,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { Purchased: 816.3, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "766488882062", AssetType: asset.Spot, Pair: currency.NewPair(currency.NewCode("REX"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3024,7 +3024,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { Purchased: 200, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "766504537761", AssetType: asset.Spot, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3040,7 +3040,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { TimeInForce: order.PostOnly, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "766536556747", AssetType: asset.Spot, Pair: currency.NewPair(currency.NewCode("GT"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3069,7 +3069,7 @@ func TestDeriveSpotWebsocketOrderResponses(t *testing.T) { var resp []*WebsocketOrderResponse require.NoError(t, json.Unmarshal(orders, &resp), "unmarshal must not error") - got, err := g.deriveSpotWebsocketOrderResponses(resp) + got, err := e.deriveSpotWebsocketOrderResponses(resp) require.ErrorIs(t, err, tc.error) require.Len(t, got, len(tc.expected)) @@ -3086,10 +3086,10 @@ func TestDeriveFuturesWebsocketOrderResponse(t *testing.T) { var resp *WebsocketFuturesOrderResponse require.NoError(t, json.Unmarshal([]byte(`{"text":"t-1337","price":"0","biz_info":"-","tif":"ioc","amend_text":"-","status":"finished","contract":"CWIF_USDT","stp_act":"-","finish_as":"filled","fill_price":"0.0000002625","id":596729318437,"create_time":1735787107.449,"size":2,"finish_time":1735787107.45,"update_time":1735787107.45,"left":0,"user":12870774,"is_reduce_only":true}`), &resp), "unmarshal must not error") - got, err := g.deriveFuturesWebsocketOrderResponse(resp) + got, err := e.deriveFuturesWebsocketOrderResponse(resp) require.NoError(t, err) assert.Equal(t, &order.SubmitResponse{ - Exchange: g.Name, + Exchange: e.Name, OrderID: "596729318437", AssetType: asset.Futures, Pair: currency.NewPair(currency.NewCode("CWIF"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3132,7 +3132,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { }, expected: []*order.SubmitResponse{ { - Exchange: g.Name, + Exchange: e.Name, OrderID: "596729318437", AssetType: asset.Futures, Pair: currency.NewPair(currency.NewCode("CWIF"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3148,7 +3148,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { ReduceOnly: true, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "596662040388", AssetType: asset.Futures, Pair: currency.NewPair(currency.NewCode("REX"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3163,7 +3163,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { TimeInForce: order.ImmediateOrCancel, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "596746193678", AssetType: asset.Futures, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3178,7 +3178,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { TimeInForce: order.GoodTillCancel, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "596748780649", AssetType: asset.Futures, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3193,7 +3193,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { TimeInForce: order.GoodTillCancel, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "36028797827161124", AssetType: asset.Futures, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3207,7 +3207,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { TimeInForce: order.ImmediateOrCancel, }, { - Exchange: g.Name, + Exchange: e.Name, OrderID: "36028797827225781", AssetType: asset.Futures, Pair: currency.NewBTCUSDT().Format(currency.PairFormat{Uppercase: true, Delimiter: "_"}), @@ -3235,7 +3235,7 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { var resp []*WebsocketFuturesOrderResponse require.NoError(t, json.Unmarshal(orders, &resp), "unmarshal must not error") - got, err := g.deriveFuturesWebsocketOrderResponses(resp) + got, err := e.deriveFuturesWebsocketOrderResponses(resp) require.ErrorIs(t, err, tc.error) require.Len(t, got, len(tc.expected)) @@ -3248,27 +3248,27 @@ func TestDeriveFuturesWebsocketOrderResponses(t *testing.T) { func TestConvertSmallBalances(t *testing.T) { t.Parallel() - err := g.ConvertSmallBalances(t.Context(), currency.EMPTYCODE) + err := e.ConvertSmallBalances(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - err = g.ConvertSmallBalances(t.Context(), currency.F16) + err = e.ConvertSmallBalances(t.Context(), currency.F16) require.NoError(t, err) } func TestGetAccountDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - got, err := g.GetAccountDetails(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + got, err := e.GetAccountDetails(t.Context()) require.NoError(t, err) require.NotEmpty(t, got) } func TestGetUserTransactionRateLimitInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) - got, err := g.GetUserTransactionRateLimitInfo(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + got, err := e.GetUserTransactionRateLimitInfo(t.Context()) require.NoError(t, err) require.NotEmpty(t, got) } @@ -3300,8 +3300,8 @@ func getPairs(tb testing.TB, a asset.Item) currency.Pairs { return p } - testexch.UpdatePairsOnce(tb, g) - enabledPairs, err := g.GetEnabledPairs(a) + testexch.UpdatePairsOnce(tb, e) + enabledPairs, err := e.GetEnabledPairs(a) assert.NoErrorf(tb, err, "%s GetEnabledPairs should not error", a) if !assert.NotEmptyf(tb, enabledPairs, "%s GetEnabledPairs should not be empty", a) { tb.Fatalf("No pair available for asset %s", a) @@ -3384,22 +3384,22 @@ func TestIsSingleOrderbookChannel(t *testing.T) { func TestValidateSubscriptions(t *testing.T) { t.Parallel() - require.NoError(t, g.ValidateSubscriptions(nil)) - require.NoError(t, g.ValidateSubscriptions([]*subscription.Subscription{{Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSDT()}}})) - require.NoError(t, g.ValidateSubscriptions([]*subscription.Subscription{ + require.NoError(t, e.ValidateSubscriptions(nil)) + require.NoError(t, e.ValidateSubscriptions([]*subscription.Subscription{{Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSDT()}}})) + require.NoError(t, e.ValidateSubscriptions([]*subscription.Subscription{ {Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookUpdateChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, })) - require.NoError(t, g.ValidateSubscriptions([]*subscription.Subscription{ + require.NoError(t, e.ValidateSubscriptions([]*subscription.Subscription{ {Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookUpdateChannel, Pairs: []currency.Pair{currency.NewBTCUSD(), currency.NewBTCUSDT()}}, })) - require.NoError(t, g.ValidateSubscriptions([]*subscription.Subscription{ + require.NoError(t, e.ValidateSubscriptions([]*subscription.Subscription{ {Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookUpdateChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookUpdateChannel, Pairs: []currency.Pair{currency.NewBTCUSDT()}}, })) - require.ErrorIs(t, g.ValidateSubscriptions([]*subscription.Subscription{ + require.ErrorIs(t, e.ValidateSubscriptions([]*subscription.Subscription{ {Channel: spotTickerChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookUpdateChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, {Channel: spotOrderbookChannel, Pairs: []currency.Pair{currency.NewBTCUSD()}}, diff --git a/exchanges/gateio/gateio_websocket.go b/exchanges/gateio/gateio_websocket.go index 2470dbaf63c..e32fb76dda3 100644 --- a/exchanges/gateio/gateio_websocket.go +++ b/exchanges/gateio/gateio_websocket.go @@ -80,8 +80,8 @@ var subscriptionNames = map[string]string{ var standardMarginAssetTypes = []asset.Item{asset.Spot, asset.Margin, asset.CrossMargin} // WsConnectSpot initiates a websocket connection -func (g *Gateio) WsConnectSpot(ctx context.Context, conn websocket.Connection) error { - err := g.CurrencyPairs.IsAssetEnabled(asset.Spot) +func (e *Exchange) WsConnectSpot(ctx context.Context, conn websocket.Connection) error { + err := e.CurrencyPairs.IsAssetEnabled(asset.Spot) if err != nil { return err } @@ -103,7 +103,7 @@ func (g *Gateio) WsConnectSpot(ctx context.Context, conn websocket.Connection) e } // websocketLogin authenticates the websocket connection -func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection, channel string) error { +func (e *Exchange) websocketLogin(ctx context.Context, conn websocket.Connection, channel string) error { if conn == nil { return fmt.Errorf("%w: %T", common.ErrNilPointer, conn) } @@ -112,7 +112,7 @@ func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection, return errChannelEmpty } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -156,7 +156,7 @@ func (g *Gateio) websocketLogin(ctx context.Context, conn websocket.Connection, return fmt.Errorf("%s: %s", wsErr.Errors.Label, wsErr.Errors.Message) } -func (g *Gateio) generateWsSignature(secret, event, channel string, t int64) (string, error) { +func (e *Exchange) generateWsSignature(secret, event, channel string, t int64) (string, error) { msg := "channel=" + channel + "&event=" + event + "&time=" + strconv.FormatInt(t, 10) mac := hmac.New(sha512.New, []byte(secret)) if _, err := mac.Write([]byte(msg)); err != nil { @@ -166,51 +166,51 @@ func (g *Gateio) generateWsSignature(secret, event, channel string, t int64) (st } // WsHandleSpotData handles spot data -func (g *Gateio) WsHandleSpotData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) WsHandleSpotData(ctx context.Context, respRaw []byte) error { push, err := parseWSHeader(respRaw) if err != nil { return err } if push.RequestID != "" { - return g.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw) + return e.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw) } if push.Event == subscribeEvent || push.Event == unsubscribeEvent { - return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw) + return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw) } switch push.Channel { // TODO: Convert function params below to only use push.Result case spotTickerChannel: - return g.processTicker(push.Result, push.Time) + return e.processTicker(push.Result, push.Time) case spotTradesChannel: - return g.processTrades(push.Result) + return e.processTrades(push.Result) case spotCandlesticksChannel: - return g.processCandlestick(push.Result) + return e.processCandlestick(push.Result) case spotOrderbookTickerChannel: - return g.processOrderbookTicker(push.Result, push.Time) + return e.processOrderbookTicker(push.Result, push.Time) case spotOrderbookUpdateChannel: - return g.processOrderbookUpdate(ctx, push.Result, push.Time) + return e.processOrderbookUpdate(ctx, push.Result, push.Time) case spotOrderbookChannel: - return g.processOrderbookSnapshot(push.Result, push.Time) + return e.processOrderbookSnapshot(push.Result, push.Time) case spotOrdersChannel: - return g.processSpotOrders(respRaw) + return e.processSpotOrders(respRaw) case spotUserTradesChannel: - return g.processUserPersonalTrades(respRaw) + return e.processUserPersonalTrades(respRaw) case spotBalancesChannel: - return g.processSpotBalances(ctx, respRaw) + return e.processSpotBalances(ctx, respRaw) case marginBalancesChannel: - return g.processMarginBalances(ctx, respRaw) + return e.processMarginBalances(ctx, respRaw) case spotFundingBalanceChannel: - return g.processFundingBalances(respRaw) + return e.processFundingBalances(respRaw) case crossMarginBalanceChannel: - return g.processCrossMarginBalance(ctx, respRaw) + return e.processCrossMarginBalance(ctx, respRaw) case crossMarginLoanChannel: - return g.processCrossMarginLoans(respRaw) + return e.processCrossMarginLoans(respRaw) case spotPongChannel: default: - g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: g.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return errors.New(websocket.UnhandledMessage) } @@ -256,16 +256,16 @@ func parseWSHeader(msg []byte) (r *WSResponse, errs error) { return r, errs } -func (g *Gateio) processTicker(incoming []byte, pushTime time.Time) error { +func (e *Exchange) processTicker(incoming []byte, pushTime time.Time) error { var data WsTicker if err := json.Unmarshal(incoming, &data); err != nil { return err } out := make([]ticker.Price, 0, len(standardMarginAssetTypes)) for _, a := range standardMarginAssetTypes { - if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { + if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { out = append(out, ticker.Price{ - ExchangeName: g.Name, + ExchangeName: e.Name, Volume: data.BaseVolume.Float64(), QuoteVolume: data.QuoteVolume.Float64(), High: data.High24H.Float64(), @@ -279,13 +279,13 @@ func (g *Gateio) processTicker(incoming []byte, pushTime time.Time) error { }) } } - g.Websocket.DataHandler <- out + e.Websocket.DataHandler <- out return nil } -func (g *Gateio) processTrades(incoming []byte) error { - saveTradeData := g.IsSaveTradeDataEnabled() - if !saveTradeData && !g.IsTradeFeedEnabled() { +func (e *Exchange) processTrades(incoming []byte) error { + saveTradeData := e.IsSaveTradeDataEnabled() + if !saveTradeData && !e.IsTradeFeedEnabled() { return nil } @@ -300,12 +300,12 @@ func (g *Gateio) processTrades(incoming []byte) error { } for _, a := range standardMarginAssetTypes { - if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { - if err := g.Websocket.Trade.Update(saveTradeData, trade.Data{ + if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { + if err := e.Websocket.Trade.Update(saveTradeData, trade.Data{ Timestamp: data.CreateTime.Time(), CurrencyPair: data.CurrencyPair, AssetType: a, - Exchange: g.Name, + Exchange: e.Name, Price: data.Price.Float64(), Amount: data.Amount.Float64(), Side: side, @@ -319,7 +319,7 @@ func (g *Gateio) processTrades(incoming []byte) error { return nil } -func (g *Gateio) processCandlestick(incoming []byte) error { +func (e *Exchange) processCandlestick(incoming []byte) error { var data WsCandlesticks if err := json.Unmarshal(incoming, &data); err != nil { return err @@ -335,11 +335,11 @@ func (g *Gateio) processCandlestick(incoming []byte) error { out := make([]websocket.KlineData, 0, len(standardMarginAssetTypes)) for _, a := range standardMarginAssetTypes { - if enabled, _ := g.CurrencyPairs.IsPairEnabled(currencyPair, a); enabled { + if enabled, _ := e.CurrencyPairs.IsPairEnabled(currencyPair, a); enabled { out = append(out, websocket.KlineData{ Pair: currencyPair, AssetType: a, - Exchange: g.Name, + Exchange: e.Name, StartTime: data.Timestamp.Time(), Interval: icp[0], OpenPrice: data.OpenPrice.Float64(), @@ -350,17 +350,17 @@ func (g *Gateio) processCandlestick(incoming []byte) error { }) } } - g.Websocket.DataHandler <- out + e.Websocket.DataHandler <- out return nil } -func (g *Gateio) processOrderbookTicker(incoming []byte, lastPushed time.Time) error { +func (e *Exchange) processOrderbookTicker(incoming []byte, lastPushed time.Time) error { var data WsOrderbookTickerData if err := json.Unmarshal(incoming, &data); err != nil { return err } - return g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: g.Name, + return e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, Pair: data.Pair, Asset: asset.Spot, LastUpdated: data.UpdateTime.Time(), @@ -370,7 +370,7 @@ func (g *Gateio) processOrderbookTicker(incoming []byte, lastPushed time.Time) e }) } -func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, lastPushed time.Time) error { +func (e *Exchange) processOrderbookUpdate(ctx context.Context, incoming []byte, lastPushed time.Time) error { var data WsOrderbookUpdate if err := json.Unmarshal(incoming, &data); err != nil { return err @@ -385,7 +385,7 @@ func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, la bids[x].Price = data.Bids[x][0].Float64() bids[x].Amount = data.Bids[x][1].Float64() } - return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdateID, &orderbook.Update{ + return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdateID, &orderbook.Update{ UpdateID: data.LastUpdateID, UpdateTime: data.UpdateTime.Time(), LastPushed: lastPushed, @@ -397,7 +397,7 @@ func (g *Gateio) processOrderbookUpdate(ctx context.Context, incoming []byte, la }) } -func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) error { +func (e *Exchange) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) error { var data WsOrderbookSnapshot if err := json.Unmarshal(incoming, &data); err != nil { return err @@ -415,9 +415,9 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) } for _, a := range standardMarginAssetTypes { - if enabled, _ := g.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { - if err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: g.Name, + if enabled, _ := e.CurrencyPairs.IsPairEnabled(data.CurrencyPair, a); enabled { + if err := e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, Pair: data.CurrencyPair, Asset: a, LastUpdated: data.UpdateTime.Time(), @@ -432,7 +432,7 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time) return nil } -func (g *Gateio) processSpotOrders(data []byte) error { +func (e *Exchange) processSpotOrders(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -459,7 +459,7 @@ func (g *Gateio) processSpotOrders(data []byte) error { } details[x] = order.Detail{ Amount: resp.Result[x].Amount.Float64(), - Exchange: g.Name, + Exchange: e.Name, OrderID: resp.Result[x].ID, Side: side, Type: orderType, @@ -472,12 +472,12 @@ func (g *Gateio) processSpotOrders(data []byte) error { LastUpdated: resp.Result[x].UpdateTime.Time(), } } - g.Websocket.DataHandler <- details + e.Websocket.DataHandler <- details return nil } -func (g *Gateio) processUserPersonalTrades(data []byte) error { - if !g.IsFillsFeedEnabled() { +func (e *Exchange) processUserPersonalTrades(data []byte) error { + if !e.IsFillsFeedEnabled() { return nil } @@ -499,7 +499,7 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error { } fills[x] = fill.Data{ Timestamp: resp.Result[x].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, CurrencyPair: resp.Result[x].CurrencyPair, Side: side, OrderID: resp.Result[x].OrderID, @@ -508,10 +508,10 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error { Amount: resp.Result[x].Amount.Float64(), } } - return g.Websocket.Fills.Update(fills...) + return e.Websocket.Fills.Update(fills...) } -func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error { +func (e *Exchange) processSpotBalances(ctx context.Context, data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -522,7 +522,7 @@ func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error { if err != nil { return err } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -540,11 +540,11 @@ func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error { }, } } - g.Websocket.DataHandler <- changes - return account.ProcessChange(g.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } -func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error { +func (e *Exchange) processMarginBalances(ctx context.Context, data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -555,7 +555,7 @@ func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error { if err != nil { return err } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -572,11 +572,11 @@ func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error { }, } } - g.Websocket.DataHandler <- changes - return account.ProcessChange(g.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } -func (g *Gateio) processFundingBalances(data []byte) error { +func (e *Exchange) processFundingBalances(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -587,11 +587,11 @@ func (g *Gateio) processFundingBalances(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- resp + e.Websocket.DataHandler <- resp return nil } -func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) error { +func (e *Exchange) processCrossMarginBalance(ctx context.Context, data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -602,7 +602,7 @@ func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) err if err != nil { return err } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -619,11 +619,11 @@ func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) err }, } } - g.Websocket.DataHandler <- changes - return account.ProcessChange(g.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } -func (g *Gateio) processCrossMarginLoans(data []byte) error { +func (e *Exchange) processCrossMarginLoans(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -634,17 +634,17 @@ func (g *Gateio) processCrossMarginLoans(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- resp + e.Websocket.DataHandler <- resp return nil } // generateSubscriptionsSpot returns configured subscriptions -func (g *Gateio) generateSubscriptionsSpot() (subscription.List, error) { - return g.Features.Subscriptions.ExpandTemplates(g) +func (e *Exchange) generateSubscriptionsSpot() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (g *Gateio) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl"). Funcs(sprig.FuncMap()). Funcs(template.FuncMap{ @@ -657,16 +657,16 @@ func (g *Gateio) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat } // manageSubs sends a websocket message to subscribe or unsubscribe from a list of channel -func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Connection, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, event string, conn websocket.Connection, subs subscription.List) error { var errs error - subs, errs = subs.ExpandTemplates(g) + subs, errs = subs.ExpandTemplates(e) if errs != nil { return errs } for _, s := range subs { if err := func() error { - msg, err := g.manageSubReq(ctx, event, conn, s) + msg, err := e.manageSubReq(ctx, event, conn, s) if err != nil { return err } @@ -682,9 +682,9 @@ func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Co return fmt.Errorf("(%d) %s", resp.Error.Code, resp.Error.Message) } if event == "unsubscribe" { - return g.Websocket.RemoveSubscriptions(conn, s) + return e.Websocket.RemoveSubscriptions(conn, s) } - return g.Websocket.AddSuccessfulSubscriptions(conn, s) + return e.Websocket.AddSuccessfulSubscriptions(conn, s) }(); err != nil { errs = common.AppendError(errs, fmt.Errorf("%s %s %s: %w", s.Channel, s.Asset, s.Pairs, err)) } @@ -693,7 +693,7 @@ func (g *Gateio) manageSubs(ctx context.Context, event string, conn websocket.Co } // manageSubReq constructs the subscription management message for a subscription -func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket.Connection, s *subscription.Subscription) (*WsInput, error) { +func (e *Exchange) manageSubReq(ctx context.Context, event string, conn websocket.Connection, s *subscription.Subscription) (*WsInput, error) { req := &WsInput{ ID: conn.GenerateMessageID(false), Event: event, @@ -702,11 +702,11 @@ func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket. Payload: strings.Split(s.QualifiedChannel, ","), } if s.Authenticated { - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return nil, err } - sig, err := g.generateWsSignature(creds.Secret, event, req.Channel, req.Time) + sig, err := e.generateWsSignature(creds.Secret, event, req.Channel, req.Time) if err != nil { return nil, err } @@ -720,18 +720,18 @@ func (g *Gateio) manageSubReq(ctx context.Context, event string, conn websocket. } // Subscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) Subscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error { - return g.manageSubs(ctx, subscribeEvent, conn, subs) +func (e *Exchange) Subscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error { + return e.manageSubs(ctx, subscribeEvent, conn, subs) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) Unsubscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error { - return g.manageSubs(ctx, unsubscribeEvent, conn, subs) +func (e *Exchange) Unsubscribe(ctx context.Context, conn websocket.Connection, subs subscription.List) error { + return e.manageSubs(ctx, unsubscribeEvent, conn, subs) } // GenerateWebsocketMessageID generates a message ID for the individual connection -func (g *Gateio) GenerateWebsocketMessageID(bool) int64 { - return g.Counter.IncrementAndGet() +func (e *Exchange) GenerateWebsocketMessageID(bool) int64 { + return e.Counter.IncrementAndGet() } // channelName converts global channel names to gateio specific channel names @@ -754,7 +754,7 @@ func singleSymbolChannel(name string) bool { // ValidateSubscriptions implements the subscription.ListValidator interface. // It ensures that, for each orderbook pair asset, only one type of subscription (e.g., best bid/ask, orderbook update, or orderbook snapshot) // is active at a time. Multiple concurrent subscriptions for the same asset are disallowed to prevent orderbook data corruption. -func (g *Gateio) ValidateSubscriptions(l subscription.List) error { +func (e *Exchange) ValidateSubscriptions(l subscription.List) error { orderbookGuard := map[key.PairAsset]string{} for _, s := range l { n := channelName(s) @@ -920,7 +920,7 @@ const subTplText = ` type GeneratePayload func(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) // handleSubscription sends a websocket message to receive data from the channel -func (g *Gateio) handleSubscription(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List, generatePayload GeneratePayload) error { +func (e *Exchange) handleSubscription(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List, generatePayload GeneratePayload) error { payloads, err := generatePayload(ctx, conn, event, channelsToSubscribe) if err != nil { return err @@ -941,9 +941,9 @@ func (g *Gateio) handleSubscription(ctx context.Context, conn websocket.Connecti continue } if event == subscribeEvent { - errs = common.AppendError(errs, g.Websocket.AddSuccessfulSubscriptions(conn, channelsToSubscribe[k])) + errs = common.AppendError(errs, e.Websocket.AddSuccessfulSubscriptions(conn, channelsToSubscribe[k])) } else { - errs = common.AppendError(errs, g.Websocket.RemoveSubscriptions(conn, channelsToSubscribe[k])) + errs = common.AppendError(errs, e.Websocket.RemoveSubscriptions(conn, channelsToSubscribe[k])) } } } @@ -955,13 +955,13 @@ type resultHolder struct { } // SendWebsocketRequest sends a websocket request to the exchange -func (g *Gateio) SendWebsocketRequest(ctx context.Context, epl request.EndpointLimit, channel string, connSignature, params, result any, expectedResponses int) error { +func (e *Exchange) SendWebsocketRequest(ctx context.Context, epl request.EndpointLimit, channel string, connSignature, params, result any, expectedResponses int) error { paramPayload, err := json.Marshal(params) if err != nil { return err } - conn, err := g.Websocket.GetConnection(connSignature) + conn, err := e.Websocket.GetConnection(connSignature) if err != nil { return err } diff --git a/exchanges/gateio/gateio_websocket_delivery_futures.go b/exchanges/gateio/gateio_websocket_delivery_futures.go index 7227b3b070f..2c6851c91cf 100644 --- a/exchanges/gateio/gateio_websocket_delivery_futures.go +++ b/exchanges/gateio/gateio_websocket_delivery_futures.go @@ -37,8 +37,8 @@ var defaultDeliveryFuturesSubscriptions = []string{ } // WsDeliveryFuturesConnect initiates a websocket connection for delivery futures account -func (g *Gateio) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Connection) error { - if err := g.CurrencyPairs.IsAssetEnabled(asset.DeliveryFutures); err != nil { +func (e *Exchange) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Connection) error { + if err := e.CurrencyPairs.IsAssetEnabled(asset.DeliveryFutures); err != nil { return err } if err := conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { @@ -63,18 +63,18 @@ func (g *Gateio) WsDeliveryFuturesConnect(ctx context.Context, conn websocket.Co // GenerateDeliveryFuturesDefaultSubscriptions returns delivery futures default subscriptions params. // TODO: Update to use the new subscription template system -func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.List, error) { ctx := context.TODO() - _, err := g.GetCredentials(ctx) + _, err := e.GetCredentials(ctx) if err != nil { - g.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } channelsToSubscribe := defaultDeliveryFuturesSubscriptions - if g.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { channelsToSubscribe = append(channelsToSubscribe, futuresOrdersChannel, futuresUserTradesChannel, futuresBalancesChannel) } - pairs, err := g.GetEnabledPairs(asset.DeliveryFutures) + pairs, err := e.GetEnabledPairs(asset.DeliveryFutures) if err != nil { if errors.Is(err, asset.ErrNotEnabled) { return nil, nil // no enabled pairs, subscriptions require an associated pair. @@ -96,7 +96,7 @@ func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.Lis params["frequency"] = kline.HundredMilliseconds params["level"] = strconv.FormatUint(deliveryFuturesUpdateLimit, 10) } - fPair, err := g.FormatExchangeCurrency(pairs[j], asset.DeliveryFutures) + fPair, err := e.FormatExchangeCurrency(pairs[j], asset.DeliveryFutures) if err != nil { return nil, err } @@ -112,25 +112,25 @@ func (g *Gateio) GenerateDeliveryFuturesDefaultSubscriptions() (subscription.Lis } // DeliveryFuturesSubscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) DeliveryFuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateDeliveryFuturesPayload) +func (e *Exchange) DeliveryFuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateDeliveryFuturesPayload) } // DeliveryFuturesUnsubscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) DeliveryFuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateDeliveryFuturesPayload) +func (e *Exchange) DeliveryFuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateDeliveryFuturesPayload) } -func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { +func (e *Exchange) generateDeliveryFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { if len(channelsToSubscribe) == 0 { return nil, errors.New("cannot generate payload, no channels supplied") } var creds *account.Credentials var err error - if g.Websocket.CanUseAuthenticatedEndpoints() { - creds, err = g.GetCredentials(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + creds, err = e.GetCredentials(ctx) if err != nil { - g.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } outbound := make([]WsInput, 0, len(channelsToSubscribe)) @@ -142,7 +142,7 @@ func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websoc timestamp := time.Now() var params []string params = []string{channelsToSubscribe[i].Pairs[0].String()} - if g.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { switch channelsToSubscribe[i].Channel { case futuresOrdersChannel, futuresUserTradesChannel, futuresLiquidatesChannel, futuresAutoDeleveragesChannel, @@ -154,7 +154,7 @@ func (g *Gateio) generateDeliveryFuturesPayload(ctx context.Context, conn websoc params = append([]string{value}, params...) } var sigTemp string - sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) + sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) if err != nil { return nil, err } diff --git a/exchanges/gateio/gateio_websocket_futures.go b/exchanges/gateio/gateio_websocket_futures.go index 0249584b43a..f01a7cfb5bb 100644 --- a/exchanges/gateio/gateio_websocket_futures.go +++ b/exchanges/gateio/gateio_websocket_futures.go @@ -58,12 +58,12 @@ var defaultFuturesSubscriptions = []string{ } // WsFuturesConnect initiates a websocket connection for futures account -func (g *Gateio) WsFuturesConnect(ctx context.Context, conn websocket.Connection) error { +func (e *Exchange) WsFuturesConnect(ctx context.Context, conn websocket.Connection) error { a := asset.USDTMarginedFutures if conn.GetURL() == btcFuturesWebsocketURL { a = asset.CoinMarginedFutures } - if err := g.CurrencyPairs.IsAssetEnabled(a); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil { return err } if err := conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { @@ -88,13 +88,13 @@ func (g *Gateio) WsFuturesConnect(ctx context.Context, conn websocket.Connection // GenerateFuturesDefaultSubscriptions returns default subscriptions information. // TODO: Update to use the new subscription template system -func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription.List, error) { +func (e *Exchange) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription.List, error) { channelsToSubscribe := defaultFuturesSubscriptions - if g.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { channelsToSubscribe = append(channelsToSubscribe, futuresOrdersChannel, futuresUserTradesChannel, futuresBalancesChannel) } - pairs, err := g.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { if errors.Is(err, asset.ErrNotEnabled) { return nil, nil // no enabled pairs, subscriptions require an associated pair. @@ -117,7 +117,7 @@ func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription params["frequency"] = kline.TwentyMilliseconds params["level"] = strconv.FormatUint(futuresOrderbookUpdateLimit, 10) } - fPair, err := g.FormatExchangeCurrency(pairs[j], a) + fPair, err := e.FormatExchangeCurrency(pairs[j], a) if err != nil { return nil, err } @@ -133,84 +133,84 @@ func (g *Gateio) GenerateFuturesDefaultSubscriptions(a asset.Item) (subscription } // FuturesSubscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) FuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateFuturesPayload) +func (e *Exchange) FuturesSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateFuturesPayload) } // FuturesUnsubscribe sends a websocket message to stop receiving data from the channel -func (g *Gateio) FuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateFuturesPayload) +func (e *Exchange) FuturesUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateFuturesPayload) } // WsHandleFuturesData handles futures websocket data -func (g *Gateio) WsHandleFuturesData(ctx context.Context, respRaw []byte, a asset.Item) error { +func (e *Exchange) WsHandleFuturesData(ctx context.Context, respRaw []byte, a asset.Item) error { push, err := parseWSHeader(respRaw) if err != nil { return err } if push.RequestID != "" { - return g.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw) + return e.Websocket.Match.RequireMatchWithData(push.RequestID, respRaw) } if push.Event == subscribeEvent || push.Event == unsubscribeEvent { - return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw) + return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw) } switch push.Channel { case futuresTickersChannel: - return g.processFuturesTickers(respRaw, a) + return e.processFuturesTickers(respRaw, a) case futuresTradesChannel: - return g.processFuturesTrades(respRaw, a) + return e.processFuturesTrades(respRaw, a) case futuresOrderbookChannel: - return g.processFuturesOrderbookSnapshot(push.Event, push.Result, a, push.Time) + return e.processFuturesOrderbookSnapshot(push.Event, push.Result, a, push.Time) case futuresOrderbookTickerChannel: - return g.processFuturesOrderbookTicker(push.Result) + return e.processFuturesOrderbookTicker(push.Result) case futuresOrderbookUpdateChannel: - return g.processFuturesOrderbookUpdate(ctx, push.Result, a, push.Time) + return e.processFuturesOrderbookUpdate(ctx, push.Result, a, push.Time) case futuresCandlesticksChannel: - return g.processFuturesCandlesticks(respRaw, a) + return e.processFuturesCandlesticks(respRaw, a) case futuresOrdersChannel: - processed, err := g.processFuturesOrdersPushData(respRaw, a) + processed, err := e.processFuturesOrdersPushData(respRaw, a) if err != nil { return err } - g.Websocket.DataHandler <- processed + e.Websocket.DataHandler <- processed return nil case futuresUserTradesChannel: - return g.procesFuturesUserTrades(respRaw, a) + return e.procesFuturesUserTrades(respRaw, a) case futuresLiquidatesChannel: - return g.processFuturesLiquidatesNotification(respRaw) + return e.processFuturesLiquidatesNotification(respRaw) case futuresAutoDeleveragesChannel: - return g.processFuturesAutoDeleveragesNotification(respRaw) + return e.processFuturesAutoDeleveragesNotification(respRaw) case futuresAutoPositionCloseChannel: - return g.processPositionCloseData(respRaw) + return e.processPositionCloseData(respRaw) case futuresBalancesChannel: - return g.processBalancePushData(ctx, respRaw, a) + return e.processBalancePushData(ctx, respRaw, a) case futuresReduceRiskLimitsChannel: - return g.processFuturesReduceRiskLimitNotification(respRaw) + return e.processFuturesReduceRiskLimitNotification(respRaw) case futuresPositionsChannel: - return g.processFuturesPositionsNotification(respRaw) + return e.processFuturesPositionsNotification(respRaw) case futuresAutoOrdersChannel: - return g.processFuturesAutoOrderPushData(respRaw) + return e.processFuturesAutoOrderPushData(respRaw) default: - g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: g.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return errors.New(websocket.UnhandledMessage) } } -func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { +func (e *Exchange) generateFuturesPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { if len(channelsToSubscribe) == 0 { return nil, errors.New("cannot generate payload, no channels supplied") } var creds *account.Credentials var err error - if g.Websocket.CanUseAuthenticatedEndpoints() { - creds, err = g.GetCredentials(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + creds, err = e.GetCredentials(ctx) if err != nil { - g.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } @@ -223,7 +223,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn timestamp := time.Now() var params []string params = []string{channelsToSubscribe[i].Pairs[0].String()} - if g.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { switch channelsToSubscribe[i].Channel { case futuresOrdersChannel, futuresUserTradesChannel, futuresLiquidatesChannel, futuresAutoDeleveragesChannel, @@ -237,7 +237,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn params...) } var sigTemp string - sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) + sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) if err != nil { return nil, err } @@ -298,7 +298,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn return outbound, nil } -func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error { +func (e *Exchange) processFuturesTickers(data []byte, assetType asset.Item) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -312,7 +312,7 @@ func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error tickerPriceDatas := make([]ticker.Price, len(resp.Result)) for x := range resp.Result { tickerPriceDatas[x] = ticker.Price{ - ExchangeName: g.Name, + ExchangeName: e.Name, Volume: resp.Result[x].Volume24HBase.Float64(), QuoteVolume: resp.Result[x].Volume24HQuote.Float64(), High: resp.Result[x].High24H.Float64(), @@ -323,13 +323,13 @@ func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error LastUpdated: resp.Time.Time(), } } - g.Websocket.DataHandler <- tickerPriceDatas + e.Websocket.DataHandler <- tickerPriceDatas return nil } -func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error { - saveTradeData := g.IsSaveTradeDataEnabled() - if !saveTradeData && !g.IsTradeFeedEnabled() { +func (e *Exchange) processFuturesTrades(data []byte, assetType asset.Item) error { + saveTradeData := e.IsSaveTradeDataEnabled() + if !saveTradeData && !e.IsTradeFeedEnabled() { return nil } @@ -350,16 +350,16 @@ func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error { Timestamp: resp.Result[x].CreateTime.Time(), CurrencyPair: resp.Result[x].Contract, AssetType: assetType, - Exchange: g.Name, + Exchange: e.Name, Price: resp.Result[x].Price.Float64(), Amount: resp.Result[x].Size, TID: strconv.FormatInt(resp.Result[x].ID, 10), } } - return g.Websocket.Trade.Update(saveTradeData, trades...) + return e.Websocket.Trade.Update(saveTradeData, trades...) } -func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) error { +func (e *Exchange) processFuturesCandlesticks(data []byte, assetType asset.Item) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -383,7 +383,7 @@ func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) e klineDatas[x] = websocket.KlineData{ Pair: currencyPair, AssetType: assetType, - Exchange: g.Name, + Exchange: e.Name, StartTime: resp.Result[x].Timestamp.Time(), Interval: icp[0], OpenPrice: resp.Result[x].OpenPrice.Float64(), @@ -393,21 +393,21 @@ func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) e Volume: resp.Result[x].Volume, } } - g.Websocket.DataHandler <- klineDatas + e.Websocket.DataHandler <- klineDatas return nil } -func (g *Gateio) processFuturesOrderbookTicker(incoming []byte) error { +func (e *Exchange) processFuturesOrderbookTicker(incoming []byte) error { var data WsFuturesOrderbookTicker err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- data + e.Websocket.DataHandler <- data return nil } -func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error { +func (e *Exchange) processFuturesOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error { var data WsFuturesAndOptionsOrderbookUpdate if err := json.Unmarshal(incoming, &data); err != nil { return err @@ -423,7 +423,7 @@ func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []b bids[x].Amount = data.Bids[x].Size } - return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdatedID, &orderbook.Update{ + return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdatedID, &orderbook.Update{ UpdateID: data.LastUpdatedID, UpdateTime: data.Timestamp.Time(), LastPushed: pushTime, @@ -435,7 +435,7 @@ func (g *Gateio) processFuturesOrderbookUpdate(ctx context.Context, incoming []b }) } -func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, assetType asset.Item, lastPushed time.Time) error { +func (e *Exchange) processFuturesOrderbookSnapshot(event string, incoming []byte, assetType asset.Item, lastPushed time.Time) error { if event == "all" { var data WsFuturesOrderbookSnapshot err := json.Unmarshal(incoming, &data) @@ -444,11 +444,11 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, } base := orderbook.Book{ Asset: assetType, - Exchange: g.Name, + Exchange: e.Name, Pair: data.Contract, LastUpdated: data.Timestamp.Time(), LastPushed: lastPushed, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } base.Asks = make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { @@ -460,7 +460,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, base.Bids[x].Amount = data.Bids[x].Size base.Bids[x].Price = data.Bids[x].Price.Float64() } - return g.Websocket.Orderbook.LoadSnapshot(&base) + return e.Websocket.Orderbook.LoadSnapshot(&base) } var data []WsFuturesOrderbookUpdateEvent err := json.Unmarshal(incoming, &data) @@ -496,15 +496,15 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, if err != nil { return err } - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: ab[0], Bids: ab[1], Asset: assetType, - Exchange: g.Name, + Exchange: e.Name, Pair: currencyPair, LastUpdated: lastPushed, LastPushed: lastPushed, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, }) if err != nil { return err @@ -513,7 +513,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte, return nil } -func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) ([]order.Detail, error) { +func (e *Exchange) processFuturesOrdersPushData(data []byte, assetType asset.Item) ([]order.Detail, error) { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -537,8 +537,8 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) status, err = order.StringToOrderStatus(resp.Result[x].Status) } if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: strconv.FormatInt(resp.Result[x].ID, 10), Err: err, } @@ -546,7 +546,7 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) orderDetails[x] = order.Detail{ Amount: resp.Result[x].Size, - Exchange: g.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp.Result[x].ID, 10), Status: status, Pair: resp.Result[x].Contract, @@ -562,8 +562,8 @@ func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) return orderDetails, nil } -func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) error { - if !g.IsFillsFeedEnabled() { +func (e *Exchange) procesFuturesUserTrades(data []byte, assetType asset.Item) error { + if !e.IsFillsFeedEnabled() { return nil } @@ -581,7 +581,7 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro for x := range resp.Result { fills[x] = fill.Data{ Timestamp: resp.Result[x].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, CurrencyPair: resp.Result[x].Contract, OrderID: resp.Result[x].OrderID, TradeID: resp.Result[x].ID, @@ -590,10 +590,10 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro AssetType: assetType, } } - return g.Websocket.Fills.Update(fills...) + return e.Websocket.Fills.Update(fills...) } -func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error { +func (e *Exchange) processFuturesLiquidatesNotification(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -604,11 +604,11 @@ func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error { +func (e *Exchange) processFuturesAutoDeleveragesNotification(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -619,11 +619,11 @@ func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processPositionCloseData(data []byte) error { +func (e *Exchange) processPositionCloseData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -634,11 +634,11 @@ func (g *Gateio) processPositionCloseData(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetType asset.Item) error { +func (e *Exchange) processBalancePushData(ctx context.Context, data []byte, assetType asset.Item) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -649,7 +649,7 @@ func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetT if err != nil { return err } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -670,11 +670,11 @@ func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetT }, } } - g.Websocket.DataHandler <- changes - return account.ProcessChange(g.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } -func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error { +func (e *Exchange) processFuturesReduceRiskLimitNotification(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -685,11 +685,11 @@ func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processFuturesPositionsNotification(data []byte) error { +func (e *Exchange) processFuturesPositionsNotification(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -700,11 +700,11 @@ func (g *Gateio) processFuturesPositionsNotification(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processFuturesAutoOrderPushData(data []byte) error { +func (e *Exchange) processFuturesAutoOrderPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -715,6 +715,6 @@ func (g *Gateio) processFuturesAutoOrderPushData(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } diff --git a/exchanges/gateio/gateio_websocket_option.go b/exchanges/gateio/gateio_websocket_option.go index 38dd735b740..5cdc45cb43b 100644 --- a/exchanges/gateio/gateio_websocket_option.go +++ b/exchanges/gateio/gateio_websocket_option.go @@ -67,8 +67,8 @@ var defaultOptionsSubscriptions = []string{ } // WsOptionsConnect initiates a websocket connection to options websocket endpoints. -func (g *Gateio) WsOptionsConnect(ctx context.Context, conn websocket.Connection) error { - err := g.CurrencyPairs.IsAssetEnabled(asset.Options) +func (e *Exchange) WsOptionsConnect(ctx context.Context, conn websocket.Connection) error { + err := e.CurrencyPairs.IsAssetEnabled(asset.Options) if err != nil { return err } @@ -95,18 +95,18 @@ func (g *Gateio) WsOptionsConnect(ctx context.Context, conn websocket.Connection // GenerateOptionsDefaultSubscriptions generates list of channel subscriptions for options asset type. // TODO: Update to use the new subscription template system -func (g *Gateio) GenerateOptionsDefaultSubscriptions() (subscription.List, error) { +func (e *Exchange) GenerateOptionsDefaultSubscriptions() (subscription.List, error) { ctx := context.TODO() channelsToSubscribe := defaultOptionsSubscriptions var userID int64 - if g.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { var err error - _, err = g.GetCredentials(ctx) + _, err = e.GetCredentials(ctx) if err != nil { - g.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) goto getEnabledPairs } - response, err := g.GetSubAccountBalances(ctx, "") + response, err := e.GetSubAccountBalances(ctx, "") if err != nil { return nil, err } @@ -116,14 +116,14 @@ func (g *Gateio) GenerateOptionsDefaultSubscriptions() (subscription.List, error optionsBalancesChannel, ) userID = response[0].UserID - } else if g.Verbose { + } else if e.Verbose { log.Errorf(log.ExchangeSys, "no subaccount found for authenticated options channel subscriptions") } } getEnabledPairs: - pairs, err := g.GetEnabledPairs(asset.Options) + pairs, err := e.GetEnabledPairs(asset.Options) if err != nil { if errors.Is(err, asset.ErrNotEnabled) { return nil, nil // no enabled pairs, subscriptions require an associated pair. @@ -156,7 +156,7 @@ getEnabledPairs: } params["user_id"] = userID } - fPair, err := g.FormatExchangeCurrency(pairs[j], asset.Options) + fPair, err := e.FormatExchangeCurrency(pairs[j], asset.Options) if err != nil { return nil, err } @@ -171,7 +171,7 @@ getEnabledPairs: return subscriptions, nil } -func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { +func (e *Exchange) generateOptionsPayload(ctx context.Context, conn websocket.Connection, event string, channelsToSubscribe subscription.List) ([]WsInput, error) { if len(channelsToSubscribe) == 0 { return nil, errors.New("cannot generate payload, no channels supplied") } @@ -191,7 +191,7 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn optionsUnderlyingPriceChannel, optionsUnderlyingCandlesticksChannel: var uly currency.Pair - uly, err = g.GetUnderlyingFromCurrencyPair(channelsToSubscribe[i].Pairs[0]) + uly, err = e.GetUnderlyingFromCurrencyPair(channelsToSubscribe[i].Pairs[0]) if err != nil { return nil, err } @@ -230,12 +230,12 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn } params = append([]string{strconv.FormatInt(userID, 10)}, params...) var creds *account.Credentials - creds, err = g.GetCredentials(ctx) + creds, err = e.GetCredentials(ctx) if err != nil { return nil, err } var sigTemp string - sigTemp, err = g.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) + sigTemp, err = e.generateWsSignature(creds.Secret, event, channelsToSubscribe[i].Channel, timestamp.Unix()) if err != nil { return nil, err } @@ -285,106 +285,106 @@ func (g *Gateio) generateOptionsPayload(ctx context.Context, conn websocket.Conn } // OptionsSubscribe sends a websocket message to stop receiving data for asset type options -func (g *Gateio) OptionsSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, g.generateOptionsPayload) +func (e *Exchange) OptionsSubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, subscribeEvent, channelsToUnsubscribe, e.generateOptionsPayload) } // OptionsUnsubscribe sends a websocket message to stop receiving data for asset type options -func (g *Gateio) OptionsUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { - return g.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, g.generateOptionsPayload) +func (e *Exchange) OptionsUnsubscribe(ctx context.Context, conn websocket.Connection, channelsToUnsubscribe subscription.List) error { + return e.handleSubscription(ctx, conn, unsubscribeEvent, channelsToUnsubscribe, e.generateOptionsPayload) } // WsHandleOptionsData handles options websocket data -func (g *Gateio) WsHandleOptionsData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) WsHandleOptionsData(ctx context.Context, respRaw []byte) error { push, err := parseWSHeader(respRaw) if err != nil { return err } if push.Event == subscribeEvent || push.Event == unsubscribeEvent { - return g.Websocket.Match.RequireMatchWithData(push.ID, respRaw) + return e.Websocket.Match.RequireMatchWithData(push.ID, respRaw) } switch push.Channel { case optionsContractTickersChannel: - return g.processOptionsContractTickers(push.Result) + return e.processOptionsContractTickers(push.Result) case optionsUnderlyingTickersChannel: - return g.processOptionsUnderlyingTicker(push.Result) + return e.processOptionsUnderlyingTicker(push.Result) case optionsTradesChannel, optionsUnderlyingTradesChannel: - return g.processOptionsTradesPushData(respRaw) + return e.processOptionsTradesPushData(respRaw) case optionsUnderlyingPriceChannel: - return g.processOptionsUnderlyingPricePushData(push.Result) + return e.processOptionsUnderlyingPricePushData(push.Result) case optionsMarkPriceChannel: - return g.processOptionsMarkPrice(push.Result) + return e.processOptionsMarkPrice(push.Result) case optionsSettlementChannel: - return g.processOptionsSettlementPushData(push.Result) + return e.processOptionsSettlementPushData(push.Result) case optionsContractsChannel: - return g.processOptionsContractPushData(push.Result) + return e.processOptionsContractPushData(push.Result) case optionsContractCandlesticksChannel, optionsUnderlyingCandlesticksChannel: - return g.processOptionsCandlestickPushData(respRaw) + return e.processOptionsCandlestickPushData(respRaw) case optionsOrderbookChannel: - return g.processOptionsOrderbookSnapshotPushData(push.Event, push.Result, push.Time) + return e.processOptionsOrderbookSnapshotPushData(push.Event, push.Result, push.Time) case optionsOrderbookTickerChannel: - return g.processOrderbookTickerPushData(respRaw) + return e.processOrderbookTickerPushData(respRaw) case optionsOrderbookUpdateChannel: - return g.processOptionsOrderbookUpdate(ctx, push.Result, asset.Options, push.Time) + return e.processOptionsOrderbookUpdate(ctx, push.Result, asset.Options, push.Time) case optionsOrdersChannel: - return g.processOptionsOrderPushData(respRaw) + return e.processOptionsOrderPushData(respRaw) case optionsUserTradesChannel: - return g.processOptionsUserTradesPushData(respRaw) + return e.processOptionsUserTradesPushData(respRaw) case optionsLiquidatesChannel: - return g.processOptionsLiquidatesPushData(respRaw) + return e.processOptionsLiquidatesPushData(respRaw) case optionsUserSettlementChannel: - return g.processOptionsUsersPersonalSettlementsPushData(respRaw) + return e.processOptionsUsersPersonalSettlementsPushData(respRaw) case optionsPositionCloseChannel: - return g.processPositionCloseData(respRaw) + return e.processPositionCloseData(respRaw) case optionsBalancesChannel: - return g.processBalancePushData(ctx, respRaw, asset.Options) + return e.processBalancePushData(ctx, respRaw, asset.Options) case optionsPositionsChannel: - return g.processOptionsPositionPushData(respRaw) + return e.processOptionsPositionPushData(respRaw) default: - g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: g.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return errors.New(websocket.UnhandledMessage) } } -func (g *Gateio) processOptionsContractTickers(incoming []byte) error { +func (e *Exchange) processOptionsContractTickers(incoming []byte) error { var data OptionsTicker err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &ticker.Price{ + e.Websocket.DataHandler <- &ticker.Price{ Pair: data.Name, Last: data.LastPrice.Float64(), Bid: data.Bid1Price.Float64(), Ask: data.Ask1Price.Float64(), AskSize: data.Ask1Size, BidSize: data.Bid1Size, - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: asset.Options, } return nil } -func (g *Gateio) processOptionsUnderlyingTicker(incoming []byte) error { +func (e *Exchange) processOptionsUnderlyingTicker(incoming []byte) error { var data WsOptionUnderlyingTicker err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsTradesPushData(data []byte) error { - saveTradeData := g.IsSaveTradeDataEnabled() +func (e *Exchange) processOptionsTradesPushData(data []byte) error { + saveTradeData := e.IsSaveTradeDataEnabled() if !saveTradeData && - !g.IsTradeFeedEnabled() { + !e.IsTradeFeedEnabled() { return nil } resp := struct { @@ -403,56 +403,56 @@ func (g *Gateio) processOptionsTradesPushData(data []byte) error { Timestamp: resp.Result[x].CreateTime.Time(), CurrencyPair: resp.Result[x].Contract, AssetType: asset.Options, - Exchange: g.Name, + Exchange: e.Name, Price: resp.Result[x].Price, Amount: resp.Result[x].Size, TID: strconv.FormatInt(resp.Result[x].ID, 10), } } - return g.Websocket.Trade.Update(saveTradeData, trades...) + return e.Websocket.Trade.Update(saveTradeData, trades...) } -func (g *Gateio) processOptionsUnderlyingPricePushData(incoming []byte) error { +func (e *Exchange) processOptionsUnderlyingPricePushData(incoming []byte) error { var data WsOptionsUnderlyingPrice err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsMarkPrice(incoming []byte) error { +func (e *Exchange) processOptionsMarkPrice(incoming []byte) error { var data WsOptionsMarkPrice err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsSettlementPushData(incoming []byte) error { +func (e *Exchange) processOptionsSettlementPushData(incoming []byte) error { var data WsOptionsSettlement err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsContractPushData(incoming []byte) error { +func (e *Exchange) processOptionsContractPushData(incoming []byte) error { var data WsOptionsContract err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsCandlestickPushData(data []byte) error { +func (e *Exchange) processOptionsCandlestickPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -476,7 +476,7 @@ func (g *Gateio) processOptionsCandlestickPushData(data []byte) error { klineDatas[x] = websocket.KlineData{ Pair: currencyPair, AssetType: asset.Options, - Exchange: g.Name, + Exchange: e.Name, StartTime: resp.Result[x].Timestamp.Time(), Interval: icp[0], OpenPrice: resp.Result[x].OpenPrice.Float64(), @@ -486,21 +486,21 @@ func (g *Gateio) processOptionsCandlestickPushData(data []byte) error { Volume: resp.Result[x].Amount.Float64(), } } - g.Websocket.DataHandler <- klineDatas + e.Websocket.DataHandler <- klineDatas return nil } -func (g *Gateio) processOrderbookTickerPushData(incoming []byte) error { +func (e *Exchange) processOrderbookTickerPushData(incoming []byte) error { var data WsOptionsOrderbookTicker err := json.Unmarshal(incoming, &data) if err != nil { return err } - g.Websocket.DataHandler <- &data + e.Websocket.DataHandler <- &data return nil } -func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error { +func (e *Exchange) processOptionsOrderbookUpdate(ctx context.Context, incoming []byte, a asset.Item, pushTime time.Time) error { var data WsFuturesAndOptionsOrderbookUpdate if err := json.Unmarshal(incoming, &data); err != nil { return err @@ -515,7 +515,7 @@ func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []b bids[x].Price = data.Bids[x].Price.Float64() bids[x].Amount = data.Bids[x].Size } - return g.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, g, data.FirstUpdatedID, &orderbook.Update{ + return e.wsOBUpdateMgr.ProcessOrderbookUpdate(ctx, e, data.FirstUpdatedID, &orderbook.Update{ UpdateID: data.LastUpdatedID, UpdateTime: data.Timestamp.Time(), LastPushed: pushTime, @@ -527,7 +527,7 @@ func (g *Gateio) processOptionsOrderbookUpdate(ctx context.Context, incoming []b }) } -func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming []byte, lastPushed time.Time) error { +func (e *Exchange) processOptionsOrderbookSnapshotPushData(event string, incoming []byte, lastPushed time.Time) error { if event == "all" { var data WsOptionsOrderbookSnapshot err := json.Unmarshal(incoming, &data) @@ -536,11 +536,11 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming } base := orderbook.Book{ Asset: asset.Options, - Exchange: g.Name, + Exchange: e.Name, Pair: data.Contract, LastUpdated: data.Timestamp.Time(), LastPushed: lastPushed, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } base.Asks = make([]orderbook.Level, len(data.Asks)) for x := range data.Asks { @@ -552,7 +552,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming base.Bids[x].Amount = data.Bids[x].Size base.Bids[x].Price = data.Bids[x].Price.Float64() } - return g.Websocket.Orderbook.LoadSnapshot(&base) + return e.Websocket.Orderbook.LoadSnapshot(&base) } var data []WsFuturesOrderbookUpdateEvent err := json.Unmarshal(incoming, &data) @@ -586,15 +586,15 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming if err != nil { return err } - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asks: ab[0], Bids: ab[1], Asset: asset.Options, - Exchange: g.Name, + Exchange: e.Name, Pair: currencyPair, LastUpdated: lastPushed, LastPushed: lastPushed, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, }) if err != nil { return err @@ -603,7 +603,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming return nil } -func (g *Gateio) processOptionsOrderPushData(data []byte) error { +func (e *Exchange) processOptionsOrderPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -627,7 +627,7 @@ func (g *Gateio) processOptionsOrderPushData(data []byte) error { } orderDetails[x] = order.Detail{ Amount: resp.Result[x].Size, - Exchange: g.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp.Result[x].ID, 10), Status: status, Pair: resp.Result[x].Contract, @@ -638,12 +638,12 @@ func (g *Gateio) processOptionsOrderPushData(data []byte) error { AccountID: resp.Result[x].User, } } - g.Websocket.DataHandler <- orderDetails + e.Websocket.DataHandler <- orderDetails return nil } -func (g *Gateio) processOptionsUserTradesPushData(data []byte) error { - if !g.IsFillsFeedEnabled() { +func (e *Exchange) processOptionsUserTradesPushData(data []byte) error { + if !e.IsFillsFeedEnabled() { return nil } resp := struct { @@ -660,7 +660,7 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error { for x := range resp.Result { fills[x] = fill.Data{ Timestamp: resp.Result[x].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, CurrencyPair: resp.Result[x].Contract, OrderID: resp.Result[x].OrderID, TradeID: resp.Result[x].ID, @@ -668,10 +668,10 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error { Amount: resp.Result[x].Size, } } - return g.Websocket.Fills.Update(fills...) + return e.Websocket.Fills.Update(fills...) } -func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error { +func (e *Exchange) processOptionsLiquidatesPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -682,11 +682,11 @@ func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) error { +func (e *Exchange) processOptionsUsersPersonalSettlementsPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -697,11 +697,11 @@ func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) err if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } -func (g *Gateio) processOptionsPositionPushData(data []byte) error { +func (e *Exchange) processOptionsPositionPushData(data []byte) error { resp := struct { Time types.Time `json:"time"` Channel string `json:"channel"` @@ -712,6 +712,6 @@ func (g *Gateio) processOptionsPositionPushData(data []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } diff --git a/exchanges/gateio/gateio_websocket_request_futures.go b/exchanges/gateio/gateio_websocket_request_futures.go index f5aa78dd45d..bc68ca49283 100644 --- a/exchanges/gateio/gateio_websocket_request_futures.go +++ b/exchanges/gateio/gateio_websocket_request_futures.go @@ -18,13 +18,13 @@ var ( ) // authenticateFutures sends an authentication message to the websocket connection -func (g *Gateio) authenticateFutures(ctx context.Context, conn websocket.Connection) error { - return g.websocketLogin(ctx, conn, "futures.login") +func (e *Exchange) authenticateFutures(ctx context.Context, conn websocket.Connection) error { + return e.websocketLogin(ctx, conn, "futures.login") } // WebsocketFuturesSubmitOrder submits an order via the websocket connection -func (g *Gateio) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, order *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) { - resps, err := g.WebsocketFuturesSubmitOrders(ctx, a, order) +func (e *Exchange) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, order *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) { + resps, err := e.WebsocketFuturesSubmitOrders(ctx, a, order) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (g *Gateio) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, } // WebsocketFuturesSubmitOrders submits orders via the websocket connection. All orders must be for the same asset. -func (g *Gateio) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item, orders ...*ContractOrderCreateParams) ([]WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item, orders ...*ContractOrderCreateParams) ([]WebsocketFuturesOrderResponse, error) { if len(orders) == 0 { return nil, errOrdersEmpty } @@ -65,16 +65,16 @@ func (g *Gateio) WebsocketFuturesSubmitOrders(ctx context.Context, a asset.Item, if len(orders) == 1 { var singleResponse WebsocketFuturesOrderResponse - err := g.SendWebsocketRequest(ctx, perpetualSubmitOrderEPL, "futures.order_place", a, orders[0], &singleResponse, 2) + err := e.SendWebsocketRequest(ctx, perpetualSubmitOrderEPL, "futures.order_place", a, orders[0], &singleResponse, 2) return []WebsocketFuturesOrderResponse{singleResponse}, err } var resp []WebsocketFuturesOrderResponse - return resp, g.SendWebsocketRequest(ctx, perpetualSubmitBatchOrdersEPL, "futures.order_batch_place", a, orders, &resp, 2) + return resp, e.SendWebsocketRequest(ctx, perpetualSubmitBatchOrdersEPL, "futures.order_batch_place", a, orders, &resp, 2) } // WebsocketFuturesCancelOrder cancels an order via the websocket connection. -func (g *Gateio) WebsocketFuturesCancelOrder(ctx context.Context, orderID string, contract currency.Pair, a asset.Item) (*WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesCancelOrder(ctx context.Context, orderID string, contract currency.Pair, a asset.Item) (*WebsocketFuturesOrderResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -88,11 +88,11 @@ func (g *Gateio) WebsocketFuturesCancelOrder(ctx context.Context, orderID string }{OrderID: orderID} var resp WebsocketFuturesOrderResponse - return &resp, g.SendWebsocketRequest(ctx, perpetualCancelOrderEPL, "futures.order_cancel", a, params, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, perpetualCancelOrderEPL, "futures.order_cancel", a, params, &resp, 1) } // WebsocketFuturesCancelAllOpenFuturesOrders cancels multiple orders via the websocket. -func (g *Gateio) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context, contract currency.Pair, a asset.Item, side string) ([]WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context, contract currency.Pair, a asset.Item, side string) ([]WebsocketFuturesOrderResponse, error) { if err := validateFuturesPairAsset(contract, a); err != nil { return nil, err } @@ -107,11 +107,11 @@ func (g *Gateio) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Context, }{Contract: contract, Side: side} var resp []WebsocketFuturesOrderResponse - return resp, g.SendWebsocketRequest(ctx, perpetualCancelOpenOrdersEPL, "futures.order_cancel_cp", a, params, &resp, 2) + return resp, e.SendWebsocketRequest(ctx, perpetualCancelOpenOrdersEPL, "futures.order_cancel_cp", a, params, &resp, 2) } // WebsocketFuturesAmendOrder amends an order via the websocket connection -func (g *Gateio) WebsocketFuturesAmendOrder(ctx context.Context, amend *WebsocketFuturesAmendOrder) (*WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesAmendOrder(ctx context.Context, amend *WebsocketFuturesAmendOrder) (*WebsocketFuturesOrderResponse, error) { if amend == nil { return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, amend) } @@ -129,11 +129,11 @@ func (g *Gateio) WebsocketFuturesAmendOrder(ctx context.Context, amend *Websocke } var resp WebsocketFuturesOrderResponse - return &resp, g.SendWebsocketRequest(ctx, perpetualAmendOrderEPL, "futures.order_amend", amend.Asset, amend, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, perpetualAmendOrderEPL, "futures.order_amend", amend.Asset, amend, &resp, 1) } // WebsocketFuturesOrderList fetches a list of orders via the websocket connection -func (g *Gateio) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketFutureOrdersList) ([]WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketFutureOrdersList) ([]WebsocketFuturesOrderResponse, error) { if list == nil { return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, list) } @@ -147,11 +147,11 @@ func (g *Gateio) WebsocketFuturesOrderList(ctx context.Context, list *WebsocketF } var resp []WebsocketFuturesOrderResponse - return resp, g.SendWebsocketRequest(ctx, perpetualGetOrdersEPL, "futures.order_list", list.Asset, list, &resp, 1) + return resp, e.SendWebsocketRequest(ctx, perpetualGetOrdersEPL, "futures.order_list", list.Asset, list, &resp, 1) } // WebsocketFuturesGetOrderStatus gets the status of an order via the websocket connection. -func (g *Gateio) WebsocketFuturesGetOrderStatus(ctx context.Context, contract currency.Pair, a asset.Item, orderID string) (*WebsocketFuturesOrderResponse, error) { +func (e *Exchange) WebsocketFuturesGetOrderStatus(ctx context.Context, contract currency.Pair, a asset.Item, orderID string) (*WebsocketFuturesOrderResponse, error) { if err := validateFuturesPairAsset(contract, a); err != nil { return nil, err } @@ -165,7 +165,7 @@ func (g *Gateio) WebsocketFuturesGetOrderStatus(ctx context.Context, contract cu }{OrderID: orderID} var resp WebsocketFuturesOrderResponse - return &resp, g.SendWebsocketRequest(ctx, perpetualFetchOrderEPL, "futures.order_status", a, params, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, perpetualFetchOrderEPL, "futures.order_status", a, params, &resp, 1) } // validateFuturesPairAsset enforces that a futures pair's quote currency matches the given asset diff --git a/exchanges/gateio/gateio_websocket_request_futures_test.go b/exchanges/gateio/gateio_websocket_request_futures_test.go index 9929c0a8efd..a290c96c055 100644 --- a/exchanges/gateio/gateio_websocket_request_futures_test.go +++ b/exchanges/gateio/gateio_websocket_request_futures_test.go @@ -18,22 +18,22 @@ var ( func TestWebsocketFuturesSubmitOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, &ContractOrderCreateParams{}) + _, err := e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, &ContractOrderCreateParams{}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) out := &ContractOrderCreateParams{Contract: BTCUSDT} - _, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidPrice) out.Price = "40000" - _, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidAmount) out.Size = 1 // 1 lovely long contract out.AutoSize = "silly_billies" - _, err = g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidAutoSize) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) out.AutoSize = "" got, err := g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out) @@ -43,36 +43,36 @@ func TestWebsocketFuturesSubmitOrder(t *testing.T) { func TestWebsocketFuturesSubmitOrders(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures) + _, err := e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures) require.ErrorIs(t, err, errOrdersEmpty) out := &ContractOrderCreateParams{} - _, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) out.Contract = BTCUSDT - _, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidPrice) out.Price = "40000" - _, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidAmount) out.Size = 1 // 1 lovely long contract out.AutoSize = "silly_billies" - _, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidAutoSize) out.AutoSize = "close_long" - _, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) + _, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.USDTMarginedFutures, out) require.ErrorIs(t, err, errInvalidAmount) out.AutoSize = "" - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) // test single order got, err := g.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out) @@ -87,18 +87,18 @@ func TestWebsocketFuturesSubmitOrders(t *testing.T) { func TestWebsocketFuturesCancelOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesCancelOrder(t.Context(), "", currency.EMPTYPAIR, asset.Empty) + _, err := e.WebsocketFuturesCancelOrder(t.Context(), "", currency.EMPTYPAIR, asset.Empty) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = g.WebsocketFuturesCancelOrder(t.Context(), "42069", currency.EMPTYPAIR, asset.Empty) + _, err = e.WebsocketFuturesCancelOrder(t.Context(), "42069", currency.EMPTYPAIR, asset.Empty) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = g.WebsocketFuturesCancelOrder(t.Context(), "42069", BTCUSDT, asset.Empty) + _, err = e.WebsocketFuturesCancelOrder(t.Context(), "42069", BTCUSDT, asset.Empty) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) got, err := g.WebsocketFuturesCancelOrder(t.Context(), "513160761072", BTCUSDT, asset.USDTMarginedFutures) require.NoError(t, err) @@ -107,18 +107,18 @@ func TestWebsocketFuturesCancelOrder(t *testing.T) { func TestWebsocketFuturesCancelAllOpenFuturesOrders(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), currency.EMPTYPAIR, asset.Empty, "") + _, err := e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), currency.EMPTYPAIR, asset.Empty, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.Empty, "bruh") + _, err = e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.Empty, "bruh") require.ErrorIs(t, err, asset.ErrNotSupported) - _, err = g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bruh") + _, err = e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bruh") require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) got, err := g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bid") require.NoError(t, err) @@ -127,30 +127,30 @@ func TestWebsocketFuturesCancelAllOpenFuturesOrders(t *testing.T) { func TestWebsocketFuturesAmendOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesAmendOrder(t.Context(), nil) + _, err := e.WebsocketFuturesAmendOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) amend := &WebsocketFuturesAmendOrder{} - _, err = g.WebsocketFuturesAmendOrder(t.Context(), amend) + _, err = e.WebsocketFuturesAmendOrder(t.Context(), amend) require.ErrorIs(t, err, order.ErrOrderIDNotSet) amend.OrderID = "1337" - _, err = g.WebsocketFuturesAmendOrder(t.Context(), amend) + _, err = e.WebsocketFuturesAmendOrder(t.Context(), amend) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) amend.Contract = BTCUSDT - _, err = g.WebsocketFuturesAmendOrder(t.Context(), amend) + _, err = e.WebsocketFuturesAmendOrder(t.Context(), amend) require.ErrorIs(t, err, asset.ErrNotSupported) amend.Asset = asset.USDTMarginedFutures - _, err = g.WebsocketFuturesAmendOrder(t.Context(), amend) + _, err = e.WebsocketFuturesAmendOrder(t.Context(), amend) require.ErrorIs(t, err, errInvalidAmount) amend.Size = 2 - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) amend.OrderID = "513170215869" got, err := g.WebsocketFuturesAmendOrder(t.Context(), amend) @@ -160,24 +160,24 @@ func TestWebsocketFuturesAmendOrder(t *testing.T) { func TestWebsocketFuturesOrderList(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesOrderList(t.Context(), nil) + _, err := e.WebsocketFuturesOrderList(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) list := &WebsocketFutureOrdersList{} - _, err = g.WebsocketFuturesOrderList(t.Context(), list) + _, err = e.WebsocketFuturesOrderList(t.Context(), list) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) list.Contract = BTCUSDT - _, err = g.WebsocketFuturesOrderList(t.Context(), list) + _, err = e.WebsocketFuturesOrderList(t.Context(), list) require.ErrorIs(t, err, asset.ErrNotSupported) list.Asset = asset.USDTMarginedFutures - _, err = g.WebsocketFuturesOrderList(t.Context(), list) + _, err = e.WebsocketFuturesOrderList(t.Context(), list) require.ErrorIs(t, err, errStatusNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) list.Status = statusOpen got, err := g.WebsocketFuturesOrderList(t.Context(), list) @@ -187,18 +187,18 @@ func TestWebsocketFuturesOrderList(t *testing.T) { func TestWebsocketFuturesGetOrderStatus(t *testing.T) { t.Parallel() - _, err := g.WebsocketFuturesGetOrderStatus(t.Context(), currency.EMPTYPAIR, asset.Empty, "") + _, err := e.WebsocketFuturesGetOrderStatus(t.Context(), currency.EMPTYPAIR, asset.Empty, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.Empty, "") + _, err = e.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.Empty, "") require.ErrorIs(t, err, asset.ErrNotSupported) - _, err = g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "") + _, err = e.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Futures) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Futures) got, err := g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "513170215869") require.NoError(t, err) diff --git a/exchanges/gateio/gateio_websocket_request_spot.go b/exchanges/gateio/gateio_websocket_request_spot.go index e9261b4c8c0..0cf2bdfe96f 100644 --- a/exchanges/gateio/gateio_websocket_request_spot.go +++ b/exchanges/gateio/gateio_websocket_request_spot.go @@ -20,13 +20,13 @@ var ( ) // authenticateSpot sends an authentication message to the websocket connection -func (g *Gateio) authenticateSpot(ctx context.Context, conn websocket.Connection) error { - return g.websocketLogin(ctx, conn, "spot.login") +func (e *Exchange) authenticateSpot(ctx context.Context, conn websocket.Connection) error { + return e.websocketLogin(ctx, conn, "spot.login") } // WebsocketSpotSubmitOrder submits an order via the websocket connection -func (g *Gateio) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrderRequest) (*WebsocketOrderResponse, error) { - resps, err := g.WebsocketSpotSubmitOrders(ctx, order) +func (e *Exchange) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrderRequest) (*WebsocketOrderResponse, error) { + resps, err := e.WebsocketSpotSubmitOrders(ctx, order) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func (g *Gateio) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrde // WebsocketSpotSubmitOrders submits orders via the websocket connection. You can // send multiple orders in a single request. But only for one asset route. -func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*CreateOrderRequest) ([]WebsocketOrderResponse, error) { +func (e *Exchange) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*CreateOrderRequest) ([]WebsocketOrderResponse, error) { if len(orders) == 0 { return nil, errOrdersEmpty } @@ -46,7 +46,7 @@ func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*Creat for i := range orders { if orders[i].Text == "" { // API requires Text field, or it will be rejected - orders[i].Text = "t-" + strconv.FormatInt(g.Counter.IncrementAndGet(), 10) + orders[i].Text = "t-" + strconv.FormatInt(e.Counter.IncrementAndGet(), 10) } if orders[i].CurrencyPair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty @@ -64,14 +64,14 @@ func (g *Gateio) WebsocketSpotSubmitOrders(ctx context.Context, orders ...*Creat if len(orders) == 1 { var singleResponse WebsocketOrderResponse - return []WebsocketOrderResponse{singleResponse}, g.SendWebsocketRequest(ctx, spotPlaceOrderEPL, "spot.order_place", asset.Spot, orders[0], &singleResponse, 2) + return []WebsocketOrderResponse{singleResponse}, e.SendWebsocketRequest(ctx, spotPlaceOrderEPL, "spot.order_place", asset.Spot, orders[0], &singleResponse, 2) } var resp []WebsocketOrderResponse - return resp, g.SendWebsocketRequest(ctx, spotBatchOrdersEPL, "spot.order_place", asset.Spot, orders, &resp, 2) + return resp, e.SendWebsocketRequest(ctx, spotBatchOrdersEPL, "spot.order_place", asset.Spot, orders, &resp, 2) } // WebsocketSpotCancelOrder cancels an order via the websocket connection -func (g *Gateio) WebsocketSpotCancelOrder(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) { +func (e *Exchange) WebsocketSpotCancelOrder(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -82,11 +82,11 @@ func (g *Gateio) WebsocketSpotCancelOrder(ctx context.Context, orderID string, p params := &WebsocketOrderRequest{OrderID: orderID, Pair: pair.String(), Account: account} var resp WebsocketOrderResponse - return &resp, g.SendWebsocketRequest(ctx, spotCancelSingleOrderEPL, "spot.order_cancel", asset.Spot, params, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, spotCancelSingleOrderEPL, "spot.order_cancel", asset.Spot, params, &resp, 1) } // WebsocketSpotCancelAllOrdersByIDs cancels multiple orders via the websocket -func (g *Gateio) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []WebsocketOrderBatchRequest) ([]WebsocketCancellAllResponse, error) { +func (e *Exchange) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []WebsocketOrderBatchRequest) ([]WebsocketCancellAllResponse, error) { if len(o) == 0 { return nil, errNoOrdersToCancel } @@ -101,11 +101,11 @@ func (g *Gateio) WebsocketSpotCancelAllOrdersByIDs(ctx context.Context, o []Webs } var resp []WebsocketCancellAllResponse - return resp, g.SendWebsocketRequest(ctx, spotCancelBatchOrdersEPL, "spot.order_cancel_ids", asset.Spot, o, &resp, 2) + return resp, e.SendWebsocketRequest(ctx, spotCancelBatchOrdersEPL, "spot.order_cancel_ids", asset.Spot, o, &resp, 2) } // WebsocketSpotCancelAllOrdersByPair cancels all orders for a specific pair -func (g *Gateio) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair currency.Pair, side order.Side, account string) ([]WebsocketOrderResponse, error) { +func (e *Exchange) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair currency.Pair, side order.Side, account string) ([]WebsocketOrderResponse, error) { if !pair.IsEmpty() && side == order.UnknownSide { // This case will cancel all orders for every pair, this can be introduced later return nil, fmt.Errorf("'%v' %w while pair is set", side, order.ErrSideIsInvalid) @@ -123,11 +123,11 @@ func (g *Gateio) WebsocketSpotCancelAllOrdersByPair(ctx context.Context, pair cu } var resp []WebsocketOrderResponse - return resp, g.SendWebsocketRequest(ctx, spotCancelAllOpenOrdersEPL, "spot.order_cancel_cp", asset.Spot, params, &resp, 1) + return resp, e.SendWebsocketRequest(ctx, spotCancelAllOpenOrdersEPL, "spot.order_cancel_cp", asset.Spot, params, &resp, 1) } // WebsocketSpotAmendOrder amends an order via the websocket connection -func (g *Gateio) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAmendOrder) (*WebsocketOrderResponse, error) { +func (e *Exchange) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAmendOrder) (*WebsocketOrderResponse, error) { if amend == nil { return nil, fmt.Errorf("%w: %T", common.ErrNilPointer, amend) } @@ -145,11 +145,11 @@ func (g *Gateio) WebsocketSpotAmendOrder(ctx context.Context, amend *WebsocketAm } var resp WebsocketOrderResponse - return &resp, g.SendWebsocketRequest(ctx, spotAmendOrderEPL, "spot.order_amend", asset.Spot, amend, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, spotAmendOrderEPL, "spot.order_amend", asset.Spot, amend, &resp, 1) } // WebsocketSpotGetOrderStatus gets the status of an order via the websocket connection -func (g *Gateio) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) { +func (e *Exchange) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string, pair currency.Pair, account string) (*WebsocketOrderResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -160,5 +160,5 @@ func (g *Gateio) WebsocketSpotGetOrderStatus(ctx context.Context, orderID string params := &WebsocketOrderRequest{OrderID: orderID, Pair: pair.String(), Account: account} var resp WebsocketOrderResponse - return &resp, g.SendWebsocketRequest(ctx, spotGetOrdersEPL, "spot.order_status", asset.Spot, params, &resp, 1) + return &resp, e.SendWebsocketRequest(ctx, spotGetOrdersEPL, "spot.order_status", asset.Spot, params, &resp, 1) } diff --git a/exchanges/gateio/gateio_websocket_request_spot_test.go b/exchanges/gateio/gateio_websocket_request_spot_test.go index 492579daef3..8e28da4e35c 100644 --- a/exchanges/gateio/gateio_websocket_request_spot_test.go +++ b/exchanges/gateio/gateio_websocket_request_spot_test.go @@ -15,12 +15,12 @@ import ( func TestWebsocketLogin(t *testing.T) { t.Parallel() - err := g.websocketLogin(t.Context(), nil, "") + err := e.websocketLogin(t.Context(), nil, "") require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) c, err := g.Websocket.GetConnection(asset.Spot) require.NoError(t, err) @@ -34,23 +34,23 @@ func TestWebsocketLogin(t *testing.T) { func TestWebsocketSpotSubmitOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotSubmitOrder(t.Context(), &CreateOrderRequest{}) + _, err := e.WebsocketSpotSubmitOrder(t.Context(), &CreateOrderRequest{}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) out := &CreateOrderRequest{CurrencyPair: currency.NewPair(currency.NewCode("GT"), currency.USDT).Format(currency.PairFormat{Uppercase: true, Delimiter: "_"})} - _, err = g.WebsocketSpotSubmitOrder(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrder(t.Context(), out) require.ErrorIs(t, err, order.ErrSideIsInvalid) out.Side = strings.ToLower(order.Sell.String()) - _, err = g.WebsocketSpotSubmitOrder(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrder(t.Context(), out) require.ErrorIs(t, err, errInvalidAmount) out.Amount = 1 out.Type = "limit" - _, err = g.WebsocketSpotSubmitOrder(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrder(t.Context(), out) require.ErrorIs(t, err, errInvalidPrice) out.Price = 100 - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) got, err := g.WebsocketSpotSubmitOrder(t.Context(), out) require.NoError(t, err) @@ -59,26 +59,26 @@ func TestWebsocketSpotSubmitOrder(t *testing.T) { func TestWebsocketSpotSubmitOrders(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotSubmitOrders(t.Context()) + _, err := e.WebsocketSpotSubmitOrders(t.Context()) require.ErrorIs(t, err, errOrdersEmpty) out := &CreateOrderRequest{} - _, err = g.WebsocketSpotSubmitOrders(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrders(t.Context(), out) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) out.CurrencyPair = currency.NewBTCUSDT() - _, err = g.WebsocketSpotSubmitOrders(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrders(t.Context(), out) require.ErrorIs(t, err, order.ErrSideIsInvalid) out.Side = strings.ToLower(order.Buy.String()) - _, err = g.WebsocketSpotSubmitOrders(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrders(t.Context(), out) require.ErrorIs(t, err, errInvalidAmount) out.Amount = 0.0003 out.Type = "limit" - _, err = g.WebsocketSpotSubmitOrders(t.Context(), out) + _, err = e.WebsocketSpotSubmitOrders(t.Context(), out) require.ErrorIs(t, err, errInvalidPrice) out.Price = 20000 - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) // test single order got, err := g.WebsocketSpotSubmitOrders(t.Context(), out) @@ -93,14 +93,14 @@ func TestWebsocketSpotSubmitOrders(t *testing.T) { func TestWebsocketSpotCancelOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotCancelOrder(t.Context(), "", currency.EMPTYPAIR, "") + _, err := e.WebsocketSpotCancelOrder(t.Context(), "", currency.EMPTYPAIR, "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = g.WebsocketSpotCancelOrder(t.Context(), "1337", currency.EMPTYPAIR, "") + _, err = e.WebsocketSpotCancelOrder(t.Context(), "1337", currency.EMPTYPAIR, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) got, err := g.WebsocketSpotCancelOrder(t.Context(), "644913098758", BTCUSDT, "") require.NoError(t, err) @@ -109,20 +109,20 @@ func TestWebsocketSpotCancelOrder(t *testing.T) { func TestWebsocketSpotCancelAllOrdersByIDs(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{}) + _, err := e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{}) require.ErrorIs(t, err, errNoOrdersToCancel) out := WebsocketOrderBatchRequest{} - _, err = g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out}) + _, err = e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) out.OrderID = "1337" - _, err = g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out}) + _, err = e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) out.Pair = BTCUSDT - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) out.OrderID = "644913101755" got, err := g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out}) @@ -132,12 +132,12 @@ func TestWebsocketSpotCancelAllOrdersByIDs(t *testing.T) { func TestWebsocketSpotCancelAllOrdersByPair(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.NewPairWithDelimiter("LTC", "USDT", "_"), 0, "") + _, err := e.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.NewPairWithDelimiter("LTC", "USDT", "_"), 0, "") require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) got, err := g.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.EMPTYPAIR, order.Buy, "") require.NoError(t, err) @@ -146,27 +146,27 @@ func TestWebsocketSpotCancelAllOrdersByPair(t *testing.T) { func TestWebsocketSpotAmendOrder(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotAmendOrder(t.Context(), nil) + _, err := e.WebsocketSpotAmendOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) amend := &WebsocketAmendOrder{} - _, err = g.WebsocketSpotAmendOrder(t.Context(), amend) + _, err = e.WebsocketSpotAmendOrder(t.Context(), amend) require.ErrorIs(t, err, order.ErrOrderIDNotSet) amend.OrderID = "1337" - _, err = g.WebsocketSpotAmendOrder(t.Context(), amend) + _, err = e.WebsocketSpotAmendOrder(t.Context(), amend) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) amend.Pair = BTCUSDT - _, err = g.WebsocketSpotAmendOrder(t.Context(), amend) + _, err = e.WebsocketSpotAmendOrder(t.Context(), amend) require.ErrorIs(t, err, errInvalidAmount) amend.Amount = "0.0004" - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + g := newExchangeWithWebsocket(t, asset.Spot) amend.OrderID = "645029162673" got, err := g.WebsocketSpotAmendOrder(t.Context(), amend) @@ -176,16 +176,16 @@ func TestWebsocketSpotAmendOrder(t *testing.T) { func TestWebsocketSpotGetOrderStatus(t *testing.T) { t.Parallel() - _, err := g.WebsocketSpotGetOrderStatus(t.Context(), "", currency.EMPTYPAIR, "") + _, err := e.WebsocketSpotGetOrderStatus(t.Context(), "", currency.EMPTYPAIR, "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = g.WebsocketSpotGetOrderStatus(t.Context(), "1337", currency.EMPTYPAIR, "") + _, err = e.WebsocketSpotGetOrderStatus(t.Context(), "1337", currency.EMPTYPAIR, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.UpdatePairsOnce(t, g) - g := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + testexch.UpdatePairsOnce(t, e) + g := newExchangeWithWebsocket(t, asset.Spot) got, err := g.WebsocketSpotGetOrderStatus(t.Context(), "644999650452", BTCUSDT, "") require.NoError(t, err) @@ -194,28 +194,28 @@ func TestWebsocketSpotGetOrderStatus(t *testing.T) { // getWebsocketInstance returns a websocket instance copy for testing. // This restricts the pairs to a single pair per asset type to reduce test time. -func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Gateio { +func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Exchange { t.Helper() if apiKey == "" || apiSecret == "" { t.Skip() } - g := new(Gateio) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(g), "Test instance Setup must not error") - testexch.UpdatePairsOnce(t, g) - g.API.AuthenticatedSupport = true - g.API.AuthenticatedWebsocketSupport = true - g.SetCredentials(apiKey, apiSecret, "", "", "", "") - g.Websocket.SetCanUseAuthenticatedEndpoints(true) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + testexch.UpdatePairsOnce(t, e) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) switch a { case asset.Spot: - avail, err := g.GetAvailablePairs(a) + avail, err := e.GetAvailablePairs(a) require.NoError(t, err) if len(avail) > 1 { // reduce pairs to 1 to speed up tests avail = avail[:1] } - require.NoError(t, g.SetPairs(avail, a, true)) + require.NoError(t, e.SetPairs(avail, a, true)) case asset.Futures: - avail, err := g.GetAvailablePairs(a) + avail, err := e.GetAvailablePairs(a) require.NoError(t, err) usdtPairs, err := avail.GetPairsByQuote(currency.USDT) // Get USDT margin pairs require.NoError(t, err) @@ -226,11 +226,11 @@ func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Gateio { avail[0] = usdtPairs[0] avail[1] = btcPairs[0] avail = avail[:2] - require.NoError(t, g.SetPairs(avail, a, true)) + require.NoError(t, e.SetPairs(avail, a, true)) default: - require.NoError(t, g.CurrencyPairs.SetAssetEnabled(a, false)) + require.NoError(t, e.CurrencyPairs.SetAssetEnabled(a, false)) } - require.NoError(t, g.Websocket.Connect()) - return g + require.NoError(t, e.Websocket.Connect()) + return e } diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index c14e3009c11..ecf4df0418f 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -37,21 +37,21 @@ import ( ) // SetDefaults sets default values for the exchange -func (g *Gateio) SetDefaults() { - g.Name = "GateIO" - g.Enabled = true - g.Verbose = true - g.API.CredentialsValidator.RequiresKey = true - g.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "GateIO" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter, Uppercase: true} configFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter, Uppercase: true} - err := g.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot, asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.Margin, asset.CrossMargin, asset.DeliveryFutures, asset.Options) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot, asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.Margin, asset.CrossMargin, asset.DeliveryFutures, asset.Options) if err != nil { log.Errorln(log.ExchangeSys, err) } - g.Features = exchange.Features{ + e.Features = exchange.Features{ CurrencyTranslations: currency.NewTranslations(map[currency.Code]currency.Code{ currency.NewCode("MBABYDOGE"): currency.BABYDOGE, }), @@ -146,7 +146,7 @@ func (g *Gateio) SetDefaults() { }, Subscriptions: defaultSubscriptions.Clone(), } - g.Requester, err = request.New(g.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(packageRateLimits), ) @@ -154,17 +154,17 @@ func (g *Gateio) SetDefaults() { log.Errorln(log.ExchangeSys, err) } // TODO: Majority of margin REST endpoints are labelled as deprecated on the API docs. These will need to be removed. - err = g.DisableAssetWebsocketSupport(asset.Margin) + err = e.DisableAssetWebsocketSupport(asset.Margin) if err != nil { log.Errorln(log.ExchangeSys, err) } // TODO: Add websocket cross margin support. - err = g.DisableAssetWebsocketSupport(asset.CrossMargin) + err = e.DisableAssetWebsocketSupport(asset.CrossMargin) if err != nil { log.Errorln(log.ExchangeSys, err) } - g.API.Endpoints = g.NewEndpoints() - err = g.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: gateioTradeURL, exchange.RestFutures: gateioFuturesLiveTradingAlternative, exchange.RestSpotSupplementary: gateioFuturesTestnetTrading, @@ -173,33 +173,33 @@ func (g *Gateio) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - g.Websocket = websocket.NewManager() - g.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - g.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - g.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit - g.wsOBUpdateMgr = newWsOBUpdateManager(defaultWSSnapshotSyncDelay) + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.wsOBUpdateMgr = newWsOBUpdateManager(defaultWSSnapshotSyncDelay) } // Setup sets user configuration -func (g *Gateio) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - g.SetEnabled(false) + e.SetEnabled(false) return nil } - err = g.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - err = g.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, - Features: &g.Features.Supports.WebsocketCapabilities, - FillsFeed: g.Features.Enabled.FillsFeed, - TradeFeed: g.Features.Enabled.TradeFeed, + Features: &e.Features.Supports.WebsocketCapabilities, + FillsFeed: e.Features.Enabled.FillsFeed, + TradeFeed: e.Features.Enabled.TradeFeed, UseMultiConnectionManagement: true, RateLimitDefinitions: packageRateLimits, }) @@ -207,60 +207,60 @@ func (g *Gateio) Setup(exch *config.Exchange) error { return err } // Spot connection - err = g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: gateioWebsocketEndpoint, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, - Handler: g.WsHandleSpotData, - Subscriber: g.Subscribe, - Unsubscriber: g.Unsubscribe, - GenerateSubscriptions: g.generateSubscriptionsSpot, - Connector: g.WsConnectSpot, - Authenticate: g.authenticateSpot, + Handler: e.WsHandleSpotData, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptionsSpot, + Connector: e.WsConnectSpot, + Authenticate: e.authenticateSpot, MessageFilter: asset.Spot, - BespokeGenerateMessageID: g.GenerateWebsocketMessageID, + BespokeGenerateMessageID: e.GenerateWebsocketMessageID, }) if err != nil { return err } // Futures connection - USDT margined - err = g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: usdtFuturesWebsocketURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, Handler: func(ctx context.Context, incoming []byte) error { - return g.WsHandleFuturesData(ctx, incoming, asset.USDTMarginedFutures) + return e.WsHandleFuturesData(ctx, incoming, asset.USDTMarginedFutures) }, - Subscriber: g.FuturesSubscribe, - Unsubscriber: g.FuturesUnsubscribe, + Subscriber: e.FuturesSubscribe, + Unsubscriber: e.FuturesUnsubscribe, GenerateSubscriptions: func() (subscription.List, error) { - return g.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) + return e.GenerateFuturesDefaultSubscriptions(asset.USDTMarginedFutures) }, - Connector: g.WsFuturesConnect, - Authenticate: g.authenticateFutures, + Connector: e.WsFuturesConnect, + Authenticate: e.authenticateFutures, MessageFilter: asset.USDTMarginedFutures, - BespokeGenerateMessageID: g.GenerateWebsocketMessageID, + BespokeGenerateMessageID: e.GenerateWebsocketMessageID, }) if err != nil { return err } // Futures connection - BTC margined - err = g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: btcFuturesWebsocketURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, Handler: func(ctx context.Context, incoming []byte) error { - return g.WsHandleFuturesData(ctx, incoming, asset.CoinMarginedFutures) + return e.WsHandleFuturesData(ctx, incoming, asset.CoinMarginedFutures) }, - Subscriber: g.FuturesSubscribe, - Unsubscriber: g.FuturesUnsubscribe, + Subscriber: e.FuturesSubscribe, + Unsubscriber: e.FuturesUnsubscribe, GenerateSubscriptions: func() (subscription.List, error) { - return g.GenerateFuturesDefaultSubscriptions(asset.CoinMarginedFutures) + return e.GenerateFuturesDefaultSubscriptions(asset.CoinMarginedFutures) }, - Connector: g.WsFuturesConnect, + Connector: e.WsFuturesConnect, MessageFilter: asset.CoinMarginedFutures, - BespokeGenerateMessageID: g.GenerateWebsocketMessageID, + BespokeGenerateMessageID: e.GenerateWebsocketMessageID, }) if err != nil { return err @@ -268,45 +268,45 @@ func (g *Gateio) Setup(exch *config.Exchange) error { // TODO: Add BTC margined delivery futures. // Futures connection - Delivery - USDT margined - err = g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: deliveryRealUSDTTradingURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, Handler: func(ctx context.Context, incoming []byte) error { - return g.WsHandleFuturesData(ctx, incoming, asset.DeliveryFutures) + return e.WsHandleFuturesData(ctx, incoming, asset.DeliveryFutures) }, - Subscriber: g.DeliveryFuturesSubscribe, - Unsubscriber: g.DeliveryFuturesUnsubscribe, - GenerateSubscriptions: g.GenerateDeliveryFuturesDefaultSubscriptions, - Connector: g.WsDeliveryFuturesConnect, + Subscriber: e.DeliveryFuturesSubscribe, + Unsubscriber: e.DeliveryFuturesUnsubscribe, + GenerateSubscriptions: e.GenerateDeliveryFuturesDefaultSubscriptions, + Connector: e.WsDeliveryFuturesConnect, MessageFilter: asset.DeliveryFutures, - BespokeGenerateMessageID: g.GenerateWebsocketMessageID, + BespokeGenerateMessageID: e.GenerateWebsocketMessageID, }) if err != nil { return err } // Futures connection - Options - return g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: optionsWebsocketURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, - Handler: g.WsHandleOptionsData, - Subscriber: g.OptionsSubscribe, - Unsubscriber: g.OptionsUnsubscribe, - GenerateSubscriptions: g.GenerateOptionsDefaultSubscriptions, - Connector: g.WsOptionsConnect, + Handler: e.WsHandleOptionsData, + Subscriber: e.OptionsSubscribe, + Unsubscriber: e.OptionsUnsubscribe, + GenerateSubscriptions: e.GenerateOptionsDefaultSubscriptions, + Connector: e.WsOptionsConnect, MessageFilter: asset.Options, - BespokeGenerateMessageID: g.GenerateWebsocketMessageID, + BespokeGenerateMessageID: e.GenerateWebsocketMessageID, }) } // UpdateTicker updates and returns the ticker for a currency pair -func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if !g.SupportsAsset(a) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, a) } - fPair, err := g.FormatExchangeCurrency(p, a) + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } @@ -317,14 +317,14 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item var tickerData *ticker.Price switch a { case asset.Margin, asset.Spot, asset.CrossMargin: - available, err := g.checkInstrumentAvailabilityInSpot(fPair) + available, err := e.checkInstrumentAvailabilityInSpot(fPair) if err != nil { return nil, err } if a != asset.Spot && !available { return nil, fmt.Errorf("%v instrument %v does not have ticker data", a, fPair) } - tickerNew, err := g.GetTicker(ctx, fPair.String(), "") + tickerNew, err := e.GetTicker(ctx, fPair.String(), "") if err != nil { return nil, err } @@ -335,7 +335,7 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item Bid: tickerNew.HighestBid.Float64(), Ask: tickerNew.LowestAsk.Float64(), Last: tickerNew.Last.Float64(), - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: a, } case asset.USDTMarginedFutures, asset.CoinMarginedFutures, asset.DeliveryFutures: @@ -345,9 +345,9 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item } var tickers []FuturesTicker if a == asset.DeliveryFutures { - tickers, err = g.GetDeliveryFutureTickers(ctx, settle, fPair) + tickers, err = e.GetDeliveryFutureTickers(ctx, settle, fPair) } else { - tickers, err = g.GetFuturesTickers(ctx, settle, fPair) + tickers, err = e.GetFuturesTickers(ctx, settle, fPair) } if err != nil { return nil, err @@ -362,17 +362,17 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item Last: tickers[0].Last.Float64(), Volume: tickers[0].Volume24HBase.Float64(), QuoteVolume: tickers[0].Volume24HQuote.Float64(), - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: a, } case asset.Options: var underlying currency.Pair var tickers []OptionsTicker - underlying, err = g.GetUnderlyingFromCurrencyPair(fPair) + underlying, err = e.GetUnderlyingFromCurrencyPair(fPair) if err != nil { return nil, err } - tickers, err = g.GetOptionsTickers(ctx, underlying.String()) + tickers, err = e.GetOptionsTickers(ctx, underlying.String()) if err != nil { return nil, err } @@ -389,7 +389,7 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item Ask: tickers[x].Ask1Price.Float64(), AskSize: tickers[x].Ask1Size, BidSize: tickers[x].Bid1Size, - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: a, } err = ticker.ProcessTicker(tickerData) @@ -397,22 +397,22 @@ func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item return nil, err } } - return ticker.GetTicker(g.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } if err := ticker.ProcessTicker(tickerData); err != nil { return nil, err } - return ticker.GetTicker(g.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !g.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, a) } switch a { case asset.Spot: - tradables, err := g.ListSpotCurrencyPairs(ctx) + tradables, err := e.ListSpotCurrencyPairs(ctx) if err != nil { return nil, err } @@ -422,7 +422,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency continue } p := strings.ToUpper(tradables[x].ID) - if !g.IsValidPairString(p) { + if !e.IsValidPairString(p) { continue } cp, err := currency.NewPairFromString(p) @@ -433,7 +433,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency } return pairs, nil case asset.Margin, asset.CrossMargin: - tradables, err := g.GetMarginSupportedCurrencyPairs(ctx) + tradables, err := e.GetMarginSupportedCurrencyPairs(ctx) if err != nil { return nil, err } @@ -443,7 +443,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency continue } p := strings.ToUpper(tradables[x].Base + currency.UnderscoreDelimiter + tradables[x].Quote) - if !g.IsValidPairString(p) { + if !e.IsValidPairString(p) { continue } cp, err := currency.NewPairFromString(p) @@ -458,7 +458,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency if err != nil { return nil, err } - contracts, err := g.GetAllFutureContracts(ctx, settle) + contracts, err := e.GetAllFutureContracts(ctx, settle) if err != nil { return nil, err } @@ -468,7 +468,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency continue } p := strings.ToUpper(contracts[i].Name) - if !g.IsValidPairString(p) { + if !e.IsValidPairString(p) { continue } cp, err := currency.NewPairFromString(p) @@ -479,7 +479,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency } return slices.Clip(pairs), nil case asset.DeliveryFutures: - contracts, err := g.GetAllDeliveryContracts(ctx, currency.USDT) + contracts, err := e.GetAllDeliveryContracts(ctx, currency.USDT) if err != nil { return nil, err } @@ -489,7 +489,7 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency continue } p := strings.ToUpper(contracts[i].Name) - if !g.IsValidPairString(p) { + if !e.IsValidPairString(p) { continue } cp, err := currency.NewPairFromString(p) @@ -500,18 +500,18 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency } return slices.Clip(pairs), nil case asset.Options: - underlyings, err := g.GetAllOptionsUnderlyings(ctx) + underlyings, err := e.GetAllOptionsUnderlyings(ctx) if err != nil { return nil, err } var pairs []currency.Pair for x := range underlyings { - contracts, err := g.GetAllContractOfUnderlyingWithinExpiryDate(ctx, underlyings[x].Name, time.Time{}) + contracts, err := e.GetAllContractOfUnderlyingWithinExpiryDate(ctx, underlyings[x].Name, time.Time{}) if err != nil { return nil, err } for c := range contracts { - if !g.IsValidPairString(contracts[c].Name) { + if !e.IsValidPairString(contracts[c].Name) { continue } cp, err := currency.NewPairFromString(strings.ReplaceAll(contracts[c].Name, currency.DashDelimiter, currency.UnderscoreDelimiter)) @@ -530,32 +530,32 @@ func (g *Gateio) FetchTradablePairs(ctx context.Context, a asset.Item) (currency // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (g *Gateio) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := g.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.GetAssetTypes(false) for x := range assets { - pairs, err := g.FetchTradablePairs(ctx, assets[x]) + pairs, err := e.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } if len(pairs) == 0 { return errors.New("no tradable pairs found") } - err = g.UpdatePairs(pairs, assets[x], false, forceUpdate) + err = e.UpdatePairs(pairs, assets[x], false, forceUpdate) if err != nil { return err } } - return g.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { - if !g.SupportsAsset(a) { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { return fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, a) } switch a { case asset.Spot, asset.Margin, asset.CrossMargin: - tickers, err := g.GetTickers(ctx, currency.EMPTYPAIR.String(), "") + tickers, err := e.GetTickers(ctx, currency.EMPTYPAIR.String(), "") if err != nil { return err } @@ -573,7 +573,7 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { Ask: tickers[x].LowestAsk.Float64(), QuoteVolume: tickers[x].QuoteVolume.Float64(), Volume: tickers[x].BaseVolume.Float64(), - ExchangeName: g.Name, + ExchangeName: e.Name, Pair: currencyPair, AssetType: a, }) @@ -588,9 +588,9 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { } var tickers []FuturesTicker if a == asset.DeliveryFutures { - tickers, errs = g.GetDeliveryFutureTickers(ctx, settle, currency.EMPTYPAIR) + tickers, errs = e.GetDeliveryFutureTickers(ctx, settle, currency.EMPTYPAIR) } else { - tickers, errs = g.GetFuturesTickers(ctx, settle, currency.EMPTYPAIR) + tickers, errs = e.GetFuturesTickers(ctx, settle, currency.EMPTYPAIR) } for i := range tickers { currencyPair, err := currency.NewPairFromString(tickers[i].Contract) @@ -604,7 +604,7 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { Low: tickers[i].Low24H.Float64(), Volume: tickers[i].Volume24H.Float64(), QuoteVolume: tickers[i].Volume24HQuote.Float64(), - ExchangeName: g.Name, + ExchangeName: e.Name, Pair: currencyPair, AssetType: a, }); err != nil { @@ -613,16 +613,16 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { } return errs case asset.Options: - pairs, err := g.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { return err } for i := range pairs { - underlying, err := g.GetUnderlyingFromCurrencyPair(pairs[i]) + underlying, err := e.GetUnderlyingFromCurrencyPair(pairs[i]) if err != nil { return err } - tickers, err := g.GetOptionsTickers(ctx, underlying.String()) + tickers, err := e.GetOptionsTickers(ctx, underlying.String()) if err != nil { return err } @@ -634,7 +634,7 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { Bid: tickers[x].Bid1Price.Float64(), BidSize: tickers[x].Bid1Size, Pair: tickers[x].Name, - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -649,13 +649,13 @@ func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gateio) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Book, error) { - return g.UpdateOrderbookWithLimit(ctx, p, a, 0) +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Book, error) { + return e.UpdateOrderbookWithLimit(ctx, p, a, 0) } // UpdateOrderbookWithLimit updates and returns the orderbook for a currency pair with a set orderbook size limit -func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, a asset.Item, limit uint64) (*orderbook.Book, error) { - p, err := g.FormatExchangeCurrency(p, a) +func (e *Exchange) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, a asset.Item, limit uint64) (*orderbook.Book, error) { + p, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } @@ -663,25 +663,25 @@ func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, switch a { case asset.Spot, asset.Margin, asset.CrossMargin: var available bool - available, err = g.checkInstrumentAvailabilityInSpot(p) + available, err = e.checkInstrumentAvailabilityInSpot(p) if err != nil { return nil, err } if a != asset.Spot && !available { return nil, fmt.Errorf("%v instrument %v does not have orderbook data", a, p) } - o, err = g.GetOrderbook(ctx, p.String(), "", limit, true) + o, err = e.GetOrderbook(ctx, p.String(), "", limit, true) case asset.CoinMarginedFutures, asset.USDTMarginedFutures: var settle currency.Code settle, err = getSettlementCurrency(p, a) if err != nil { return nil, err } - o, err = g.GetFuturesOrderbook(ctx, settle, p.String(), "", limit, true) + o, err = e.GetFuturesOrderbook(ctx, settle, p.String(), "", limit, true) case asset.DeliveryFutures: - o, err = g.GetDeliveryOrderbook(ctx, currency.USDT, "", p, limit, true) + o, err = e.GetDeliveryOrderbook(ctx, currency.USDT, "", p, limit, true) case asset.Options: - o, err = g.GetOptionsOrderbook(ctx, p, "", limit, true) + o, err = e.GetOptionsOrderbook(ctx, p, "", limit, true) default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } @@ -689,9 +689,9 @@ func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, return nil, err } book := &orderbook.Book{ - Exchange: g.Name, + Exchange: e.Name, Asset: a, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Pair: p.Upper(), LastUpdateID: o.ID, LastUpdated: o.Update.Time(), @@ -715,20 +715,20 @@ func (g *Gateio) UpdateOrderbookWithLimit(ctx context.Context, p currency.Pair, if err != nil { return book, err } - return orderbook.Get(g.Name, book.Pair, a) + return orderbook.Get(e.Name, book.Pair, a) } // UpdateAccountInfo retrieves balances for all enabled currencies for the -func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { info := account.Holdings{ - Exchange: g.Name, + Exchange: e.Name, Accounts: []account.SubAccount{{ AssetType: a, }}, } switch a { case asset.Spot: - balances, err := g.GetSpotAccounts(ctx, currency.EMPTYCODE) + balances, err := e.GetSpotAccounts(ctx, currency.EMPTYCODE) if err != nil { return info, err } @@ -743,7 +743,7 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H } info.Accounts[0].Currencies = currencies case asset.Margin, asset.CrossMargin: - balances, err := g.GetMarginAccountList(ctx, currency.EMPTYPAIR) + balances, err := e.GetMarginAccountList(ctx, currency.EMPTYPAIR) if err != nil { return info, err } @@ -771,9 +771,9 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H } var acc *FuturesAccount if a == asset.DeliveryFutures { - acc, err = g.GetDeliveryFuturesAccounts(ctx, settle) + acc, err = e.GetDeliveryFuturesAccounts(ctx, settle) } else { - acc, err = g.QueryFuturesAccount(ctx, settle) + acc, err = e.QueryFuturesAccount(ctx, settle) } if err != nil { return info, err @@ -785,7 +785,7 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H Free: acc.Available.Float64(), }} case asset.Options: - balance, err := g.GetOptionAccounts(ctx) + balance, err := e.GetOptionAccounts(ctx) if err != nil { return info, err } @@ -798,7 +798,7 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H default: return info, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, a) } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err == nil { err = account.Process(&info, creds) } @@ -807,13 +807,13 @@ func (g *Gateio) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.H // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (g *Gateio) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (g *Gateio) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - records, err := g.GetWithdrawalRecords(ctx, c, time.Time{}, time.Time{}, 0, 0) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + records, err := e.GetWithdrawalRecords(ctx, c, time.Time{}, time.Time{}, 0, 0) if err != nil { return nil, err } @@ -833,8 +833,8 @@ func (g *Gateio) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ a } // GetRecentTrades returns the most recent trades for a currency and asset -func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { - p, err := g.FormatExchangeCurrency(p, a) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { + p, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } @@ -844,7 +844,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - tradeData, err := g.GetMarketTrades(ctx, p, 0, "", false, time.Time{}, time.Time{}, 0) + tradeData, err := e.GetMarketTrades(ctx, p, 0, "", false, time.Time{}, time.Time{}, 0) if err != nil { return nil, err } @@ -855,7 +855,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I return nil, err } resp[i] = trade.Data{ - Exchange: g.Name, + Exchange: e.Name, TID: tradeData[i].OrderID, CurrencyPair: p, AssetType: a, @@ -872,9 +872,9 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I } var futuresTrades []TradingHistoryItem if a == asset.DeliveryFutures { - futuresTrades, err = g.GetDeliveryTradingHistory(ctx, settle, "", p.Upper(), 0, time.Time{}, time.Time{}) + futuresTrades, err = e.GetDeliveryTradingHistory(ctx, settle, "", p.Upper(), 0, time.Time{}, time.Time{}) } else { - futuresTrades, err = g.GetFuturesTradingHistory(ctx, settle, p, 0, 0, "", time.Time{}, time.Time{}) + futuresTrades, err = e.GetFuturesTradingHistory(ctx, settle, p, 0, 0, "", time.Time{}, time.Time{}) } if err != nil { return nil, err @@ -883,7 +883,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I for i := range futuresTrades { resp[i] = trade.Data{ TID: strconv.FormatInt(futuresTrades[i].ID, 10), - Exchange: g.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: futuresTrades[i].Price.Float64(), @@ -892,7 +892,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I } } case asset.Options: - trades, err := g.GetOptionsTradeHistory(ctx, p.Upper(), "", 0, 0, time.Time{}, time.Time{}) + trades, err := e.GetOptionsTradeHistory(ctx, p.Upper(), "", 0, 0, time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -900,7 +900,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I for i := range trades { resp[i] = trade.Data{ TID: strconv.FormatInt(trades[i].ID, 10), - Exchange: g.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: a, Price: trades[i].Price.Float64(), @@ -911,7 +911,7 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I default: return nil, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, a) } - err = g.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -920,19 +920,19 @@ func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.I } // GetHistoricTrades returns historic trade data within the timeframe provided -func (g *Gateio) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // TODO: support multiple order types (IOC) -func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - err := s.Validate(g.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } - s.Pair, err = g.FormatExchangeCurrency(s.Pair, s.AssetType) + s.Pair, err = e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -940,11 +940,11 @@ func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi switch s.AssetType { case asset.Spot, asset.Margin, asset.CrossMargin: - req, err := g.getSpotOrderRequest(s) + req, err := e.getSpotOrderRequest(s) if err != nil { return nil, err } - sOrder, err := g.PlaceSpotOrder(ctx, req) + sOrder, err := e.PlaceSpotOrder(ctx, req) if err != nil { return nil, err } @@ -994,9 +994,9 @@ func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi } var o *Order if s.AssetType == asset.DeliveryFutures { - o, err = g.PlaceDeliveryOrder(ctx, orderParams) + o, err = e.PlaceDeliveryOrder(ctx, orderParams) } else { - o, err = g.PlaceFuturesOrder(ctx, orderParams) + o, err = e.PlaceFuturesOrder(ctx, orderParams) } if err != nil { return nil, err @@ -1020,7 +1020,7 @@ func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi resp.AverageExecutedPrice = o.FillPrice.Float64() return resp, nil case asset.Options: - optionOrder, err := g.PlaceOptionOrder(ctx, &OptionOrderParam{ + optionOrder, err := e.PlaceOptionOrder(ctx, &OptionOrderParam{ Contract: s.Pair.String(), OrderSize: s.Amount, Price: types.Number(s.Price), @@ -1049,33 +1049,33 @@ func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi } // ModifyOrder will allow of changing orderbook placement and limit to market conversion -func (g *Gateio) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (g *Gateio) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - fPair, err := g.FormatExchangeCurrency(o.Pair, o.AssetType) + fPair, err := e.FormatExchangeCurrency(o.Pair, o.AssetType) if err != nil { return err } switch o.AssetType { case asset.Spot, asset.Margin, asset.CrossMargin: - _, err = g.CancelSingleSpotOrder(ctx, o.OrderID, fPair.String(), o.AssetType == asset.CrossMargin) + _, err = e.CancelSingleSpotOrder(ctx, o.OrderID, fPair.String(), o.AssetType == asset.CrossMargin) case asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.DeliveryFutures: var settle currency.Code if settle, err = getSettlementCurrency(o.Pair, o.AssetType); err == nil { if o.AssetType == asset.DeliveryFutures { - _, err = g.CancelSingleDeliveryOrder(ctx, settle, o.OrderID) + _, err = e.CancelSingleDeliveryOrder(ctx, settle, o.OrderID) } else { - _, err = g.CancelSingleFuturesOrder(ctx, settle, o.OrderID) + _, err = e.CancelSingleFuturesOrder(ctx, settle, o.OrderID) } } case asset.Options: - _, err = g.CancelOptionSingleOrder(ctx, o.OrderID) + _, err = e.CancelOptionSingleOrder(ctx, o.OrderID) default: return fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, o.AssetType) } @@ -1083,7 +1083,7 @@ func (g *Gateio) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { response := order.CancelBatchResponse{ Status: map[string]string{}, } @@ -1094,7 +1094,7 @@ func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde var cancelSpotOrdersParam []CancelOrderByIDParam a := o[0].AssetType for x := range o { - o[x].Pair, err = g.FormatExchangeCurrency(o[x].Pair, a) + o[x].Pair, err = e.FormatExchangeCurrency(o[x].Pair, a) if err != nil { return nil, err } @@ -1125,7 +1125,7 @@ func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde input = cancelSpotOrdersParam[count*10 : (count*10)+10] } var cancel []CancelOrderByIDResponse - cancel, err = g.CancelBatchOrdersWithIDList(ctx, input) + cancel, err = e.CancelBatchOrdersWithIDList(ctx, input) if err != nil { return nil, err } @@ -1143,9 +1143,9 @@ func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } var resp []Order if a == asset.DeliveryFutures { - resp, err = g.CancelMultipleDeliveryOrders(ctx, o[i].Pair, o[i].Side.Lower(), settle) + resp, err = e.CancelMultipleDeliveryOrders(ctx, o[i].Pair, o[i].Side.Lower(), settle) } else { - resp, err = g.CancelMultipleFuturesOpenOrders(ctx, o[i].Pair, o[i].Side.Lower(), settle) + resp, err = e.CancelMultipleFuturesOpenOrders(ctx, o[i].Pair, o[i].Side.Lower(), settle) } if err != nil { return nil, err @@ -1156,7 +1156,7 @@ func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } case asset.Options: for i := range o { - cancel, err := g.CancelMultipleOptionOpenOrders(ctx, o[i].Pair, o[i].Pair.String(), o[i].Side.Lower()) + cancel, err := e.CancelMultipleOptionOpenOrders(ctx, o[i].Pair, o[i].Pair.String(), o[i].Side.Lower()) if err != nil { return nil, err } @@ -1171,7 +1171,7 @@ func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde } // CancelAllOrders cancels all orders associated with a currency pair -func (g *Gateio) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) { err := o.Validate() if err != nil { return order.CancelAllResponse{}, err @@ -1184,7 +1184,7 @@ func (g *Gateio) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Ca return order.CancelAllResponse{}, currency.ErrCurrencyPairEmpty } var cancel []SpotPriceTriggeredOrder - cancel, err = g.CancelMultipleSpotOpenOrders(ctx, o.Pair, o.AssetType) + cancel, err = e.CancelMultipleSpotOpenOrders(ctx, o.Pair, o.AssetType) if err != nil { return cancelAllOrdersResponse, err } @@ -1201,9 +1201,9 @@ func (g *Gateio) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Ca } var cancel []Order if o.AssetType == asset.DeliveryFutures { - cancel, err = g.CancelMultipleDeliveryOrders(ctx, o.Pair, o.Side.Lower(), settle) + cancel, err = e.CancelMultipleDeliveryOrders(ctx, o.Pair, o.Side.Lower(), settle) } else { - cancel, err = g.CancelMultipleFuturesOpenOrders(ctx, o.Pair, o.Side.Lower(), settle) + cancel, err = e.CancelMultipleFuturesOpenOrders(ctx, o.Pair, o.Side.Lower(), settle) } if err != nil { return cancelAllOrdersResponse, err @@ -1214,12 +1214,12 @@ func (g *Gateio) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Ca case asset.Options: var underlying currency.Pair if !o.Pair.IsEmpty() { - underlying, err = g.GetUnderlyingFromCurrencyPair(o.Pair) + underlying, err = e.GetUnderlyingFromCurrencyPair(o.Pair) if err != nil { return cancelAllOrdersResponse, err } } - cancel, err := g.CancelMultipleOptionOpenOrders(ctx, o.Pair, underlying.String(), o.Side.Lower()) + cancel, err := e.CancelMultipleOptionOpenOrders(ctx, o.Pair, underlying.String(), o.Side.Lower()) if err != nil { return cancelAllOrdersResponse, err } @@ -1234,19 +1234,19 @@ func (g *Gateio) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Ca } // GetOrderInfo returns order information based on order ID -func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, a asset.Item) (*order.Detail, error) { - if err := g.CurrencyPairs.IsAssetEnabled(a); err != nil { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, a asset.Item) (*order.Detail, error) { + if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil { return nil, err } - pair, err := g.FormatExchangeCurrency(pair, a) + pair, err := e.FormatExchangeCurrency(pair, a) if err != nil { return nil, err } switch a { case asset.Spot, asset.Margin, asset.CrossMargin: var spotOrder *SpotOrder - spotOrder, err = g.GetSpotOrder(ctx, orderID, pair, a) + spotOrder, err = e.GetSpotOrder(ctx, orderID, pair, a) if err != nil { return nil, err } @@ -1267,7 +1267,7 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency } return &order.Detail{ Amount: spotOrder.Amount.Float64(), - Exchange: g.Name, + Exchange: e.Name, OrderID: spotOrder.OrderID, Side: side, Type: orderType, @@ -1287,9 +1287,9 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency } var fOrder *Order if a == asset.DeliveryFutures { - fOrder, err = g.GetSingleDeliveryOrder(ctx, settle, orderID) + fOrder, err = e.GetSingleDeliveryOrder(ctx, settle, orderID) } else { - fOrder, err = g.GetSingleFuturesOrder(ctx, settle, orderID) + fOrder, err = e.GetSingleFuturesOrder(ctx, settle, orderID) } if err != nil { return nil, err @@ -1315,7 +1315,7 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency Amount: amount, ExecutedAmount: amount - remaining, RemainingAmount: remaining, - Exchange: g.Name, + Exchange: e.Name, OrderID: orderID, ClientOrderID: getClientOrderIDFromText(fOrder.Text), Status: orderStatus, @@ -1330,7 +1330,7 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency Side: side, }, nil case asset.Options: - optionOrder, err := g.GetSingleOptionOrder(ctx, orderID) + optionOrder, err := e.GetSingleOptionOrder(ctx, orderID) if err != nil { return nil, err } @@ -1345,7 +1345,7 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency return &order.Detail{ Amount: optionOrder.Size, ExecutedAmount: optionOrder.Size - optionOrder.Left, - Exchange: g.Name, + Exchange: e.Name, OrderID: orderID, Status: orderStatus, Price: optionOrder.Price.Float64(), @@ -1360,8 +1360,8 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency } // GetDepositAddress returns a deposit address for a specified currency -func (g *Gateio) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { - addr, err := g.GenerateCurrencyDepositAddress(ctx, cryptocurrency) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { + addr, err := e.GenerateCurrencyDepositAddress(ctx, cryptocurrency) if err != nil { return nil, err } @@ -1388,11 +1388,11 @@ func (g *Gateio) GetDepositAddress(ctx context.Context, cryptocurrency currency. // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (g *Gateio) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - response, err := g.WithdrawCurrency(ctx, + response, err := e.WithdrawCurrency(ctx, WithdrawalRequestParam{ Amount: types.Number(withdrawRequest.Amount), Currency: withdrawRequest.Currency, @@ -1410,41 +1410,41 @@ func (g *Gateio) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted -func (g *Gateio) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (g *Gateio) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (g *Gateio) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !g.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return g.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail - format, err := g.GetPairFormat(req.AssetType, false) + format, err := e.GetPairFormat(req.AssetType, false) if err != nil { return nil, err } switch req.AssetType { case asset.Spot, asset.Margin, asset.CrossMargin: - spotOrders, err := g.GetSpotOpenOrders(ctx, 0, 0, req.AssetType == asset.CrossMargin) + spotOrders, err := e.GetSpotOpenOrders(ctx, 0, 0, req.AssetType == asset.CrossMargin) if err != nil { return nil, err } @@ -1459,7 +1459,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } side, err := order.StringToOrderSide(spotOrders[x].Orders[y].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", g.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } oType, err := order.StringToOrderType(spotOrders[x].Orders[y].Type) if err != nil { @@ -1467,7 +1467,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } status, err := order.StringToOrderStatus(spotOrders[x].Orders[y].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", g.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders = append(orders, order.Detail{ Side: side, @@ -1482,7 +1482,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque AverageExecutedPrice: spotOrders[x].Orders[y].AverageFillPrice.Float64(), Date: spotOrders[x].Orders[y].CreateTime.Time(), LastUpdated: spotOrders[x].Orders[y].UpdateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, AssetType: req.AssetType, ClientOrderID: spotOrders[x].Orders[y].Text, FeeAsset: currency.NewCode(spotOrders[x].Orders[y].FeeCurrency), @@ -1496,9 +1496,9 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } var futuresOrders []Order if req.AssetType == asset.DeliveryFutures { - futuresOrders, err = g.GetDeliveryOrders(ctx, currency.EMPTYPAIR, statusOpen, settle, "", 0, 0, 0) + futuresOrders, err = e.GetDeliveryOrders(ctx, currency.EMPTYPAIR, statusOpen, settle, "", 0, 0, 0) } else { - futuresOrders, err = g.GetFuturesOrders(ctx, currency.EMPTYPAIR, statusOpen, "", settle, 0, 0, 0) + futuresOrders, err = e.GetFuturesOrders(ctx, currency.EMPTYPAIR, statusOpen, "", settle, 0, 0, 0) } if err != nil { return nil, err @@ -1529,7 +1529,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque RemainingAmount: remaining, LastUpdated: futuresOrders[i].FinishTime.Time(), Date: futuresOrders[i].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, AssetType: req.AssetType, Side: side, Type: order.Limit, @@ -1541,7 +1541,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque } case asset.Options: var optionsOrders []OptionOrderResponse - optionsOrders, err = g.GetOptionFuturesOrders(ctx, currency.EMPTYPAIR, "", statusOpen, 0, 0, req.StartTime, req.EndTime) + optionsOrders, err = e.GetOptionFuturesOrders(ctx, currency.EMPTYPAIR, "", statusOpen, 0, 0, req.StartTime, req.EndTime) if err != nil { return nil, err } @@ -1566,7 +1566,7 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque RemainingAmount: optionsOrders[i].Left, LastUpdated: optionsOrders[i].FinishTime.Time(), Date: optionsOrders[i].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, AssetType: req.AssetType, ClientOrderID: optionsOrders[i].Text, }) @@ -1574,17 +1574,17 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque default: return nil, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, req.AssetType) } - return req.Filter(g.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail - format, err := g.GetPairFormat(req.AssetType, true) + format, err := e.GetPairFormat(req.AssetType, true) if err != nil { return nil, err } @@ -1592,7 +1592,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque case asset.Spot, asset.Margin, asset.CrossMargin: for x := range req.Pairs { fPair := req.Pairs[x].Format(format) - spotOrders, err := g.GetMySpotTradingHistory(ctx, fPair, req.FromOrderID, 0, 0, req.AssetType == asset.CrossMargin, req.StartTime, req.EndTime) + spotOrders, err := e.GetMySpotTradingHistory(ctx, fPair, req.FromOrderID, 0, 0, req.AssetType == asset.CrossMargin, req.StartTime, req.EndTime) if err != nil { return nil, err } @@ -1609,7 +1609,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque Price: spotOrders[o].Price.Float64(), Date: spotOrders[o].CreateTime.Time(), Side: side, - Exchange: g.Name, + Exchange: e.Name, Pair: fPair, AssetType: req.AssetType, Fee: spotOrders[o].Fee.Float64(), @@ -1628,9 +1628,9 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque } var futuresOrder []TradingHistoryItem if req.AssetType == asset.DeliveryFutures { - futuresOrder, err = g.GetMyDeliveryTradingHistory(ctx, settle, req.FromOrderID, fPair, 0, 0, 0, "") + futuresOrder, err = e.GetMyDeliveryTradingHistory(ctx, settle, req.FromOrderID, fPair, 0, 0, 0, "") } else { - futuresOrder, err = g.GetMyFuturesTradingHistory(ctx, settle, "", req.FromOrderID, fPair, 0, 0, 0) + futuresOrder, err = e.GetMyFuturesTradingHistory(ctx, settle, "", req.FromOrderID, fPair, 0, 0, 0) } if err != nil { return nil, err @@ -1641,7 +1641,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque Amount: futuresOrder[o].Size, Price: futuresOrder[o].Price.Float64(), Date: futuresOrder[o].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, Pair: fPair, AssetType: req.AssetType, } @@ -1652,7 +1652,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque case asset.Options: for x := range req.Pairs { fPair := req.Pairs[x].Format(format) - optionOrders, err := g.GetMyOptionsTradingHistory(ctx, fPair.String(), fPair.Upper(), 0, 0, req.StartTime, req.EndTime) + optionOrders, err := e.GetMyOptionsTradingHistory(ctx, fPair.String(), fPair.Upper(), 0, 0, req.StartTime, req.EndTime) if err != nil { return nil, err } @@ -1662,7 +1662,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque Amount: optionOrders[o].Size, Price: optionOrders[o].Price.Float64(), Date: optionOrders[o].CreateTime.Time(), - Exchange: g.Name, + Exchange: e.Name, Pair: fPair, AssetType: req.AssetType, } @@ -1673,19 +1673,19 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque default: return nil, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, req.AssetType) } - return req.Filter(g.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetHistoricCandles returns candles between a time period for a set time interval -func (g *Gateio) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := g.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } var listCandlesticks []kline.Candle switch a { case asset.Spot, asset.Margin, asset.CrossMargin: - candles, err := g.GetCandlesticks(ctx, req.RequestFormatted, 0, start, end, interval) + candles, err := e.GetCandlesticks(ctx, req.RequestFormatted, 0, start, end, interval) if err != nil { return nil, err } @@ -1707,9 +1707,9 @@ func (g *Gateio) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a } var candles []FuturesCandlestick if a == asset.DeliveryFutures { - candles, err = g.GetDeliveryFuturesCandlesticks(ctx, settle, req.RequestFormatted.Upper(), start, end, 0, interval) + candles, err = e.GetDeliveryFuturesCandlesticks(ctx, settle, req.RequestFormatted.Upper(), start, end, 0, interval) } else { - candles, err = g.GetFuturesCandlesticks(ctx, settle, req.RequestFormatted.String(), start, end, 0, interval) + candles, err = e.GetFuturesCandlesticks(ctx, settle, req.RequestFormatted.String(), start, end, 0, interval) } if err != nil { return nil, err @@ -1732,8 +1732,8 @@ func (g *Gateio) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (g *Gateio) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := g.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1741,7 +1741,7 @@ func (g *Gateio) GetHistoricCandlesExtended(ctx context.Context, pair currency.P for _, r := range req.RangeHolder.Ranges { switch a { case asset.Spot, asset.Margin, asset.CrossMargin: - candles, err := g.GetCandlesticks(ctx, req.RequestFormatted, 0, r.Start.Time, r.End.Time, interval) + candles, err := e.GetCandlesticks(ctx, req.RequestFormatted, 0, r.Start.Time, r.End.Time, interval) if err != nil { return nil, err } @@ -1762,9 +1762,9 @@ func (g *Gateio) GetHistoricCandlesExtended(ctx context.Context, pair currency.P } var candles []FuturesCandlestick if a == asset.DeliveryFutures { - candles, err = g.GetDeliveryFuturesCandlesticks(ctx, settle, req.RequestFormatted.Upper(), r.Start.Time, r.End.Time, 0, interval) + candles, err = e.GetDeliveryFuturesCandlesticks(ctx, settle, req.RequestFormatted.Upper(), r.Start.Time, r.End.Time, 0, interval) } else { - candles, err = g.GetFuturesCandlesticks(ctx, settle, req.RequestFormatted.String(), r.Start.Time, r.End.Time, 0, interval) + candles, err = e.GetFuturesCandlesticks(ctx, settle, req.RequestFormatted.String(), r.Start.Time, r.End.Time, 0, interval) } if err != nil { return nil, err @@ -1786,10 +1786,9 @@ func (g *Gateio) GetHistoricCandlesExtended(ctx context.Context, pair currency.P return req.ProcessResponse(candlestickItems) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (g *Gateio) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - chains, err := g.ListCurrencyChain(ctx, cryptocurrency.Upper()) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + chains, err := e.ListCurrencyChain(ctx, cryptocurrency.Upper()) if err != nil { return nil, err } @@ -1804,15 +1803,15 @@ func (g *Gateio) GetAvailableTransferChains(ctx context.Context, cryptocurrency // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (g *Gateio) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := g.UpdateAccountInfo(ctx, assetType) - return g.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // checkInstrumentAvailabilityInSpot checks whether the instrument is available in the spot exchange // if so we can use the instrument to retrieve orderbook and ticker information using the spot endpoints. -func (g *Gateio) checkInstrumentAvailabilityInSpot(instrument currency.Pair) (bool, error) { - availables, err := g.CurrencyPairs.GetPairs(asset.Spot, false) +func (e *Exchange) checkInstrumentAvailabilityInSpot(instrument currency.Pair) (bool, error) { + availables, err := e.CurrencyPairs.GetPairs(asset.Spot, false) if err != nil { return false, err } @@ -1820,11 +1819,11 @@ func (g *Gateio) checkInstrumentAvailabilityInSpot(instrument currency.Pair) (bo } // GetFuturesContractDetails returns details about futures contracts -func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([]futures.Contract, error) { if !a.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !g.SupportsAsset(a) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } settle, err := getSettlementCurrency(currency.EMPTYPAIR, a) @@ -1833,7 +1832,7 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([ } switch a { case asset.CoinMarginedFutures, asset.USDTMarginedFutures: - contracts, err := g.GetAllFutureContracts(ctx, settle) + contracts, err := e.GetAllFutureContracts(ctx, settle) if err != nil { return nil, err } @@ -1851,7 +1850,7 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([ contractSettlementType = futures.Quanto } c := futures.Contract{ - Exchange: g.Name, + Exchange: e.Name, Name: name, Underlying: name, Asset: a, @@ -1870,7 +1869,7 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([ } return resp, nil case asset.DeliveryFutures: - contracts, err := g.GetAllDeliveryContracts(ctx, settle) + contracts, err := e.GetAllDeliveryContracts(ctx, settle) if err != nil { return nil, err } @@ -1886,30 +1885,30 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([ } // no start information, inferring it based on contract type // gateio also reuses contracts for kline data, cannot use a lookup to see the first trade - var s time.Time - e := contracts[i].ExpireTime.Time() + var startTime time.Time + endTime := contracts[i].ExpireTime.Time() ct := futures.LongDated switch contracts[i].Cycle { case "WEEKLY": ct = futures.Weekly - s = e.Add(-kline.OneWeek.Duration()) + startTime = endTime.Add(-kline.OneWeek.Duration()) case "BI-WEEKLY": ct = futures.Fortnightly - s = e.Add(-kline.TwoWeek.Duration()) + startTime = endTime.Add(-kline.TwoWeek.Duration()) case "QUARTERLY": ct = futures.Quarterly - s = e.Add(-kline.ThreeMonth.Duration()) + startTime = endTime.Add(-kline.ThreeMonth.Duration()) case "BI-QUARTERLY": ct = futures.HalfYearly - s = e.Add(-kline.SixMonth.Duration()) + startTime = endTime.Add(-kline.SixMonth.Duration()) } resp[i] = futures.Contract{ - Exchange: g.Name, + Exchange: e.Name, Name: name, Underlying: underlying, Asset: a, - StartDate: s, - EndDate: e, + StartDate: startTime, + EndDate: endTime, SettlementType: futures.Linear, IsActive: !contracts[i].InDelisting, Type: ct, @@ -1925,15 +1924,15 @@ func (g *Gateio) GetFuturesContractDetails(ctx context.Context, a asset.Item) ([ } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (g *Gateio) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { - if !g.SupportsAsset(a) { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { return fmt.Errorf("%s %w", a, asset.ErrNotSupported) } var limits []order.MinMaxLevel switch a { case asset.Spot: - pairsData, err := g.ListSpotCurrencyPairs(ctx) + pairsData, err := e.ListSpotCurrencyPairs(ctx) if err != nil { return err } @@ -1943,7 +1942,7 @@ func (g *Gateio) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e if pairsData[i].TradeStatus == "untradable" { continue } - pair, err := g.MatchSymbolWithAvailablePairs(pairsData[i].ID, a, true) + pair, err := e.MatchSymbolWithAvailablePairs(pairsData[i].ID, a, true) if err != nil { return err } @@ -1969,11 +1968,11 @@ func (g *Gateio) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e return fmt.Errorf("%s %w", a, common.ErrNotYetImplemented) } - return g.LoadLimits(limits) + return e.LoadLimits(limits) } // GetHistoricalFundingRates returns historical funding rates for a futures contract -func (g *Gateio) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { +func (e *Exchange) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -2006,12 +2005,12 @@ func (g *Gateio) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.H return nil, fmt.Errorf("include predicted rate %w", common.ErrNotYetImplemented) } - fPair, err := g.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } - records, err := g.GetFutureFundingRates(ctx, r.PaymentCurrency, fPair, 1000) + records, err := e.GetFutureFundingRates(ctx, r.PaymentCurrency, fPair, 1000) if err != nil { return nil, err } @@ -2042,7 +2041,7 @@ func (g *Gateio) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.H } return &fundingrate.HistoricalRates{ - Exchange: g.Name, + Exchange: e.Name, Asset: r.Asset, Pair: r.Pair, FundingRates: fundingRates, @@ -2054,7 +2053,7 @@ func (g *Gateio) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.H } // GetLatestFundingRates returns the latest funding rates data -func (g *Gateio) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -2068,32 +2067,32 @@ func (g *Gateio) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } if !r.Pair.IsEmpty() { - fPair, err := g.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } - contract, err := g.GetFuturesContract(ctx, settle, fPair.String()) + contract, err := e.GetFuturesContract(ctx, settle, fPair.String()) if err != nil { return nil, err } return []fundingrate.LatestRateResponse{ - contractToFundingRate(g.Name, r.Asset, fPair, contract, r.IncludePredictedRate), + contractToFundingRate(e.Name, r.Asset, fPair, contract, r.IncludePredictedRate), }, nil } - pairs, err := g.GetEnabledPairs(r.Asset) + pairs, err := e.GetEnabledPairs(r.Asset) if err != nil { return nil, err } - contracts, err := g.GetAllFutureContracts(ctx, settle) + contracts, err := e.GetAllFutureContracts(ctx, settle) if err != nil { return nil, err } resp := make([]fundingrate.LatestRateResponse, 0, len(contracts)) for i := range contracts { p := strings.ToUpper(contracts[i].Name) - if !g.IsValidPairString(p) { + if !e.IsValidPairString(p) { continue } cp, err := currency.NewPairFromString(p) @@ -2103,7 +2102,7 @@ func (g *Gateio) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates if !pairs.Contains(cp, false) { continue } - resp = append(resp, contractToFundingRate(g.Name, r.Asset, cp, &contracts[i], r.IncludePredictedRate)) + resp = append(resp, contractToFundingRate(e.Name, r.Asset, cp, &contracts[i], r.IncludePredictedRate)) } return slices.Clip(resp), nil @@ -2131,14 +2130,14 @@ func contractToFundingRate(name string, item asset.Item, fPair currency.Pair, co } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (g *Gateio) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { return a == asset.CoinMarginedFutures || a == asset.USDTMarginedFutures, nil } // GetOpenInterest returns the open interest rate for a given asset pair // If no pairs are provided, all enabled assets and pairs will be used // If keys are provided, those asset pairs only need to be available, not enabled -func (g *Gateio) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([]futures.OpenInterest, error) { var errs error resp := make([]futures.OpenInterest, 0, len(keys)) assets := asset.Items{} @@ -2154,24 +2153,24 @@ func (g *Gateio) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([] for _, a := range assets { var p currency.Pair if len(keys) == 1 && a == keys[0].Asset { - if p, errs = g.MatchSymbolWithAvailablePairs(keys[0].Pair().String(), a, false); errs != nil { + if p, errs = e.MatchSymbolWithAvailablePairs(keys[0].Pair().String(), a, false); errs != nil { return nil, errs } } - contracts, err := g.getOpenInterestContracts(ctx, a, p) + contracts, err := e.getOpenInterestContracts(ctx, a, p) if err != nil { errs = common.AppendError(errs, fmt.Errorf("%w fetching %s", err, a)) continue } for _, c := range contracts { if p.IsEmpty() { // If not exactly one key provided - p, err = g.MatchSymbolWithAvailablePairs(c.contractName(), a, true) + p, err = e.MatchSymbolWithAvailablePairs(c.contractName(), a, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { errs = common.AppendError(errs, fmt.Errorf("%w from %s contract %s", err, a, c.contractName())) continue } if len(keys) == 0 { // No keys: All enabled pairs - if enabled, err := g.IsPairEnabled(p, a); err != nil { + if enabled, err := e.IsPairEnabled(p, a); err != nil { errs = common.AppendError(errs, fmt.Errorf("%w: %s %s", err, a, p)) continue } else if !enabled { @@ -2185,7 +2184,7 @@ func (g *Gateio) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([] } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: g.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, @@ -2222,17 +2221,17 @@ func (c *DeliveryContract) contractName() string { return c.Name } -func (g *Gateio) getOpenInterestContracts(ctx context.Context, a asset.Item, p currency.Pair) ([]openInterestContract, error) { +func (e *Exchange) getOpenInterestContracts(ctx context.Context, a asset.Item, p currency.Pair) ([]openInterestContract, error) { settle, err := getSettlementCurrency(p, a) if err != nil { return nil, err } if a == asset.DeliveryFutures { if p != currency.EMPTYPAIR { - d, err := g.GetDeliveryContract(ctx, settle, p) + d, err := e.GetDeliveryContract(ctx, settle, p) return []openInterestContract{d}, err } - d, err := g.GetAllDeliveryContracts(ctx, settle) + d, err := e.GetAllDeliveryContracts(ctx, settle) contracts := make([]openInterestContract, len(d)) for i := range d { contracts[i] = &d[i] @@ -2240,10 +2239,10 @@ func (g *Gateio) getOpenInterestContracts(ctx context.Context, a asset.Item, p c return contracts, err } if p != currency.EMPTYPAIR { - contract, err := g.GetFuturesContract(ctx, settle, p.String()) + contract, err := e.GetFuturesContract(ctx, settle, p.String()) return []openInterestContract{contract}, err } - fc, err := g.GetAllFutureContracts(ctx, settle) + fc, err := e.GetAllFutureContracts(ctx, settle) contracts := make([]openInterestContract, len(fc)) for i := range fc { contracts[i] = &fc[i] @@ -2295,8 +2294,8 @@ func getFutureOrderSize(s *order.Submit) (float64, error) { } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (g *Gateio) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := g.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } @@ -2320,13 +2319,13 @@ func (g *Gateio) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currenc // WebsocketSubmitOrder submits an order to the exchange // NOTE: Regarding spot orders, fee is applied to purchased currency. -func (g *Gateio) WebsocketSubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - err := s.Validate(g.GetTradingRequirements()) +func (e *Exchange) WebsocketSubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } - s.Pair, err = g.FormatExchangeCurrency(s.Pair, s.AssetType) + s.Pair, err = e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -2334,23 +2333,23 @@ func (g *Gateio) WebsocketSubmitOrder(ctx context.Context, s *order.Submit) (*or switch s.AssetType { case asset.Spot: - req, err := g.getSpotOrderRequest(s) + req, err := e.getSpotOrderRequest(s) if err != nil { return nil, err } - resp, err := g.WebsocketSpotSubmitOrder(ctx, req) + resp, err := e.WebsocketSpotSubmitOrder(ctx, req) if err != nil { return nil, err } - return g.deriveSpotWebsocketOrderResponse(resp) + return e.deriveSpotWebsocketOrderResponse(resp) case asset.CoinMarginedFutures, asset.USDTMarginedFutures: amountWithDirection, err := getFutureOrderSize(s) if err != nil { return nil, err } - resp, err := g.WebsocketFuturesSubmitOrder(ctx, s.AssetType, &ContractOrderCreateParams{ + resp, err := e.WebsocketFuturesSubmitOrder(ctx, s.AssetType, &ContractOrderCreateParams{ Contract: s.Pair, Size: amountWithDirection, Price: strconv.FormatFloat(s.Price, 'f', -1, 64), @@ -2361,7 +2360,7 @@ func (g *Gateio) WebsocketSubmitOrder(ctx context.Context, s *order.Submit) (*or if err != nil { return nil, err } - return g.deriveFuturesWebsocketOrderResponse(resp) + return e.deriveFuturesWebsocketOrderResponse(resp) default: return nil, common.ErrNotYetImplemented } @@ -2385,8 +2384,8 @@ func timeInForceString(tif order.TimeInForce) string { } } -func (g *Gateio) deriveSpotWebsocketOrderResponse(responses *WebsocketOrderResponse) (*order.SubmitResponse, error) { - resp, err := g.deriveSpotWebsocketOrderResponses([]*WebsocketOrderResponse{responses}) +func (e *Exchange) deriveSpotWebsocketOrderResponse(responses *WebsocketOrderResponse) (*order.SubmitResponse, error) { + resp, err := e.deriveSpotWebsocketOrderResponses([]*WebsocketOrderResponse{responses}) if err != nil { return nil, err } @@ -2394,7 +2393,7 @@ func (g *Gateio) deriveSpotWebsocketOrderResponse(responses *WebsocketOrderRespo } // deriveSpotWebsocketOrderResponses returns the order submission responses for spot -func (g *Gateio) deriveSpotWebsocketOrderResponses(responses []*WebsocketOrderResponse) ([]*order.SubmitResponse, error) { +func (e *Exchange) deriveSpotWebsocketOrderResponses(responses []*WebsocketOrderResponse) ([]*order.SubmitResponse, error) { if len(responses) == 0 { return nil, common.ErrNoResponse } @@ -2433,7 +2432,7 @@ func (g *Gateio) deriveSpotWebsocketOrderResponses(responses []*WebsocketOrderRe return nil, err } out = append(out, &order.SubmitResponse{ - Exchange: g.Name, + Exchange: e.Name, OrderID: resp.ID, AssetType: resp.Account, Pair: resp.CurrencyPair, @@ -2457,8 +2456,8 @@ func (g *Gateio) deriveSpotWebsocketOrderResponses(responses []*WebsocketOrderRe return out, nil } -func (g *Gateio) deriveFuturesWebsocketOrderResponse(responses *WebsocketFuturesOrderResponse) (*order.SubmitResponse, error) { - resp, err := g.deriveFuturesWebsocketOrderResponses([]*WebsocketFuturesOrderResponse{responses}) +func (e *Exchange) deriveFuturesWebsocketOrderResponse(responses *WebsocketFuturesOrderResponse) (*order.SubmitResponse, error) { + resp, err := e.deriveFuturesWebsocketOrderResponses([]*WebsocketFuturesOrderResponse{responses}) if err != nil { return nil, err } @@ -2466,7 +2465,7 @@ func (g *Gateio) deriveFuturesWebsocketOrderResponse(responses *WebsocketFutures } // deriveFuturesWebsocketOrderResponses returns the order submission responses for futures -func (g *Gateio) deriveFuturesWebsocketOrderResponses(responses []*WebsocketFuturesOrderResponse) ([]*order.SubmitResponse, error) { +func (e *Exchange) deriveFuturesWebsocketOrderResponses(responses []*WebsocketFuturesOrderResponse) ([]*order.SubmitResponse, error) { if len(responses) == 0 { return nil, common.ErrNoResponse } @@ -2501,7 +2500,7 @@ func (g *Gateio) deriveFuturesWebsocketOrderResponses(responses []*WebsocketFutu return nil, err } out = append(out, &order.SubmitResponse{ - Exchange: g.Name, + Exchange: e.Name, OrderID: strconv.FormatInt(resp.ID, 10), AssetType: asset.Futures, Pair: resp.Contract, @@ -2522,7 +2521,7 @@ func (g *Gateio) deriveFuturesWebsocketOrderResponses(responses []*WebsocketFutu return out, nil } -func (g *Gateio) getSpotOrderRequest(s *order.Submit) (*CreateOrderRequest, error) { +func (e *Exchange) getSpotOrderRequest(s *order.Submit) (*CreateOrderRequest, error) { switch { case s.Side.IsLong(): s.Side = order.Buy @@ -2543,8 +2542,8 @@ func (g *Gateio) getSpotOrderRequest(s *order.Submit) (*CreateOrderRequest, erro return &CreateOrderRequest{ Side: s.Side.Lower(), Type: s.Type.Lower(), - Account: g.assetTypeToString(s.AssetType), - Amount: types.Number(s.GetTradeAmount(g.GetTradingRequirements())), + Account: e.assetTypeToString(s.AssetType), + Amount: types.Number(s.GetTradeAmount(e.GetTradingRequirements())), Price: types.Number(s.Price), CurrencyPair: s.Pair, Text: s.ClientOrderID, diff --git a/exchanges/gateio/ws_ob_update_manager.go b/exchanges/gateio/ws_ob_update_manager.go index b6ee2ab65b5..5f559436c24 100644 --- a/exchanges/gateio/ws_ob_update_manager.go +++ b/exchanges/gateio/ws_ob_update_manager.go @@ -40,7 +40,7 @@ func newWsOBUpdateManager(snapshotSyncDelay time.Duration) *wsOBUpdateManager { } // ProcessOrderbookUpdate processes an orderbook update by syncing snapshot, caching updates and applying them -func (m *wsOBUpdateManager) ProcessOrderbookUpdate(ctx context.Context, g *Gateio, firstUpdateID int64, update *orderbook.Update) error { +func (m *wsOBUpdateManager) ProcessOrderbookUpdate(ctx context.Context, g *Exchange, firstUpdateID int64, update *orderbook.Update) error { cache := m.LoadCache(update.Pair, update.Asset) cache.mtx.Lock() defer cache.mtx.Unlock() @@ -97,7 +97,7 @@ func (m *wsOBUpdateManager) LoadCache(p currency.Pair, a asset.Item) *updateCach // SyncOrderbook fetches and synchronises an orderbook snapshot to the limit size so that pending updates can be // applied to the orderbook. -func (c *updateCache) SyncOrderbook(ctx context.Context, g *Gateio, pair currency.Pair, a asset.Item) error { +func (c *updateCache) SyncOrderbook(ctx context.Context, g *Exchange, pair currency.Pair, a asset.Item) error { // TODO: When subscription config is added for all assets update limits to use sub.Levels var limit uint64 switch a { @@ -150,7 +150,7 @@ func (c *updateCache) SyncOrderbook(ctx context.Context, g *Gateio, pair currenc } // ApplyPendingUpdates applies all pending updates to the orderbook -func (c *updateCache) applyPendingUpdates(g *Gateio, a asset.Item) error { +func (c *updateCache) applyPendingUpdates(g *Exchange, a asset.Item) error { for _, data := range c.updates { lastUpdateID, err := g.Websocket.Orderbook.LastUpdateID(data.update.Pair, a) if err != nil { @@ -171,7 +171,7 @@ func (c *updateCache) applyPendingUpdates(g *Gateio, a asset.Item) error { } // applyOrderbookUpdate applies an orderbook update to the orderbook -func applyOrderbookUpdate(g *Gateio, update *orderbook.Update) error { +func applyOrderbookUpdate(g *Exchange, update *orderbook.Update) error { if update.Asset != asset.Spot { return g.Websocket.Orderbook.Update(update) } diff --git a/exchanges/gateio/ws_ob_update_manager_test.go b/exchanges/gateio/ws_ob_update_manager_test.go index b5f401af0c6..5c2ca326e8f 100644 --- a/exchanges/gateio/ws_ob_update_manager_test.go +++ b/exchanges/gateio/ws_ob_update_manager_test.go @@ -18,12 +18,12 @@ func TestProcessOrderbookUpdate(t *testing.T) { t.Parallel() m := newWsOBUpdateManager(0) - err := m.ProcessOrderbookUpdate(t.Context(), g, 1337, &orderbook.Update{}) + err := m.ProcessOrderbookUpdate(t.Context(), e, 1337, &orderbook.Update{}) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) pair := currency.NewPair(currency.BABY, currency.BABYDOGE) - err = g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: g.Name, + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, Pair: pair, Asset: asset.USDTMarginedFutures, Bids: []orderbook.Level{{Price: 1, Amount: 1}}, @@ -34,7 +34,7 @@ func TestProcessOrderbookUpdate(t *testing.T) { }) require.NoError(t, err) - err = m.ProcessOrderbookUpdate(t.Context(), g, 1337, &orderbook.Update{ + err = m.ProcessOrderbookUpdate(t.Context(), e, 1337, &orderbook.Update{ UpdateID: 1338, Pair: pair, Asset: asset.USDTMarginedFutures, @@ -44,7 +44,7 @@ func TestProcessOrderbookUpdate(t *testing.T) { require.NoError(t, err) // Test orderbook snapshot is behind update - err = m.ProcessOrderbookUpdate(t.Context(), g, 1340, &orderbook.Update{ + err = m.ProcessOrderbookUpdate(t.Context(), e, 1340, &orderbook.Update{ UpdateID: 1341, Pair: pair, Asset: asset.USDTMarginedFutures, @@ -61,7 +61,7 @@ func TestProcessOrderbookUpdate(t *testing.T) { cache.mtx.Unlock() // Test orderbook snapshot is behind update - err = m.ProcessOrderbookUpdate(t.Context(), g, 1342, &orderbook.Update{ + err = m.ProcessOrderbookUpdate(t.Context(), e, 1342, &orderbook.Update{ UpdateID: 1343, Pair: pair, Asset: asset.USDTMarginedFutures, @@ -100,25 +100,25 @@ func TestLoadCache(t *testing.T) { func TestSyncOrderbook(t *testing.T) { t.Parallel() - g := new(Gateio) - require.NoError(t, testexch.Setup(g), "Setup must not error") - require.NoError(t, g.UpdateTradablePairs(t.Context(), false)) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Setup must not error") + require.NoError(t, e.UpdateTradablePairs(t.Context(), false)) // Add dummy subscription so that it can be matched and a limit/level can be extracted for initial orderbook sync spot. - err := g.Websocket.AddSubscriptions(nil, &subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.HundredMilliseconds}) + err := e.Websocket.AddSubscriptions(nil, &subscription.Subscription{Channel: subscription.OrderbookChannel, Interval: kline.HundredMilliseconds}) require.NoError(t, err) m := newWsOBUpdateManager(defaultWSSnapshotSyncDelay) for _, a := range []asset.Item{asset.Spot, asset.USDTMarginedFutures} { pair := currency.NewPair(currency.ETH, currency.USDT) - err := g.CurrencyPairs.EnablePair(a, pair) + err := e.CurrencyPairs.EnablePair(a, pair) require.NoError(t, err) cache := m.LoadCache(pair, a) cache.updates = []pendingUpdate{{update: &orderbook.Update{Pair: pair, Asset: a}}} cache.updating = true - err = cache.SyncOrderbook(t.Context(), g, pair, a) + err = cache.SyncOrderbook(t.Context(), e, pair, a) require.NoError(t, err) require.False(t, cache.updating) require.Empty(t, cache.updates) @@ -128,7 +128,7 @@ func TestSyncOrderbook(t *testing.T) { expectedLimit = 100 } - b, err := g.Websocket.Orderbook.GetOrderbook(pair, a) + b, err := e.Websocket.Orderbook.GetOrderbook(pair, a) require.NoError(t, err) require.Len(t, b.Bids, expectedLimit) require.Len(t, b.Asks, expectedLimit) @@ -138,14 +138,14 @@ func TestSyncOrderbook(t *testing.T) { func TestApplyPendingUpdates(t *testing.T) { t.Parallel() - g := new(Gateio) - require.NoError(t, testexch.Setup(g), "Setup must not error") - require.NoError(t, g.UpdateTradablePairs(t.Context(), false)) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Setup must not error") + require.NoError(t, e.UpdateTradablePairs(t.Context(), false)) m := newWsOBUpdateManager(defaultWSSnapshotSyncDelay) pair := currency.NewPair(currency.LTC, currency.USDT) - err := g.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: g.Name, + err := e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, Pair: pair, Asset: asset.USDTMarginedFutures, Bids: []orderbook.Level{{Price: 1, Amount: 1}}, @@ -167,20 +167,20 @@ func TestApplyPendingUpdates(t *testing.T) { } cache.updates = []pendingUpdate{{update: update, firstUpdateID: 1337}} - err = cache.applyPendingUpdates(g, asset.USDTMarginedFutures) + err = cache.applyPendingUpdates(e, asset.USDTMarginedFutures) require.ErrorIs(t, err, errOrderbookSnapshotOutdated) cache.updates[0].firstUpdateID = 1336 - err = cache.applyPendingUpdates(g, asset.USDTMarginedFutures) + err = cache.applyPendingUpdates(e, asset.USDTMarginedFutures) require.NoError(t, err) } func TestApplyOrderbookUpdate(t *testing.T) { t.Parallel() - g := new(Gateio) - require.NoError(t, testexch.Setup(g), "Setup must not error") - require.NoError(t, g.UpdateTradablePairs(t.Context(), false)) + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Setup must not error") + require.NoError(t, e.UpdateTradablePairs(t.Context(), false)) pair := currency.NewBTCUSDT() @@ -191,14 +191,14 @@ func TestApplyOrderbookUpdate(t *testing.T) { UpdateTime: time.Now(), } - err := applyOrderbookUpdate(g, update) + err := applyOrderbookUpdate(e, update) require.ErrorIs(t, err, orderbook.ErrDepthNotFound) update.Asset = asset.Spot - err = applyOrderbookUpdate(g, update) + err = applyOrderbookUpdate(e, update) require.ErrorIs(t, err, orderbook.ErrDepthNotFound) update.Pair = currency.NewPair(currency.BABY, currency.BABYDOGE) - err = applyOrderbookUpdate(g, update) + err = applyOrderbookUpdate(e, update) require.NoError(t, err) } diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 26ce5f79884..f893fe5a4bd 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -51,31 +51,31 @@ const ( geminiTransfers = "transfers" ) -// Gemini is the overarching type across the Gemini package, create multiple +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Gemini, create multiple // instances with differing APIkeys for segregation of roles for authenticated // requests & sessions by appending new sessions to the Session map using // AddSession. If sandbox test is needed, append a new session with the same // API keys and change the IsSandbox variable to true. -type Gemini struct { +type Exchange struct { exchange.Base } // GetSymbols returns all available symbols for trading -func (g *Gemini) GetSymbols(ctx context.Context) ([]string, error) { +func (e *Exchange) GetSymbols(ctx context.Context) ([]string, error) { var symbols []string path := fmt.Sprintf("/v%s/%s", geminiAPIVersion, geminiSymbols) - return symbols, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &symbols) + return symbols, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &symbols) } // GetSymbolDetails returns extra symbol details // use symbol "all" to get everything -func (g *Gemini) GetSymbolDetails(ctx context.Context, symbol string) ([]SymbolDetails, error) { +func (e *Exchange) GetSymbolDetails(ctx context.Context, symbol string) ([]SymbolDetails, error) { if symbol == "all" { var details []SymbolDetails - return details, g.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+geminiAPIVersion+"/"+geminiSymbolDetails+"/"+symbol, &details) + return details, e.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+geminiAPIVersion+"/"+geminiSymbolDetails+"/"+symbol, &details) } var details SymbolDetails - err := g.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+geminiAPIVersion+"/"+geminiSymbolDetails+"/"+symbol, &details) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+geminiAPIVersion+"/"+geminiSymbolDetails+"/"+symbol, &details) if err != nil { return nil, err } @@ -83,16 +83,16 @@ func (g *Gemini) GetSymbolDetails(ctx context.Context, symbol string) ([]SymbolD } // GetTicker returns information about recent trading activity for the symbol -func (g *Gemini) GetTicker(ctx context.Context, currencyPair string) (TickerV2, error) { +func (e *Exchange) GetTicker(ctx context.Context, currencyPair string) (TickerV2, error) { ticker := TickerV2{} path := "/v2/ticker/" + currencyPair - err := g.SendHTTPRequest(ctx, exchange.RestSpot, path, &ticker) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &ticker) if err != nil { return ticker, err } if ticker.Result == "error" { return ticker, fmt.Errorf("%v %v %v", - g.Name, + e.Name, ticker.Reason, ticker.Message) } @@ -105,7 +105,7 @@ func (g *Gemini) GetTicker(ctx context.Context, currencyPair string) (TickerV2, // // params - limit_bids or limit_asks [OPTIONAL] default 50, 0 returns all Values // Type is an integer ie "params.Set("limit_asks", 30)" -func (g *Gemini) GetOrderbook(ctx context.Context, currencyPair string, params url.Values) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, currencyPair string, params url.Values) (*Orderbook, error) { path := common.EncodeURLValues( fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, @@ -114,7 +114,7 @@ func (g *Gemini) GetOrderbook(ctx context.Context, currencyPair string, params u params) var orderbook Orderbook - return &orderbook, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook) + return &orderbook, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook) } // GetTrades return the trades that have executed since the specified timestamp. @@ -126,7 +126,7 @@ func (g *Gemini) GetOrderbook(ctx context.Context, currencyPair string, params u // limit_trades integer Optional. The maximum number of trades to return. // include_breaks boolean Optional. Whether to display broken trades. False by // default. Can be '1' or 'true' to activate -func (g *Gemini) GetTrades(ctx context.Context, currencyPair string, since, limit int64, includeBreaks bool) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, currencyPair string, since, limit int64, includeBreaks bool) ([]Trade, error) { params := url.Values{} if since > 0 { params.Add("since", strconv.FormatInt(since, 10)) @@ -140,15 +140,15 @@ func (g *Gemini) GetTrades(ctx context.Context, currencyPair string, since, limi path := common.EncodeURLValues(fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, geminiTrades, currencyPair), params) var trades []Trade - return trades, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) + return trades, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) } // GetAuction returns auction information -func (g *Gemini) GetAuction(ctx context.Context, currencyPair string) (Auction, error) { +func (e *Exchange) GetAuction(ctx context.Context, currencyPair string) (Auction, error) { path := fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, geminiAuction, currencyPair) auction := Auction{} - return auction, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &auction) + return auction, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &auction) } // GetAuctionHistory returns the auction events, optionally including @@ -168,15 +168,15 @@ func (g *Gemini) GetAuction(ctx context.Context, currencyPair string) (Auction, // include_indicative - [bool] Whether to include publication of // // indicative prices and quantities. -func (g *Gemini) GetAuctionHistory(ctx context.Context, currencyPair string, params url.Values) ([]AuctionHistory, error) { +func (e *Exchange) GetAuctionHistory(ctx context.Context, currencyPair string, params url.Values) ([]AuctionHistory, error) { path := common.EncodeURLValues(fmt.Sprintf("/v%s/%s/%s/%s", geminiAPIVersion, geminiAuction, currencyPair, geminiAuctionHistory), params) var auctionHist []AuctionHistory - return auctionHist, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &auctionHist) + return auctionHist, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &auctionHist) } // NewOrder Only limit orders are supported through the API at present. // returns order ID if successful -func (g *Gemini) NewOrder(ctx context.Context, symbol string, amount, price float64, side, orderType string) (int64, error) { +func (e *Exchange) NewOrder(ctx context.Context, symbol string, amount, price float64, side, orderType string) (int64, error) { req := make(map[string]any) req["symbol"] = symbol req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) @@ -185,7 +185,7 @@ func (g *Gemini) NewOrder(ctx context.Context, symbol string, amount, price floa req["type"] = orderType response := Order{} - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderNew, req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderNew, req, &response) if err != nil { return 0, err } @@ -193,7 +193,7 @@ func (g *Gemini) NewOrder(ctx context.Context, symbol string, amount, price floa } // Transfers returns transfer history ie withdrawals and deposits -func (g *Gemini) Transfers(ctx context.Context, curr currency.Code, start time.Time, limit int64, account string, showCompletedDeposit bool) ([]TransferResponse, error) { +func (e *Exchange) Transfers(ctx context.Context, curr currency.Code, start time.Time, limit int64, account string, showCompletedDeposit bool) ([]TransferResponse, error) { req := make(map[string]any) if !curr.IsEmpty() { req["symbol"] = curr.String() @@ -212,17 +212,17 @@ func (g *Gemini) Transfers(ctx context.Context, curr currency.Code, start time.T } var response []TransferResponse - return response, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiTransfers, req, &response) + return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiTransfers, req, &response) } // CancelExistingOrder will cancel an order. If the order is already canceled, the // message will succeed but have no effect. -func (g *Gemini) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { req := make(map[string]any) req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderCancel, req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderCancel, req, &response) if err != nil { return Order{}, err } @@ -237,14 +237,14 @@ func (g *Gemini) CancelExistingOrder(ctx context.Context, orderID int64) (Order, // sessions owned by this account, including interactive orders placed through // the UI. If sessions = true will only cancel the order that is called on this // session associated with the APIKEY -func (g *Gemini) CancelExistingOrders(ctx context.Context, cancelBySession bool) (OrderResult, error) { +func (e *Exchange) CancelExistingOrders(ctx context.Context, cancelBySession bool) (OrderResult, error) { path := geminiOrderCancelAll if cancelBySession { path = geminiOrderCancelSession } var response OrderResult - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, &response) if err != nil { return response, err } @@ -255,13 +255,13 @@ func (g *Gemini) CancelExistingOrders(ctx context.Context, cancelBySession bool) } // GetOrderStatus returns the status for an order -func (g *Gemini) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { +func (e *Exchange) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { req := make(map[string]any) req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderStatus, req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderStatus, req, &response) if err != nil { return response, err } @@ -273,14 +273,14 @@ func (g *Gemini) GetOrderStatus(ctx context.Context, orderID int64) (Order, erro } // GetOrders returns active orders in the market -func (g *Gemini) GetOrders(ctx context.Context) ([]Order, error) { +func (e *Exchange) GetOrders(ctx context.Context) ([]Order, error) { var response any type orders struct { orders []Order } - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrders, nil, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrders, nil, &response) if err != nil { return nil, err } @@ -297,7 +297,7 @@ func (g *Gemini) GetOrders(ctx context.Context) ([]Order, error) { // // currencyPair - example "btcusd" // timestamp - [optional] Only return trades on or after this timestamp. -func (g *Gemini) GetTradeHistory(ctx context.Context, currencyPair string, timestamp int64) ([]TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, currencyPair string, timestamp int64) ([]TradeHistory, error) { var response []TradeHistory req := make(map[string]any) req["symbol"] = currencyPair @@ -307,35 +307,35 @@ func (g *Gemini) GetTradeHistory(ctx context.Context, currencyPair string, times } return response, - g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiMyTrades, req, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiMyTrades, req, &response) } // GetNotionalVolume returns the volume in price currency that has been traded across all pairs over a period of 30 days -func (g *Gemini) GetNotionalVolume(ctx context.Context) (NotionalVolume, error) { +func (e *Exchange) GetNotionalVolume(ctx context.Context) (NotionalVolume, error) { response := NotionalVolume{} return response, - g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiVolume, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiVolume, nil, &response) } // GetTradeVolume returns a multi-arrayed volume response -func (g *Gemini) GetTradeVolume(ctx context.Context) ([][]TradeVolume, error) { +func (e *Exchange) GetTradeVolume(ctx context.Context) ([][]TradeVolume, error) { var response [][]TradeVolume return response, - g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiTradeVolume, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiTradeVolume, nil, &response) } // GetBalances returns available balances in the supported currencies -func (g *Gemini) GetBalances(ctx context.Context) ([]Balance, error) { +func (e *Exchange) GetBalances(ctx context.Context) ([]Balance, error) { var response []Balance return response, - g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiBalances, nil, &response) + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiBalances, nil, &response) } // GetCryptoDepositAddress returns a deposit address -func (g *Gemini) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, currency string) (DepositAddress, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, currency string) (DepositAddress, error) { response := DepositAddress{} req := make(map[string]any) @@ -343,7 +343,7 @@ func (g *Gemini) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, c req["label"] = depositAddlabel } - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) if err != nil { return response, err } @@ -354,13 +354,13 @@ func (g *Gemini) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, c } // WithdrawCrypto withdraws crypto currency to a whitelisted address -func (g *Gemini) WithdrawCrypto(ctx context.Context, address, currency string, amount float64) (WithdrawalAddress, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, address, currency string, amount float64) (WithdrawalAddress, error) { response := WithdrawalAddress{} req := make(map[string]any) req["address"] = address req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(currency), req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(currency), req, &response) if err != nil { return response, err } @@ -372,14 +372,14 @@ func (g *Gemini) WithdrawCrypto(ctx context.Context, address, currency string, a // PostHeartbeat sends a maintenance heartbeat to the exchange for all heartbeat // maintained sessions -func (g *Gemini) PostHeartbeat(ctx context.Context) (string, error) { +func (e *Exchange) PostHeartbeat(ctx context.Context) (string, error) { type Response struct { Result string `json:"result"` Message string `json:"message"` } response := Response{} - err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiHeartbeat, nil, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiHeartbeat, nil, &response) if err != nil { return response.Result, err } @@ -390,8 +390,8 @@ func (g *Gemini) PostHeartbeat(ctx context.Context) (string, error) { } // SendHTTPRequest sends an unauthenticated request -func (g *Gemini) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := g.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -400,33 +400,33 @@ func (g *Gemini) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: g.Verbose, - HTTPDebugging: g.HTTPDebugging, - HTTPRecording: g.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return g.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the // exchange and returns an error -func (g *Gemini) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any) (err error) { - creds, err := g.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]any, result any) (err error) { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := g.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } - return g.SendPayload(ctx, request.Auth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Auth, func() (*request.Item, error) { req := make(map[string]any) req["request"] = fmt.Sprintf("/v%s/%s", geminiAPIVersion, path) - req["nonce"] = g.Requester.GetNonce(nonce.UnixNano).String() + req["nonce"] = e.Requester.GetNonce(nonce.UnixNano).String() maps.Copy(req, params) @@ -455,19 +455,19 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U Headers: headers, Result: result, NonceEnabled: true, - Verbose: g.Verbose, - HTTPDebugging: g.HTTPDebugging, - HTTPRecording: g.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (g *Gemini) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - notionVolume, err := g.GetNotionalVolume(ctx) + notionVolume, err := e.GetNotionalVolume(ctx) if err != nil { return 0, err } diff --git a/exchanges/gemini/gemini_live_test.go b/exchanges/gemini/gemini_live_test.go index f33c93dc956..efe6d64ceb1 100644 --- a/exchanges/gemini/gemini_live_test.go +++ b/exchanges/gemini/gemini_live_test.go @@ -17,17 +17,17 @@ import ( var mockTests = false func TestMain(m *testing.M) { - g = new(Gemini) - if err := testexch.Setup(g); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Gemini Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - g.API.AuthenticatedSupport = true - g.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } - if err := g.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), geminiAPIURL); err != nil { + if err := e.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), geminiAPIURL); err != nil { log.Fatalf("Gemini SetRunningURL error: %s", err) } - log.Printf(sharedtestvalues.LiveTesting, g.Name) + log.Printf(sharedtestvalues.LiveTesting, e.Name) os.Exit(m.Run()) } diff --git a/exchanges/gemini/gemini_mock_test.go b/exchanges/gemini/gemini_mock_test.go index 0d8fea3c130..6f894e3136c 100644 --- a/exchanges/gemini/gemini_mock_test.go +++ b/exchanges/gemini/gemini_mock_test.go @@ -15,12 +15,12 @@ import ( var mockTests = true func TestMain(m *testing.M) { - g = new(Gemini) - if err := testexch.Setup(g); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Gemini Setup error: %s", err) } - if err := testexch.MockHTTPInstance(g); err != nil { + if err := testexch.MockHTTPInstance(e); err != nil { log.Fatalf("Gemini MockHTTPInstance error: %s", err) } diff --git a/exchanges/gemini/gemini_test.go b/exchanges/gemini/gemini_test.go index d9de790f61a..d37dd1658e8 100644 --- a/exchanges/gemini/gemini_test.go +++ b/exchanges/gemini/gemini_test.go @@ -33,11 +33,11 @@ const ( const testCurrency = "btcusd" -var g = &Gemini{} +var e *Exchange func TestGetSymbols(t *testing.T) { t.Parallel() - _, err := g.GetSymbols(t.Context()) + _, err := e.GetSymbols(t.Context()) if err != nil { t.Error("GetSymbols() error", err) } @@ -45,7 +45,7 @@ func TestGetSymbols(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - pairs, err := g.FetchTradablePairs(t.Context(), asset.Spot) + pairs, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Fatal(err) } @@ -62,11 +62,11 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := g.GetTicker(t.Context(), "BTCUSD") + _, err := e.GetTicker(t.Context(), "BTCUSD") if err != nil { t.Error("GetTicker() error", err) } - _, err = g.GetTicker(t.Context(), "bla") + _, err = e.GetTicker(t.Context(), "bla") if err == nil { t.Error("GetTicker() Expected error") } @@ -74,7 +74,7 @@ func TestGetTicker(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetOrderbook(t.Context(), testCurrency, url.Values{}) + _, err := e.GetOrderbook(t.Context(), testCurrency, url.Values{}) if err != nil { t.Error("GetOrderbook() error", err) } @@ -82,7 +82,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := g.GetTrades(t.Context(), testCurrency, 0, 0, false) + _, err := e.GetTrades(t.Context(), testCurrency, 0, 0, false) if err != nil { t.Error("GetTrades() error", err) } @@ -90,7 +90,7 @@ func TestGetTrades(t *testing.T) { func TestGetNotionalVolume(t *testing.T) { t.Parallel() - _, err := g.GetNotionalVolume(t.Context()) + _, err := e.GetNotionalVolume(t.Context()) if err != nil && mockTests { t.Error("GetNotionalVolume() error", err) } else if err == nil && !mockTests { @@ -100,7 +100,7 @@ func TestGetNotionalVolume(t *testing.T) { func TestGetAuction(t *testing.T) { t.Parallel() - _, err := g.GetAuction(t.Context(), testCurrency) + _, err := e.GetAuction(t.Context(), testCurrency) if err != nil { t.Error("GetAuction() error", err) } @@ -108,7 +108,7 @@ func TestGetAuction(t *testing.T) { func TestGetAuctionHistory(t *testing.T) { t.Parallel() - _, err := g.GetAuctionHistory(t.Context(), testCurrency, url.Values{}) + _, err := e.GetAuctionHistory(t.Context(), testCurrency, url.Values{}) if err != nil { t.Error("GetAuctionHistory() error", err) } @@ -116,7 +116,7 @@ func TestGetAuctionHistory(t *testing.T) { func TestNewOrder(t *testing.T) { t.Parallel() - _, err := g.NewOrder(t.Context(), + _, err := e.NewOrder(t.Context(), testCurrency, 1, 9000000, @@ -131,7 +131,7 @@ func TestNewOrder(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Parallel() - _, err := g.CancelExistingOrder(t.Context(), 265555413) + _, err := e.CancelExistingOrder(t.Context(), 265555413) if err != nil && mockTests { t.Error("CancelExistingOrder() error", err) } else if err == nil && !mockTests { @@ -141,7 +141,7 @@ func TestCancelExistingOrder(t *testing.T) { func TestCancelExistingOrders(t *testing.T) { t.Parallel() - _, err := g.CancelExistingOrders(t.Context(), false) + _, err := e.CancelExistingOrders(t.Context(), false) if err != nil && mockTests { t.Error("CancelExistingOrders() error", err) } else if err == nil && !mockTests { @@ -151,7 +151,7 @@ func TestCancelExistingOrders(t *testing.T) { func TestGetOrderStatus(t *testing.T) { t.Parallel() - _, err := g.GetOrderStatus(t.Context(), 265563260) + _, err := e.GetOrderStatus(t.Context(), 265563260) if err != nil && mockTests { t.Error("GetOrderStatus() error", err) } else if err == nil && !mockTests { @@ -161,7 +161,7 @@ func TestGetOrderStatus(t *testing.T) { func TestGetOrders(t *testing.T) { t.Parallel() - _, err := g.GetOrders(t.Context()) + _, err := e.GetOrders(t.Context()) if err != nil && mockTests { t.Error("GetOrders() error", err) } else if err == nil && !mockTests { @@ -171,7 +171,7 @@ func TestGetOrders(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := g.GetTradeHistory(t.Context(), testCurrency, 0) + _, err := e.GetTradeHistory(t.Context(), testCurrency, 0) if err != nil && mockTests { t.Error("GetTradeHistory() error", err) } else if err == nil && !mockTests { @@ -181,7 +181,7 @@ func TestGetTradeHistory(t *testing.T) { func TestGetTradeVolume(t *testing.T) { t.Parallel() - _, err := g.GetTradeVolume(t.Context()) + _, err := e.GetTradeVolume(t.Context()) if err != nil && mockTests { t.Error("GetTradeVolume() error", err) } else if err == nil && !mockTests { @@ -191,7 +191,7 @@ func TestGetTradeVolume(t *testing.T) { func TestGetBalances(t *testing.T) { t.Parallel() - _, err := g.GetBalances(t.Context()) + _, err := e.GetBalances(t.Context()) if err != nil && mockTests { t.Error("GetBalances() error", err) } else if err == nil && !mockTests { @@ -201,7 +201,7 @@ func TestGetBalances(t *testing.T) { func TestGetCryptoDepositAddress(t *testing.T) { t.Parallel() - _, err := g.GetCryptoDepositAddress(t.Context(), "LOL123", "btc") + _, err := e.GetCryptoDepositAddress(t.Context(), "LOL123", "btc") if err == nil { t.Error("GetCryptoDepositAddress() Expected error") } @@ -209,7 +209,7 @@ func TestGetCryptoDepositAddress(t *testing.T) { func TestWithdrawCrypto(t *testing.T) { t.Parallel() - _, err := g.WithdrawCrypto(t.Context(), "LOL123", "btc", 1) + _, err := e.WithdrawCrypto(t.Context(), "LOL123", "btc", 1) if err == nil { t.Error("WithdrawCrypto() Expected error") } @@ -217,7 +217,7 @@ func TestWithdrawCrypto(t *testing.T) { func TestPostHeartbeat(t *testing.T) { t.Parallel() - _, err := g.PostHeartbeat(t.Context()) + _, err := e.PostHeartbeat(t.Context()) if err != nil && mockTests { t.Error("PostHeartbeat() error", err) } else if err == nil && !mockTests { @@ -242,11 +242,11 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - _, err := g.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(g) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, @@ -264,9 +264,9 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(g) || mockTests { + if sharedtestvalues.AreAPICredentialsSet(e) || mockTests { // CryptocurrencyTradeFee Basic - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -274,28 +274,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -303,21 +303,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -325,7 +325,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := g.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -337,7 +337,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText - withdrawPermissions := g.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, @@ -356,11 +356,11 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := g.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(g) && err != nil && !mockTests: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil && !mockTests: t.Errorf("Could not get open orders: %s", err) - case !sharedtestvalues.AreAPICredentialsSet(g) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: t.Errorf("Could not get open orders: %s", err) @@ -376,11 +376,11 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := g.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(g) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not get order history: %s", err) - case !sharedtestvalues.AreAPICredentialsSet(g) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case err != nil && mockTests: t.Errorf("Could not get order history: %s", err) @@ -392,11 +392,11 @@ func TestGetOrderHistory(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderSubmission := &order.Submit{ - Exchange: g.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "_", Base: currency.LTC, @@ -410,11 +410,11 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := g.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) switch { - case sharedtestvalues.AreAPICredentialsSet(g) && (err != nil || response.Status != order.New): + case sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New): t.Errorf("Order failed to be placed: %v", err) - case !sharedtestvalues.AreAPICredentialsSet(g) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: t.Errorf("Order failed to be placed: %v", err) @@ -424,7 +424,7 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderCancellation := &order.Cancel{ OrderID: "266029865", @@ -432,11 +432,11 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: currency.NewBTCUSDT(), } - err := g.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) switch { - case !sharedtestvalues.AreAPICredentialsSet(g) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") - case sharedtestvalues.AreAPICredentialsSet(g) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not cancel orders: %v", err) case err != nil && mockTests: t.Errorf("Could not cancel orders: %v", err) @@ -446,7 +446,7 @@ func TestCancelExchangeOrder(t *testing.T) { func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } currencyPair := currency.NewPair(currency.LTC, currency.BTC) @@ -457,11 +457,11 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := g.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) switch { - case !sharedtestvalues.AreAPICredentialsSet(g) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") - case sharedtestvalues.AreAPICredentialsSet(g) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not cancel orders: %v", err) case mockTests && err != nil: t.Errorf("Could not cancel orders: %v", err) @@ -474,9 +474,9 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - _, err := g.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -486,12 +486,12 @@ func TestWithdraw(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } - _, err := g.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: g.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -499,13 +499,13 @@ func TestWithdraw(t *testing.T) { Address: core.BitcoinDonationAddress, }, }) - if !sharedtestvalues.AreAPICredentialsSet(g) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(g) && err != nil && !mockTests { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil && !mockTests { t.Errorf("Withdraw failed to be placed: %v", err) } - if sharedtestvalues.AreAPICredentialsSet(g) && err == nil && mockTests { + if sharedtestvalues.AreAPICredentialsSet(e) && err == nil && mockTests { t.Errorf("Withdraw failed to be placed: %v", err) } } @@ -513,11 +513,11 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } withdrawFiatRequest := withdraw.Request{} - _, err := g.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -528,11 +528,11 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, g, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } withdrawFiatRequest := withdraw.Request{} - _, err := g.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", @@ -543,7 +543,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := g.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress error cannot be nil") } @@ -552,24 +552,24 @@ func TestGetDepositAddress(t *testing.T) { // TestWsAuth dials websocket, sends login request. func TestWsAuth(t *testing.T) { t.Parallel() - err := g.API.Endpoints.SetRunningURL(exchange.WebsocketSpot.String(), geminiWebsocketSandboxEndpoint) + err := e.API.Endpoints.SetRunningURL(exchange.WebsocketSpot.String(), geminiWebsocketSandboxEndpoint) if err != nil { t.Error(err) } - if !g.Websocket.IsEnabled() && - !g.API.AuthenticatedWebsocketSupport || - !sharedtestvalues.AreAPICredentialsSet(g) { + if !e.Websocket.IsEnabled() && + !e.API.AuthenticatedWebsocketSupport || + !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } var dialer gws.Dialer - go g.wsReadData() - err = g.WsAuth(t.Context(), &dialer) + go e.wsReadData() + err = e.WsAuth(t.Context(), &dialer) if err != nil { t.Error(err) } timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout) select { - case resp := <-g.Websocket.DataHandler: + case resp := <-e.Websocket.DataHandler: subAck, ok := resp.(WsSubscriptionAcknowledgementResponse) if !ok { t.Error("unable to type assert WsSubscriptionAcknowledgementResponse") @@ -589,7 +589,7 @@ func TestWsMissingRole(t *testing.T) { "reason":"MissingRole", "message":"To access this endpoint, you need to log in to the website and go to the settings page to assign one of these roles [FundManager] to API key wujB3szN54gtJ4QDhqRJ which currently has roles [Trader]" }`) - if err := g.wsHandleData(pressXToJSON); err == nil { + if err := e.wsHandleData(pressXToJSON); err == nil { t.Error("Expected error") } } @@ -613,7 +613,7 @@ func TestWsOrderEventSubscriptionResponse(t *testing.T) { "original_amount" : "14.0296", "price" : "1059.54" } ]`) - err := g.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -635,7 +635,7 @@ func TestWsOrderEventSubscriptionResponse(t *testing.T) { "price": "3592.00", "socket_sequence": 13 }]`) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -656,7 +656,7 @@ func TestWsOrderEventSubscriptionResponse(t *testing.T) { "total_spend": "200.00", "socket_sequence": 29 }]`) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -677,7 +677,7 @@ func TestWsOrderEventSubscriptionResponse(t *testing.T) { "original_amount": "25", "socket_sequence": 26 }]`) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -699,7 +699,7 @@ func TestWsOrderEventSubscriptionResponse(t *testing.T) { "original_amount" : "500", "socket_sequence" : 32307 } ]`) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -721,7 +721,7 @@ func TestWsSubAck(t *testing.T) { "closed" ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -734,7 +734,7 @@ func TestWsHeartbeat(t *testing.T) { "trace_id": "b8biknoqppr32kc7gfgg", "socket_sequence": 37 }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -755,7 +755,7 @@ func TestWsUnsubscribe(t *testing.T) { ]} ] }`) - err := g.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -778,7 +778,7 @@ func TestWsTradeData(t *testing.T) { } ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -810,7 +810,7 @@ func TestWsAuctionData(t *testing.T) { ], "type": "update" }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -831,7 +831,7 @@ func TestWsBlockTrade(t *testing.T) { } ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -846,7 +846,7 @@ func TestWSTrade(t *testing.T) { "quantity": "0.09110000", "side": "buy" }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -874,7 +874,7 @@ func TestWsCandles(t *testing.T) { ] ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -896,7 +896,7 @@ func TestWsAuctions(t *testing.T) { ], "type": "update" }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } @@ -920,7 +920,7 @@ func TestWsAuctions(t *testing.T) { } ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } @@ -951,7 +951,7 @@ func TestWsAuctions(t *testing.T) { } ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -980,7 +980,7 @@ func TestWsMarketData(t *testing.T) { } ] } `) - err := g.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -1008,7 +1008,7 @@ func TestWsMarketData(t *testing.T) { } ] } `) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -1030,7 +1030,7 @@ func TestWsMarketData(t *testing.T) { } ] } `) - err = g.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -1068,7 +1068,7 @@ func TestWsError(t *testing.T) { } for x := range tt { - err := g.wsHandleData(tt[x].Data) + err := e.wsHandleData(tt[x].Data) if tt[x].ErrorExpected && err != nil && !strings.Contains(err.Error(), tt[x].ErrorShouldContain) { t.Errorf("expected error to contain: %s, got: %s", tt[x].ErrorShouldContain, err.Error(), @@ -1128,7 +1128,7 @@ func TestWsLevel2Update(t *testing.T) { } ] }`) - if err := g.wsHandleData(pressXToJSON); err != nil { + if err := e.wsHandleData(pressXToJSON); err != nil { t.Error(err) } } @@ -1183,7 +1183,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = g.GetRecentTrades(t.Context(), currencyPair, asset.Spot) + _, err = e.GetRecentTrades(t.Context(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1201,7 +1201,7 @@ func TestGetHistoricTrades(t *testing.T) { tStart = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 0, 0, 0, time.UTC) tEnd = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 15, 0, 0, time.UTC) } - _, err = g.GetHistoricTrades(t.Context(), + _, err = e.GetHistoricTrades(t.Context(), currencyPair, asset.Spot, tStart, tEnd) if err != nil { t.Error(err) @@ -1210,9 +1210,9 @@ func TestGetHistoricTrades(t *testing.T) { func TestTransfers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := g.Transfers(t.Context(), currency.BTC, time.Time{}, 100, "", true) + _, err := e.Transfers(t.Context(), currency.BTC, time.Time{}, 100, "", true) if err != nil { t.Error(err) } @@ -1220,9 +1220,9 @@ func TestTransfers(t *testing.T) { func TestGetAccountFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := g.GetAccountFundingHistory(t.Context()) + _, err := e.GetAccountFundingHistory(t.Context()) if err != nil { t.Error(err) } @@ -1230,9 +1230,9 @@ func TestGetAccountFundingHistory(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := g.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) if err != nil { t.Error(err) } @@ -1240,9 +1240,9 @@ func TestGetWithdrawalsHistory(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, g) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := g.GetOrderInfo(t.Context(), "1234", currency.EMPTYPAIR, asset.Empty) + _, err := e.GetOrderInfo(t.Context(), "1234", currency.EMPTYPAIR, asset.Empty) if err != nil { t.Error(err) } @@ -1250,11 +1250,11 @@ func TestGetOrderInfo(t *testing.T) { func TestGetSymbolDetails(t *testing.T) { t.Parallel() - _, err := g.GetSymbolDetails(t.Context(), "all") + _, err := e.GetSymbolDetails(t.Context(), "all") if err != nil { t.Error(err) } - _, err = g.GetSymbolDetails(t.Context(), "btcusd") + _, err = e.GetSymbolDetails(t.Context(), "btcusd") if err != nil { t.Error(err) } @@ -1262,18 +1262,18 @@ func TestGetSymbolDetails(t *testing.T) { func TestSetExchangeOrderExecutionLimits(t *testing.T) { t.Parallel() - err := g.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) if err != nil { t.Fatal(err) } - err = g.UpdateOrderExecutionLimits(t.Context(), asset.Futures) + err = e.UpdateOrderExecutionLimits(t.Context(), asset.Futures) assert.ErrorIs(t, err, asset.ErrNotSupported) - availPairs, err := g.GetAvailablePairs(asset.Spot) + availPairs, err := e.GetAvailablePairs(asset.Spot) require.NoError(t, err) for x := range availPairs { var limit order.MinMaxLevel - limit, err = g.GetOrderExecutionLimits(asset.Spot, availPairs[x]) + limit, err = e.GetOrderExecutionLimits(asset.Spot, availPairs[x]) if err != nil { t.Fatal(err, availPairs[x]) } @@ -1285,12 +1285,12 @@ func TestSetExchangeOrderExecutionLimits(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, g) - for _, a := range g.GetAssetTypes(false) { - pairs, err := g.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := g.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -1298,12 +1298,12 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - g := new(Gemini) - require.NoError(t, testexch.Setup(g), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") p := currency.Pairs{currency.NewPairWithDelimiter("BTC", "USD", ""), currency.NewPairWithDelimiter("ETH", "BTC", "")} - require.NoError(t, g.CurrencyPairs.StorePairs(asset.Spot, p, false)) - require.NoError(t, g.CurrencyPairs.StorePairs(asset.Spot, p, true)) - subs, err := g.generateSubscriptions() + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, false)) + require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, true)) + subs, err := e.generateSubscriptions() require.NoError(t, err) exp := subscription.List{ {Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: p, QualifiedChannel: "candles_1d", Interval: kline.OneDay}, @@ -1312,12 +1312,12 @@ func TestGenerateSubscriptions(t *testing.T) { testsubs.EqualLists(t, exp, subs) for _, i := range []kline.Interval{kline.OneMin, kline.FiveMin, kline.FifteenMin, kline.ThirtyMin, kline.OneHour, kline.SixHour} { - subs, err = subscription.List{{Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: p, Interval: i}}.ExpandTemplates(g) + subs, err = subscription.List{{Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: p, Interval: i}}.ExpandTemplates(e) assert.NoErrorf(t, err, "ExpandTemplates should not error on interval %s", i) require.NotEmpty(t, subs) assert.Equal(t, "candles_"+i.Short(), subs[0].QualifiedChannel) } - _, err = subscription.List{{Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: p, Interval: kline.FourHour}}.ExpandTemplates(g) + _, err = subscription.List{{Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: p, Interval: kline.FourHour}}.ExpandTemplates(e) assert.ErrorIs(t, err, kline.ErrUnsupportedInterval, "ExpandTemplates should error on invalid interval") assert.PanicsWithError(t, diff --git a/exchanges/gemini/gemini_websocket.go b/exchanges/gemini/gemini_websocket.go index 1b78e53bee9..f2f5a6fd772 100644 --- a/exchanges/gemini/gemini_websocket.go +++ b/exchanges/gemini/gemini_websocket.go @@ -58,39 +58,39 @@ var subscriptionNames = map[string]string{ var comms = make(chan websocket.Response) // WsConnect initiates a websocket connection -func (g *Gemini) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !g.Websocket.IsEnabled() || !g.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := g.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - g.Websocket.Wg.Add(2) - go g.wsReadData() - go g.wsFunnelConnectionData(g.Websocket.Conn) + e.Websocket.Wg.Add(2) + go e.wsReadData() + go e.wsFunnelConnectionData(e.Websocket.Conn) - if g.Websocket.CanUseAuthenticatedEndpoints() { - err := g.WsAuth(ctx, &dialer) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err := e.WsAuth(ctx, &dialer) if err != nil { - log.Errorf(log.ExchangeSys, "%v - websocket authentication failed: %v\n", g.Name, err) - g.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%v - websocket authentication failed: %v\n", e.Name, err) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } return nil } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (g *Gemini) generateSubscriptions() (subscription.List, error) { - return g.Features.Subscriptions.ExpandTemplates(g) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (g *Gemini) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "interval": channelInterval, @@ -98,18 +98,18 @@ func (g *Gemini) GetSubscriptionTemplate(_ *subscription.Subscription) (*templat } // Subscribe sends a websocket message to receive data from the channel -func (g *Gemini) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - return g.manageSubs(ctx, subs, wsSubscribeOp) + return e.manageSubs(ctx, subs, wsSubscribeOp) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (g *Gemini) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - return g.manageSubs(ctx, subs, wsUnsubscribeOp) + return e.manageSubs(ctx, subs, wsUnsubscribeOp) } -func (g *Gemini) manageSubs(ctx context.Context, subs subscription.List, op wsSubOp) error { +func (e *Exchange) manageSubs(ctx context.Context, subs subscription.List, op wsSubOp) error { req := wsSubscribeRequest{ Type: op, Subscriptions: make([]wsSubscriptions, 0, len(subs)), @@ -121,23 +121,23 @@ func (g *Gemini) manageSubs(ctx context.Context, subs subscription.List, op wsSu }) } - if err := g.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req); err != nil { + if err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req); err != nil { return err } if op == wsUnsubscribeOp { - return g.Websocket.RemoveSubscriptions(g.Websocket.Conn, subs...) + return e.Websocket.RemoveSubscriptions(e.Websocket.Conn, subs...) } - return g.Websocket.AddSuccessfulSubscriptions(g.Websocket.Conn, subs...) + return e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, subs...) } // WsAuth will connect to Gemini's secure endpoint -func (g *Gemini) WsAuth(ctx context.Context, dialer *gws.Dialer) error { - if !g.IsWebsocketAuthenticationSupported() { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", g.Name) +func (e *Exchange) WsAuth(ctx context.Context, dialer *gws.Dialer) error { + if !e.IsWebsocketAuthenticationSupported() { + return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", e.Name) } - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -147,9 +147,9 @@ func (g *Gemini) WsAuth(ctx context.Context, dialer *gws.Dialer) error { } payloadJSON, err := json.Marshal(payload) if err != nil { - return fmt.Errorf("%v sendAuthenticatedHTTPRequest: Unable to JSON request", g.Name) + return fmt.Errorf("%v sendAuthenticatedHTTPRequest: Unable to JSON request", e.Name) } - wsEndpoint, err := g.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } @@ -168,18 +168,18 @@ func (g *Gemini) WsAuth(ctx context.Context, dialer *gws.Dialer) error { headers.Add("X-GEMINI-SIGNATURE", hex.EncodeToString(hmac)) headers.Add("Cache-Control", "no-cache") - err = g.Websocket.AuthConn.Dial(ctx, dialer, headers) + err = e.Websocket.AuthConn.Dial(ctx, dialer, headers) if err != nil { - return fmt.Errorf("%v Websocket connection %v error. Error %v", g.Name, endpoint, err) + return fmt.Errorf("%v Websocket connection %v error. Error %v", e.Name, endpoint, err) } - g.Websocket.Wg.Add(1) - go g.wsFunnelConnectionData(g.Websocket.AuthConn) + e.Websocket.Wg.Add(1) + go e.wsFunnelConnectionData(e.Websocket.AuthConn) return nil } // wsFunnelConnectionData receives data from multiple connections and passes it to wsReadData -func (g *Gemini) wsFunnelConnectionData(ws websocket.Connection) { - defer g.Websocket.Wg.Done() +func (e *Exchange) wsFunnelConnectionData(ws websocket.Connection) { + defer e.Websocket.Wg.Done() for { resp := ws.ReadMessage() if resp.Raw == nil { @@ -190,21 +190,21 @@ func (g *Gemini) wsFunnelConnectionData(ws websocket.Connection) { } // wsReadData receives and passes on websocket messages for processing -func (g *Gemini) wsReadData() { - defer g.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { select { - case <-g.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: select { case resp := <-comms: - err := g.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { select { - case g.Websocket.DataHandler <- err: + case e.Websocket.DataHandler <- err: default: log.Errorf(log.WebsocketMgr, "%s websocket handle data error: %v", - g.Name, + e.Name, err) } } @@ -212,15 +212,15 @@ func (g *Gemini) wsReadData() { } return case resp := <-comms: - err := g.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - g.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (g *Gemini) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { // only order details are sent in arrays if strings.HasPrefix(string(respRaw), "[") { var result []WsOrderResponse @@ -232,8 +232,8 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { for i := range result { oSide, err := order.StringToOrderSide(result[i].Side) if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: result[i].OrderID, Err: err, } @@ -241,8 +241,8 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { var oType order.Type oType, err = stringToOrderType(result[i].OrderType) if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: result[i].OrderID, Err: err, } @@ -250,19 +250,19 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { var oStatus order.Status oStatus, err = stringToOrderStatus(result[i].Type) if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: result[i].OrderID, Err: err, } } - enabledPairs, err := g.GetAvailablePairs(asset.Spot) + enabledPairs, err := e.GetAvailablePairs(asset.Spot) if err != nil { return err } - format, err := g.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -272,13 +272,13 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { return err } - g.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ HiddenOrder: result[i].IsHidden, Price: result[i].Price, Amount: result[i].OriginalAmount, ExecutedAmount: result[i].ExecutedAmount, RemainingAmount: result[i].RemainingAmount, - Exchange: g.Name, + Exchange: e.Name, OrderID: result[i].OrderID, Type: oType, Side: oSide, @@ -293,7 +293,7 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { var result map[string]any err := json.Unmarshal(respRaw, &result) if err != nil { - return fmt.Errorf("%v Error: %v, Raw: %v", g.Name, err, string(respRaw)) + return fmt.Errorf("%v Error: %v, Raw: %v", e.Name, err, string(respRaw)) } if _, ok := result["type"]; ok { switch result["type"] { @@ -303,9 +303,9 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { if err != nil { return err } - return g.wsProcessUpdate(l2MarketData) + return e.wsProcessUpdate(l2MarketData) case "trade": - if !g.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } @@ -317,18 +317,18 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { tSide, err := order.StringToOrderSide(result.Side) if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, Err: err, } } - enabledPairs, err := g.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := g.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -342,7 +342,7 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { Timestamp: result.Timestamp.Time(), CurrencyPair: pair, AssetType: asset.Spot, - Exchange: g.Name, + Exchange: e.Name, Price: result.Price, Amount: result.Quantity, Side: tSide, @@ -356,14 +356,14 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { if err != nil { return err } - g.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result case "initial": var result WsSubscriptionAcknowledgementResponse err := json.Unmarshal(respRaw, &result) if err != nil { return err } - g.Websocket.DataHandler <- result + e.Websocket.DataHandler <- result case "heartbeat": return nil case "candles_1m_updates", @@ -378,12 +378,12 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { if err != nil { return err } - enabledPairs, err := g.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := g.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -401,11 +401,11 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { if !ok { return errors.New("unable to type assert interval") } - g.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: time.UnixMilli(int64(candle.Changes[i][0])), Pair: pair, AssetType: asset.Spot, - Exchange: g.Name, + Exchange: e.Name, Interval: interval, OpenPrice: candle.Changes[i][1], HighPrice: candle.Changes[i][2], @@ -415,7 +415,7 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { } } default: - g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: g.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } } else if r, ok := result["result"].(string); ok { @@ -427,9 +427,9 @@ func (g *Gemini) wsHandleData(respRaw []byte) error { } return errors.New(reason) } - return fmt.Errorf("%v Unhandled websocket error %s", g.Name, respRaw) + return fmt.Errorf("%v Unhandled websocket error %s", e.Name, respRaw) default: - g.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: g.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } } @@ -468,14 +468,14 @@ func stringToOrderType(oType string) (order.Type, error) { } } -func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { +func (e *Exchange) wsProcessUpdate(result *wsL2MarketData) error { isInitial := len(result.Changes) > 0 && len(result.Trades) > 0 - enabledPairs, err := g.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := g.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -514,10 +514,10 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { newOrderBook.Bids = bids newOrderBook.Asset = asset.Spot newOrderBook.Pair = pair - newOrderBook.Exchange = g.Name - newOrderBook.ValidateOrderbook = g.ValidateOrderbook + newOrderBook.Exchange = e.Name + newOrderBook.ValidateOrderbook = e.ValidateOrderbook newOrderBook.LastUpdated = time.Now() // No time is sent - err := g.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + err := e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) if err != nil { return err } @@ -525,7 +525,7 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { if len(asks) == 0 && len(bids) == 0 { return nil } - err := g.Websocket.Orderbook.Update(&orderbook.Update{ + err := e.Websocket.Orderbook.Update(&orderbook.Update{ Asks: asks, Bids: bids, Pair: pair, @@ -538,10 +538,10 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { } if len(result.AuctionEvents) > 0 { - g.Websocket.DataHandler <- result.AuctionEvents + e.Websocket.DataHandler <- result.AuctionEvents } - if !g.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } @@ -549,8 +549,8 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { for x := range result.Trades { tSide, err := order.StringToOrderSide(result.Trades[x].Side) if err != nil { - g.Websocket.DataHandler <- order.ClassificationError{ - Exchange: g.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, Err: err, } } @@ -558,7 +558,7 @@ func (g *Gemini) wsProcessUpdate(result *wsL2MarketData) error { Timestamp: result.Trades[x].Timestamp.Time(), CurrencyPair: pair, AssetType: asset.Spot, - Exchange: g.Name, + Exchange: e.Name, Price: result.Trades[x].Price, Amount: result.Trades[x].Quantity, Side: tSide, diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index b88fae2d1ee..aa09bd19fa0 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -32,12 +32,12 @@ import ( ) // SetDefaults sets package defaults for gemini exchange -func (g *Gemini) SetDefaults() { - g.Name = "Gemini" - g.Enabled = true - g.Verbose = true - g.API.CredentialsValidator.RequiresKey = true - g.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Gemini" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{ Uppercase: true, @@ -47,12 +47,12 @@ func (g *Gemini) SetDefaults() { Uppercase: true, Delimiter: currency.DashDelimiter, } - err := g.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - g.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -92,68 +92,68 @@ func (g *Gemini) SetDefaults() { Subscriptions: defaultSubscriptions.Clone(), } - g.Requester, err = request.New(g.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - g.API.Endpoints = g.NewEndpoints() - err = g.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: geminiAPIURL, exchange.WebsocketSpot: geminiWebsocketEndpoint, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - g.Websocket = websocket.NewManager() - g.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - g.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - g.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets exchange configuration parameters -func (g *Gemini) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - g.SetEnabled(false) + e.SetEnabled(false) return nil } - err = g.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } if exch.UseSandbox { - err = g.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), geminiSandboxAPIURL) + err = e.API.Endpoints.SetRunningURL(exchange.RestSpot.String(), geminiSandboxAPIURL) if err != nil { log.Errorln(log.ExchangeSys, err) } } - wsRunningURL, err := g.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = g.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: geminiWebsocketEndpoint, RunningURL: wsRunningURL, - Connector: g.WsConnect, - Subscriber: g.Subscribe, - Unsubscriber: g.Unsubscribe, - GenerateSubscriptions: g.generateSubscriptions, - Features: &g.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - err = g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, URL: geminiWebsocketEndpoint + "/v2/" + geminiWsMarketData, @@ -162,7 +162,7 @@ func (g *Gemini) Setup(exch *config.Exchange) error { return err } - return g.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, URL: geminiWebsocketEndpoint + "/v1/" + geminiWsOrderEvents, @@ -171,12 +171,12 @@ func (g *Gemini) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (g *Gemini) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !g.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, asset.ErrNotSupported } - details, err := g.GetSymbolDetails(ctx, "all") + details, err := e.GetSymbolDetails(ctx, "all") if err != nil { return nil, err } @@ -202,24 +202,24 @@ func (g *Gemini) FetchTradablePairs(ctx context.Context, a asset.Item) (currency // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (g *Gemini) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := g.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = g.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return g.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateAccountInfo Retrieves balances for all enabled currencies for the // Gemini exchange -func (g *Gemini) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = g.Name - accountBalance, err := g.GetBalances(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetBalances(ctx) if err != nil { return response, err } @@ -239,7 +239,7 @@ func (g *Gemini) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a Currencies: currencies, }) - creds, err := g.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -252,18 +252,18 @@ func (g *Gemini) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (g *Gemini) UpdateTickers(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateTickers(_ context.Context, _ asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (g *Gemini) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - fPair, err := g.FormatExchangeCurrency(p, a) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + fPair, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := g.GetTicker(ctx, fPair.String()) + tick, err := e.GetTicker(ctx, fPair.String()) if err != nil { return nil, err } @@ -276,36 +276,36 @@ func (g *Gemini) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item Open: tick.Open, Close: tick.Close, Pair: fPair, - ExchangeName: g.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } - return ticker.GetTicker(g.Name, fPair, a) + return ticker.GetTicker(e.Name, fPair, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := g.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: g.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: g.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := g.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := g.GetOrderbook(ctx, fPair.String(), url.Values{}) + orderbookNew, err := e.GetOrderbook(ctx, fPair.String(), url.Values{}) if err != nil { return book, err } @@ -329,13 +329,13 @@ func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(g.Name, fPair, assetType) + return orderbook.Get(e.Name, fPair, assetType) } // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (g *Gemini) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { - transfers, err := g.Transfers(ctx, currency.EMPTYCODE, time.Time{}, 50, "", false) +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { + transfers, err := e.Transfers(ctx, currency.EMPTYCODE, time.Time{}, 50, "", false) if err != nil { return nil, err } @@ -357,11 +357,11 @@ func (g *Gemini) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fundi } // GetWithdrawalsHistory returns previous withdrawals data -func (g *Gemini) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { - if err := g.CurrencyPairs.IsAssetEnabled(a); err != nil { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { + if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil { return nil, err } - transfers, err := g.Transfers(ctx, c, time.Time{}, 50, "", false) + transfers, err := e.Transfers(ctx, c, time.Time{}, 50, "", false) if err != nil { return nil, err } @@ -386,17 +386,17 @@ func (g *Gemini) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a a } // GetRecentTrades returns the most recent trades for a currency and asset -func (g *Gemini) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return g.GetHistoricTrades(ctx, pair, assetType, time.Time{}, time.Time{}) +func (e *Exchange) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, pair, assetType, time.Time{}, time.Time{}) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (g *Gemini) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil && !errors.Is(err, common.ErrDateUnset) { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - p, err = g.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -406,7 +406,7 @@ func (g *Gemini) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTy allTrades: for { var tradeData []Trade - tradeData, err = g.GetTrades(ctx, p.String(), ts.Unix(), int64(limit), false) + tradeData, err = e.GetTrades(ctx, p.String(), ts.Unix(), int64(limit), false) if err != nil { return nil, err } @@ -422,7 +422,7 @@ allTrades: return nil, err } resp = append(resp, trade.Data{ - Exchange: g.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].TID, 10), CurrencyPair: p, AssetType: assetType, @@ -443,7 +443,7 @@ allTrades: } } - err = g.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -454,8 +454,8 @@ allTrades: } // SubmitOrder submits a new order -func (g *Gemini) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(g.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -463,12 +463,12 @@ func (g *Gemini) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi return nil, errors.New("only limit orders are enabled through this exchange") } - fPair, err := g.FormatExchangeCurrency(s.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pair, asset.Spot) if err != nil { return nil, err } - response, err := g.NewOrder(ctx, + response, err := e.NewOrder(ctx, fPair.String(), s.Amount, s.Price, @@ -483,12 +483,12 @@ func (g *Gemini) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (g *Gemini) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (g *Gemini) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -498,26 +498,26 @@ func (g *Gemini) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } - _, err = g.CancelExistingOrder(ctx, orderIDInt) + _, err = e.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (g *Gemini) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (g *Gemini) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (g *Gemini) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - resp, err := g.CancelExistingOrders(ctx, false) + resp, err := e.CancelExistingOrders(ctx, false) if err != nil { return cancelAllOrdersResponse, err } @@ -530,12 +530,12 @@ func (g *Gemini) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Ca } // GetOrderInfo returns order information based on order ID -func (g *Gemini) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { iOID, err := strconv.ParseInt(orderID, 10, 64) if err != nil { return nil, err } - resp, err := g.GetOrderStatus(ctx, iOID) + resp, err := e.GetOrderStatus(ctx, iOID) if err != nil { return nil, err } @@ -575,8 +575,8 @@ func (g *Gemini) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa } // GetDepositAddress returns a deposit address for a specified currency -func (g *Gemini) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { - addr, err := g.GetCryptoDepositAddress(ctx, "", cryptocurrency.String()) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { + addr, err := e.GetCryptoDepositAddress(ctx, "", cryptocurrency.String()) if err != nil { return nil, err } @@ -585,11 +585,11 @@ func (g *Gemini) GetDepositAddress(ctx context.Context, cryptocurrency currency. // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (g *Gemini) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := g.WithdrawCrypto(ctx, + resp, err := e.WithdrawCrypto(ctx, withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), withdrawRequest.Amount) @@ -607,46 +607,46 @@ func (g *Gemini) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (g *Gemini) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (g *Gemini) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (g *Gemini) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if (!g.AreCredentialsValid(ctx) || g.SkipAuthCheck) && // Todo check connection status + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return g.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := g.GetOrders(ctx) + resp, err := e.GetOrders(ctx) if err != nil { return nil, err } - availPairs, err := g.GetAvailablePairs(asset.Spot) + availPairs, err := e.GetAvailablePairs(asset.Spot) if err != nil { return nil, err } - format, err := g.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return nil, err } @@ -680,7 +680,7 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque RemainingAmount: resp[i].RemainingAmount, OrderID: strconv.FormatInt(resp[i].OrderID, 10), ExecutedAmount: resp[i].ExecutedAmount, - Exchange: g.Name, + Exchange: e.Name, Type: orderType, Side: side, Price: resp[i].Price, @@ -688,12 +688,12 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque Date: resp[i].Timestamp.Time(), } } - return req.Filter(g.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -706,13 +706,13 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var trades []TradeHistory for j := range req.Pairs { var fPair currency.Pair - fPair, err = g.FormatExchangeCurrency(req.Pairs[j], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[j], asset.Spot) if err != nil { return nil, err } var resp []TradeHistory - resp, err = g.GetTradeHistory(ctx, fPair.String(), req.StartTime.Unix()) + resp, err = e.GetTradeHistory(ctx, fPair.String(), req.StartTime.Unix()) if err != nil { return nil, err } @@ -724,7 +724,7 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque } } - format, err := g.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -740,7 +740,7 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque OrderID: strconv.FormatInt(trades[i].OrderID, 10), Amount: trades[i].Amount, ExecutedAmount: trades[i].Amount, - Exchange: g.Name, + Exchange: e.Name, Date: trades[i].Timestamp.Time(), Side: side, Fee: trades[i].FeeAmount, @@ -755,37 +755,37 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque detail.InferCostsAndTimes() orders[i] = detail } - return req.Filter(g.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (g *Gemini) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := g.UpdateAccountInfo(ctx, assetType) - return g.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (g *Gemini) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (g *Gemini) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (g *Gemini) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (g *Gemini) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { if a != asset.Spot { return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - details, err := g.GetSymbolDetails(ctx, "all") + details, err := e.GetSymbolDetails(ctx, "all") if err != nil { return fmt.Errorf("cannot update exchange execution limits: %w", err) } @@ -807,17 +807,17 @@ func (g *Gemini) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e QuoteStepIncrementSize: details[i].QuoteIncrement, }) } - return g.LoadLimits(resp) + return e.LoadLimits(resp) } // GetLatestFundingRates returns the latest funding rates data -func (g *Gemini) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (g *Gemini) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := g.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index 9e390fa2b87..97efbd29201 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -41,8 +41,8 @@ const ( apiOrder = "api/2/order" ) -// HitBTC is the overarching type across the hitbtc package -type HitBTC struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with HitBTC +type Exchange struct { exchange.Base } @@ -51,13 +51,13 @@ type HitBTC struct { // GetCurrencies returns the actual list of available currencies, tokens, ICO // etc. -func (h *HitBTC) GetCurrencies(ctx context.Context) (map[string]Currencies, error) { +func (e *Exchange) GetCurrencies(ctx context.Context) (map[string]Currencies, error) { type Response struct { Data []Currencies } resp := Response{} ret := make(map[string]Currencies) - err := h.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Currency, &resp.Data) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Currency, &resp.Data) if err != nil { return ret, err } @@ -70,14 +70,14 @@ func (h *HitBTC) GetCurrencies(ctx context.Context) (map[string]Currencies, erro // GetCurrency returns the actual list of available currencies, tokens, ICO // etc. -func (h *HitBTC) GetCurrency(ctx context.Context, currency string) (Currencies, error) { +func (e *Exchange) GetCurrency(ctx context.Context, currency string) (Currencies, error) { type Response struct { Data Currencies } resp := Response{} path := apiV2Currency + "/" + currency - return resp.Data, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) + return resp.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) } // GetSymbols Return the actual list of currency symbols (currency pairs) traded @@ -85,12 +85,12 @@ func (h *HitBTC) GetCurrency(ctx context.Context, currency string) (Currencies, // currency, and the second currency is called the quote currency. The currency // pair indicates how much of the quote currency is needed to purchase one unit // of the base currency. -func (h *HitBTC) GetSymbols(ctx context.Context, symbol string) ([]string, error) { +func (e *Exchange) GetSymbols(ctx context.Context, symbol string) ([]string, error) { var resp []Symbol path := apiV2Symbol + "/" + symbol ret := make([]string, 0, len(resp)) - err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return ret, err } @@ -103,26 +103,26 @@ func (h *HitBTC) GetSymbols(ctx context.Context, symbol string) ([]string, error // GetSymbolsDetailed is the same as above but returns an array of symbols with // all their details. -func (h *HitBTC) GetSymbolsDetailed(ctx context.Context) ([]Symbol, error) { +func (e *Exchange) GetSymbolsDetailed(ctx context.Context) ([]Symbol, error) { var resp []Symbol - return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Symbol, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Symbol, &resp) } // GetTicker returns ticker information -func (h *HitBTC) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { var resp TickerResponse path := apiV2Ticker + "/" + symbol - return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTickers returns ticker information -func (h *HitBTC) GetTickers(ctx context.Context) ([]TickerResponse, error) { +func (e *Exchange) GetTickers(ctx context.Context) ([]TickerResponse, error) { var resp []TickerResponse - return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Ticker, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, apiV2Ticker, &resp) } // GetTrades returns trades from hitbtc -func (h *HitBTC) GetTrades(ctx context.Context, currencyPair, by, sort string, from, till, limit, offset int64) ([]TradeHistory, error) { +func (e *Exchange) GetTrades(ctx context.Context, currencyPair, by, sort string, from, till, limit, offset int64) ([]TradeHistory, error) { urlValues := url.Values{} if from > 0 { urlValues.Set("from", strconv.FormatInt(from, 10)) @@ -145,12 +145,12 @@ func (h *HitBTC) GetTrades(ctx context.Context, currencyPair, by, sort string, f var resp []TradeHistory path := common.EncodeURLValues(apiV2Trades+"/"+currencyPair, urlValues) - return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetOrderbook an order book is an electronic list of buy and sell orders for a // specific symbol, organized by price level. -func (h *HitBTC) GetOrderbook(ctx context.Context, currencyPair string, limit int) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, currencyPair string, limit int) (*Orderbook, error) { // limit Limit of orderbook levels, default 100. Set 0 to view full orderbook levels vals := url.Values{} @@ -160,7 +160,7 @@ func (h *HitBTC) GetOrderbook(ctx context.Context, currencyPair string, limit in var resp Orderbook path := common.EncodeURLValues(apiV2Orderbook+"/"+currencyPair, vals) - err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (h *HitBTC) GetOrderbook(ctx context.Context, currencyPair string, limit in // GetCandles returns candles which is used for OHLC a specific currency. // Note: Result contain candles only with non zero volume. -func (h *HitBTC) GetCandles(ctx context.Context, currencyPair, limit, period string, start, end time.Time) ([]ChartData, error) { +func (e *Exchange) GetCandles(ctx context.Context, currencyPair, limit, period string, start, end time.Time) ([]ChartData, error) { // limit Limit of candles, default 100. // period One of: M1 (one minute), M3, M5, M15, M30, H1, H4, D1, D7, 1M (one month). Default is M30 (30 minutes). vals := url.Values{} @@ -195,16 +195,16 @@ func (h *HitBTC) GetCandles(ctx context.Context, currencyPair, limit, period str var resp []ChartData path := common.EncodeURLValues(apiV2Candles+"/"+currencyPair, vals) - return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // Authenticated Market Data // https://api.hitbtc.com/?python#market-data // GetBalances returns full balance for your account -func (h *HitBTC) GetBalances(ctx context.Context) (map[string]Balance, error) { +func (e *Exchange) GetBalances(ctx context.Context) (map[string]Balance, error) { var result []Balance - err := h.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2Balance, @@ -225,11 +225,11 @@ func (h *HitBTC) GetBalances(ctx context.Context) (map[string]Balance, error) { } // GetDepositAddresses returns a deposit address for a specific currency -func (h *HitBTC) GetDepositAddresses(ctx context.Context, currency string) (DepositCryptoAddresses, error) { +func (e *Exchange) GetDepositAddresses(ctx context.Context, currency string) (DepositCryptoAddresses, error) { var resp DepositCryptoAddresses return resp, - h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2CryptoAddress+"/"+currency, url.Values{}, otherRequests, @@ -237,9 +237,9 @@ func (h *HitBTC) GetDepositAddresses(ctx context.Context, currency string) (Depo } // GenerateNewAddress generates a new deposit address for a currency -func (h *HitBTC) GenerateNewAddress(ctx context.Context, currency string) (DepositCryptoAddresses, error) { +func (e *Exchange) GenerateNewAddress(ctx context.Context, currency string) (DepositCryptoAddresses, error) { resp := DepositCryptoAddresses{} - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2CryptoAddress+"/"+currency, url.Values{}, otherRequests, @@ -249,7 +249,7 @@ func (h *HitBTC) GenerateNewAddress(ctx context.Context, currency string) (Depos } // GetTradeHistoryForCurrency returns your trade history -func (h *HitBTC) GetTradeHistoryForCurrency(ctx context.Context, currency, start, end string) (AuthenticatedTradeHistoryResponse, error) { +func (e *Exchange) GetTradeHistoryForCurrency(ctx context.Context, currency, start, end string) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start != "" { @@ -263,7 +263,7 @@ func (h *HitBTC) GetTradeHistoryForCurrency(ctx context.Context, currency, start values.Set("currencyPair", currency) result := AuthenticatedTradeHistoryResponse{} - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2TradeHistory, values, otherRequests, @@ -271,7 +271,7 @@ func (h *HitBTC) GetTradeHistoryForCurrency(ctx context.Context, currency, start } // GetTradeHistoryForAllCurrencies returns your trade history -func (h *HitBTC) GetTradeHistoryForAllCurrencies(ctx context.Context, start, end string) (AuthenticatedTradeHistoryAll, error) { +func (e *Exchange) GetTradeHistoryForAllCurrencies(ctx context.Context, start, end string) (AuthenticatedTradeHistoryAll, error) { values := url.Values{} if start != "" { @@ -285,7 +285,7 @@ func (h *HitBTC) GetTradeHistoryForAllCurrencies(ctx context.Context, start, end values.Set("currencyPair", "all") result := AuthenticatedTradeHistoryAll{} - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2TradeHistory, values, otherRequests, @@ -293,12 +293,12 @@ func (h *HitBTC) GetTradeHistoryForAllCurrencies(ctx context.Context, start, end } // GetOrders List of your order history. -func (h *HitBTC) GetOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { +func (e *Exchange) GetOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { values := url.Values{} values.Set("symbol", currency) var result []OrderHistoryResponse - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2OrderHistory, values, tradingRequests, @@ -306,12 +306,12 @@ func (h *HitBTC) GetOrders(ctx context.Context, currency string) ([]OrderHistory } // GetOpenOrders List of your currently open orders. -func (h *HitBTC) GetOpenOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { values := url.Values{} values.Set("symbol", currency) var result []OrderHistoryResponse - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiv2OpenOrders, values, tradingRequests, @@ -319,10 +319,10 @@ func (h *HitBTC) GetOpenOrders(ctx context.Context, currency string) ([]OrderHis } // GetActiveOrderByClientOrderID Get an active order by id -func (h *HitBTC) GetActiveOrderByClientOrderID(ctx context.Context, clientOrderID string) (OrderHistoryResponse, error) { +func (e *Exchange) GetActiveOrderByClientOrderID(ctx context.Context, clientOrderID string) (OrderHistoryResponse, error) { var result OrderHistoryResponse - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiv2OpenOrders+"/"+clientOrderID, nil, tradingRequests, @@ -330,7 +330,7 @@ func (h *HitBTC) GetActiveOrderByClientOrderID(ctx context.Context, clientOrderI } // PlaceOrder places an order on the exchange -func (h *HitBTC) PlaceOrder(ctx context.Context, currency string, rate, amount float64, orderType, side string) (OrderResponse, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, currency string, rate, amount float64, orderType, side string) (OrderResponse, error) { var result OrderResponse values := url.Values{} @@ -341,7 +341,7 @@ func (h *HitBTC) PlaceOrder(ctx context.Context, currency string, rate, amount f values.Set("price", strconv.FormatFloat(rate, 'f', -1, 64)) values.Set("type", orderType) - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiOrder, values, tradingRequests, @@ -349,11 +349,11 @@ func (h *HitBTC) PlaceOrder(ctx context.Context, currency string, rate, amount f } // CancelExistingOrder cancels a specific order by OrderID -func (h *HitBTC) CancelExistingOrder(ctx context.Context, orderID int64) (bool, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) (bool, error) { result := GenericResponse{} values := url.Values{} - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, apiOrder+"/"+strconv.FormatInt(orderID, 10), values, tradingRequests, @@ -370,10 +370,10 @@ func (h *HitBTC) CancelExistingOrder(ctx context.Context, orderID int64) (bool, } // CancelAllExistingOrders cancels all open orders -func (h *HitBTC) CancelAllExistingOrders(ctx context.Context) ([]Order, error) { +func (e *Exchange) CancelAllExistingOrders(ctx context.Context) ([]Order, error) { var result []Order values := url.Values{} - return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, apiOrder, values, tradingRequests, @@ -381,7 +381,7 @@ func (h *HitBTC) CancelAllExistingOrders(ctx context.Context) ([]Order, error) { } // Withdraw allows for the withdrawal to a specific address -func (h *HitBTC) Withdraw(ctx context.Context, currency, address string, amount float64) (bool, error) { +func (e *Exchange) Withdraw(ctx context.Context, currency, address string, amount float64) (bool, error) { result := Withdraw{} values := url.Values{} @@ -389,7 +389,7 @@ func (h *HitBTC) Withdraw(ctx context.Context, currency, address string, amount values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2CryptoWithdraw, values, otherRequests, @@ -406,9 +406,9 @@ func (h *HitBTC) Withdraw(ctx context.Context, currency, address string, amount } // GetFeeInfo returns current fee information -func (h *HitBTC) GetFeeInfo(ctx context.Context, currencyPair string) (Fee, error) { +func (e *Exchange) GetFeeInfo(ctx context.Context, currencyPair string) (Fee, error) { result := Fee{} - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2FeeInfo+"/"+currencyPair, url.Values{}, tradingRequests, @@ -418,8 +418,8 @@ func (h *HitBTC) GetFeeInfo(ctx context.Context, currencyPair string) (Fee, erro } // SendHTTPRequest sends an unauthenticated HTTP request -func (h *HitBTC) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := h.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -428,23 +428,23 @@ func (h *HitBTC) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: h.Verbose, - HTTPDebugging: h.HTTPDebugging, - HTTPRecording: h.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return h.SendPayload(ctx, marketRequests, func() (*request.Item, error) { + return e.SendPayload(ctx, marketRequests, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated http request -func (h *HitBTC) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, f request.EndpointLimit, result any) error { - creds, err := h.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, f request.EndpointLimit, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := h.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -456,23 +456,23 @@ func (h *HitBTC) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U Path: ePoint + "/" + endpoint, Headers: headers, Result: result, - Verbose: h.Verbose, - HTTPDebugging: h.HTTPDebugging, - HTTPRecording: h.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return h.SendPayload(ctx, f, func() (*request.Item, error) { + return e.SendPayload(ctx, f, func() (*request.Item, error) { item.Body = bytes.NewBufferString(values.Encode()) return item, nil }, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (h *HitBTC) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feeInfo, err := h.GetFeeInfo(ctx, + feeInfo, err := e.GetFeeInfo(ctx, feeBuilder.Pair.Base.String()+ feeBuilder.Pair.Delimiter+ feeBuilder.Pair.Quote.String()) @@ -483,7 +483,7 @@ func (h *HitBTC) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (f feeBuilder.Amount, feeBuilder.IsMaker) case exchange.CryptocurrencyWithdrawalFee: - currencyInfo, err := h.GetCurrency(ctx, feeBuilder.Pair.Base.String()) + currencyInfo, err := e.GetCurrency(ctx, feeBuilder.Pair.Base.String()) if err != nil { return 0, err } diff --git a/exchanges/hitbtc/hitbtc_test.go b/exchanges/hitbtc/hitbtc_test.go index 7ff4c28c563..c8845339e96 100644 --- a/exchanges/hitbtc/hitbtc_test.go +++ b/exchanges/hitbtc/hitbtc_test.go @@ -27,7 +27,7 @@ import ( ) var ( - h *HitBTC + e *Exchange wsSetupRan bool ) @@ -41,18 +41,18 @@ const ( var spotPair = currency.NewBTCUSD().Format(currency.PairFormat{Uppercase: true}) func TestMain(m *testing.M) { - h = new(HitBTC) - if err := testexch.Setup(h); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("HitBTC Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - h.API.AuthenticatedSupport = true - h.API.AuthenticatedWebsocketSupport = true - h.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } - if err := h.UpdateTradablePairs(context.Background(), false); err != nil { + if err := e.UpdateTradablePairs(context.Background(), false); err != nil { log.Fatalf("HitBTC UpdateTradablePairs error: %s", err) } @@ -60,17 +60,17 @@ func TestMain(m *testing.M) { } func TestGetOrderbook(t *testing.T) { - _, err := h.GetOrderbook(t.Context(), spotPair.String(), 50) + _, err := e.GetOrderbook(t.Context(), spotPair.String(), 50) assert.NoError(t, err, "GetOrderbook should not error") } func TestGetTrades(t *testing.T) { - _, err := h.GetTrades(t.Context(), spotPair.String(), "", "", 0, 0, 0, 0) + _, err := e.GetTrades(t.Context(), spotPair.String(), "", "", 0, 0, 0, 0) assert.NoError(t, err, "GetTrades should not error") } func TestGetChartCandles(t *testing.T) { - _, err := h.GetCandles(t.Context(), spotPair.String(), "", "D1", time.Now().Add(-24*time.Hour), time.Now()) + _, err := e.GetCandles(t.Context(), spotPair.String(), "", "D1", time.Now().Add(-24*time.Hour), time.Now()) assert.NoError(t, err, "GetCandles should not error") } @@ -79,7 +79,7 @@ func TestGetHistoricCandles(t *testing.T) { startTime := time.Now().Add(-time.Hour * 6) end := time.Now() - _, err := h.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneMin, startTime, end) + _, err := e.GetHistoricCandles(t.Context(), spotPair, asset.Spot, kline.OneMin, startTime, end) assert.NoError(t, err, "GetHistoricCandles should not error") } @@ -88,12 +88,12 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err := h.GetHistoricCandlesExtended(t.Context(), spotPair, asset.Spot, kline.OneHour, startTime, end) + _, err := e.GetHistoricCandlesExtended(t.Context(), spotPair, asset.Spot, kline.OneHour, startTime, end) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") } func TestGetCurrencies(t *testing.T) { - _, err := h.GetCurrencies(t.Context()) + _, err := e.GetCurrencies(t.Context()) if err != nil { t.Error("Test failed - HitBTC GetCurrencies() error", err) } @@ -113,11 +113,11 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := h.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(h) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -133,11 +133,11 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - err = h.CurrencyPairs.StorePairs(asset.Spot, pairs, true) + err = e.CurrencyPairs.StorePairs(asset.Spot, pairs, true) if err != nil { t.Fatal(err) } - _, err = h.UpdateTicker(t.Context(), pairs[0], asset.Spot) + _, err = e.UpdateTicker(t.Context(), pairs[0], asset.Spot) if err != nil { t.Error(err) } @@ -145,34 +145,34 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - require.NoError(t, h.UpdateTickers(t.Context(), asset.Spot)) + require.NoError(t, e.UpdateTickers(t.Context(), asset.Spot)) - enabled, err := h.GetEnabledPairs(asset.Spot) + enabled, err := e.GetEnabledPairs(asset.Spot) require.NoError(t, err) for j := range enabled { - _, err = h.GetCachedTicker(enabled[j], asset.Spot) + _, err = e.GetCachedTicker(enabled[j], asset.Spot) require.NoErrorf(t, err, "GetCached Ticker must not error for pair %q", enabled[j]) } } func TestGetAllTickers(t *testing.T) { - _, err := h.GetTickers(t.Context()) + _, err := e.GetTickers(t.Context()) if err != nil { t.Error(err) } } func TestGetSingularTicker(t *testing.T) { - _, err := h.GetTicker(t.Context(), spotPair.String()) + _, err := e.GetTicker(t.Context(), spotPair.String()) assert.NoError(t, err, "GetTicker should not error") } func TestGetFee(t *testing.T) { feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(h) { + if sharedtestvalues.AreAPICredentialsSet(e) { // CryptocurrencyTradeFee Basic - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -180,32 +180,32 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Invalid currency feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -215,14 +215,14 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.CryptocurrencyDepositFee feeBuilder.Pair.Base = currency.BTC feeBuilder.Pair.Quote = currency.LTC - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -230,14 +230,14 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := h.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } func TestFormatWithdrawPermissions(t *testing.T) { expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := h.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -252,10 +252,10 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := h.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(h) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -269,10 +269,10 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := h.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(h) && err != nil { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -281,10 +281,10 @@ func TestGetOrderHistory(t *testing.T) { // ---------------------------------------------------------------------------------------------------------------------------- func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: h.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.DGD, Quote: currency.BTC, @@ -296,17 +296,17 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := h.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(h) && (err != nil || response.Status != order.New) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -316,18 +316,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := h.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(h) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -337,12 +337,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := h.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(h) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } @@ -353,9 +353,9 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - _, err := h.ModifyOrder(t.Context(), + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") @@ -364,10 +364,10 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: h.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -376,22 +376,22 @@ func TestWithdraw(t *testing.T) { }, } - _, err := h.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if !sharedtestvalues.AreAPICredentialsSet(h) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(h) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := h.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -399,10 +399,10 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := h.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -411,13 +411,13 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(h) { - _, err := h.GetDepositAddress(t.Context(), currency.XRP, "", "") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetDepositAddress(t.Context(), currency.XRP, "", "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := h.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -429,23 +429,23 @@ func setupWsAuth(t *testing.T) { if wsSetupRan { return } - if !h.Websocket.IsEnabled() && !h.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(h) { + if !e.Websocket.IsEnabled() && !e.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } var dialer gws.Dialer - err := h.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) if err != nil { t.Fatal(err) } - go h.wsReadData() - err = h.wsLogin(t.Context()) + go e.wsReadData() + err = e.wsLogin(t.Context()) if err != nil { t.Fatal(err) } timer := time.NewTimer(time.Second) select { - case loginError := <-h.Websocket.DataHandler: + case loginError := <-e.Websocket.DataHandler: t.Fatal(loginError) case <-timer.C: } @@ -459,7 +459,7 @@ func TestWsCancelOrder(t *testing.T) { if !canManipulateRealOrders { t.Skip("canManipulateRealOrders false, skipping test") } - _, err := h.wsCancelOrder(t.Context(), "ImNotARealOrderID") + _, err := e.wsCancelOrder(t.Context(), "ImNotARealOrderID") if err != nil { t.Fatal(err) } @@ -471,7 +471,7 @@ func TestWsPlaceOrder(t *testing.T) { if !canManipulateRealOrders { t.Skip("canManipulateRealOrders false, skipping test") } - _, err := h.wsPlaceOrder(t.Context(), currency.NewPair(currency.LTC, currency.BTC), order.Buy.String(), 1, 1) + _, err := e.wsPlaceOrder(t.Context(), currency.NewPair(currency.LTC, currency.BTC), order.Buy.String(), 1, 1) if err != nil { t.Fatal(err) } @@ -483,7 +483,7 @@ func TestWsReplaceOrder(t *testing.T) { if !canManipulateRealOrders { t.Skip("canManipulateRealOrders false, skipping test") } - _, err := h.wsReplaceOrder(t.Context(), "ImNotARealOrderID", 1, 1) + _, err := e.wsReplaceOrder(t.Context(), "ImNotARealOrderID", 1, 1) if err != nil { t.Fatal(err) } @@ -492,7 +492,7 @@ func TestWsReplaceOrder(t *testing.T) { // TestWsGetActiveOrders dials websocket, sends get active orders request. func TestWsGetActiveOrders(t *testing.T) { setupWsAuth(t) - if _, err := h.wsGetActiveOrders(t.Context()); err != nil { + if _, err := e.wsGetActiveOrders(t.Context()); err != nil { t.Fatal(err) } } @@ -500,7 +500,7 @@ func TestWsGetActiveOrders(t *testing.T) { // TestWsGetTradingBalance dials websocket, sends get trading balance request. func TestWsGetTradingBalance(t *testing.T) { setupWsAuth(t) - if _, err := h.wsGetTradingBalance(t.Context()); err != nil { + if _, err := e.wsGetTradingBalance(t.Context()); err != nil { t.Fatal(err) } } @@ -508,7 +508,7 @@ func TestWsGetTradingBalance(t *testing.T) { // TestWsGetTradingBalance dials websocket, sends get trading balance request. func TestWsGetTrades(t *testing.T) { setupWsAuth(t) - _, err := h.wsGetTrades(t.Context(), currency.NewPair(currency.ETH, currency.BTC), 1000, "ASC", "id") + _, err := e.wsGetTrades(t.Context(), currency.NewPair(currency.ETH, currency.BTC), 1000, "ASC", "id") if err != nil { t.Fatal(err) } @@ -517,7 +517,7 @@ func TestWsGetTrades(t *testing.T) { // TestWsGetTradingBalance dials websocket, sends get trading balance request. func TestWsGetSymbols(t *testing.T) { setupWsAuth(t) - _, err := h.wsGetSymbols(t.Context(), currency.NewPair(currency.ETH, currency.BTC)) + _, err := e.wsGetSymbols(t.Context(), currency.NewPair(currency.ETH, currency.BTC)) if err != nil { t.Fatal(err) } @@ -526,7 +526,7 @@ func TestWsGetSymbols(t *testing.T) { // TestWsGetCurrencies dials websocket, sends get trading balance request. func TestWsGetCurrencies(t *testing.T) { setupWsAuth(t) - _, err := h.wsGetCurrencies(t.Context(), currency.BTC) + _, err := e.wsGetCurrencies(t.Context(), currency.BTC) if err != nil { t.Fatal(err) } @@ -555,7 +555,7 @@ func TestWsGetActiveOrdersJSON(t *testing.T) { } ] }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -579,7 +579,7 @@ func TestWsGetCurrenciesJSON(t *testing.T) { }, "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -600,7 +600,7 @@ func TestWsGetSymbolsJSON(t *testing.T) { }, "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -623,7 +623,7 @@ func TestWsTicker(t *testing.T) { "symbol": "BTCUSD" } }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -667,7 +667,7 @@ func TestWsOrderbook(t *testing.T) { "timestamp": "2018-11-19T05:00:28.193Z" } }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -697,7 +697,7 @@ func TestWsOrderbook(t *testing.T) { "timestamp": "2018-11-19T05:00:28.700Z" } }`) - err = h.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -728,7 +728,7 @@ func TestWsOrderNotification(t *testing.T) { "tradeFee": "-0.000000005" } }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -755,7 +755,7 @@ func TestWsSubmitOrderJSON(t *testing.T) { }, "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -782,7 +782,7 @@ func TestWsCancelOrderJSON(t *testing.T) { }, "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -810,7 +810,7 @@ func TestWsCancelReplaceJSON(t *testing.T) { }, "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -838,7 +838,7 @@ func TestWsGetTradesRequestResponse(t *testing.T) { ], "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -868,7 +868,7 @@ func TestWsGetActiveOrdersRequestJSON(t *testing.T) { ], "id": 123 }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -905,7 +905,7 @@ func TestWsTrades(t *testing.T) { "symbol": "BTCUSD" } }`) - err := h.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -926,7 +926,7 @@ func TestWsTrades(t *testing.T) { "symbol": "BTCUSD" } } `) - err = h.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -966,24 +966,24 @@ func TestFormatExchangeKlineInterval(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := h.GetRecentTrades(t.Context(), spotPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), spotPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades should not error") } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := h.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.NoError(t, err, "GetHistoricTrades should not error") // longer term - _, err = h.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute*60*200), time.Now().Add(-time.Minute*60*199)) + _, err = e.GetHistoricTrades(t.Context(), spotPair, asset.Spot, time.Now().Add(-time.Minute*60*200), time.Now().Add(-time.Minute*60*199)) assert.NoError(t, err, "GetHistoricTrades should not error") } func TestGetActiveOrderByClientOrderID(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := h.GetActiveOrderByClientOrderID(t.Context(), "1234") + _, err := e.GetActiveOrderByClientOrderID(t.Context(), "1234") if err != nil { t.Error(err) } @@ -991,9 +991,9 @@ func TestGetActiveOrderByClientOrderID(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := h.GetOrderInfo(t.Context(), "1234", currency.NewBTCUSD(), asset.Spot) + _, err := e.GetOrderInfo(t.Context(), "1234", currency.NewBTCUSD(), asset.Spot) if err != nil { t.Error(err) } @@ -1001,19 +1001,19 @@ func TestGetOrderInfo(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - if _, err := h.FetchTradablePairs(t.Context(), asset.Spot); err != nil { + if _, err := e.FetchTradablePairs(t.Context(), asset.Spot); err != nil { t.Fatal(err) } } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, h) - for _, a := range h.GetAssetTypes(false) { - pairs, err := h.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := h.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } @@ -1022,17 +1022,17 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - h := new(HitBTC) - require.NoError(t, testexch.Setup(h), "Test instance Setup must not error") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - h.Websocket.SetCanUseAuthenticatedEndpoints(true) - require.True(t, h.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") - subs, err := h.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + require.True(t, e.Websocket.CanUseAuthenticatedEndpoints(), "CanUseAuthenticatedEndpoints must return true") + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - pairs, err := h.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) require.NoErrorf(t, err, "GetEnabledPairs must not error") - for _, s := range h.Features.Subscriptions { + for _, s := range e.Features.Subscriptions { for _, p := range pairs.Format(currency.PairFormat{Uppercase: true}) { s = s.Clone() s.Pairs = currency.Pairs{p} diff --git a/exchanges/hitbtc/hitbtc_websocket.go b/exchanges/hitbtc/hitbtc_websocket.go index 95d2e665ac7..1e04f844151 100644 --- a/exchanges/hitbtc/hitbtc_websocket.go +++ b/exchanges/hitbtc/hitbtc_websocket.go @@ -52,24 +52,24 @@ var defaultSubscriptions = subscription.List{ } // WsConnect starts a new connection with the websocket API -func (h *HitBTC) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !h.Websocket.IsEnabled() || !h.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := h.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - h.Websocket.Wg.Add(1) - go h.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() - if h.Websocket.CanUseAuthenticatedEndpoints() { - err = h.wsLogin(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.wsLogin(ctx) if err != nil { - log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", h.Name, err) + log.Errorf(log.ExchangeSys, "%v - authentication failed: %v\n", e.Name, err) } } @@ -77,33 +77,33 @@ func (h *HitBTC) WsConnect() error { } // wsReadData receives and passes on websocket messages for processing -func (h *HitBTC) wsReadData() { - defer h.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { - resp := h.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := h.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - h.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } -func (h *HitBTC) wsGetTableName(respRaw []byte) (string, error) { +func (e *Exchange) wsGetTableName(respRaw []byte) (string, error) { var init capture err := json.Unmarshal(respRaw, &init) if err != nil { return "", err } if init.Error.Code == errAuthFailed { - h.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } if init.ID > 0 { - if h.Websocket.Match.IncomingWithData(init.ID, respRaw) { + if e.Websocket.Match.IncomingWithData(init.ID, respRaw) { return "", nil } } @@ -132,7 +132,7 @@ func (h *HitBTC) wsGetTableName(respRaw []byte) (string, error) { } case []any: if len(resultType) == 0 { - h.Websocket.DataHandler <- fmt.Sprintf("No data returned. ID: %v", init.ID) + e.Websocket.DataHandler <- fmt.Sprintf("No data returned. ID: %v", init.ID) return "", nil } @@ -146,12 +146,12 @@ func (h *HitBTC) wsGetTableName(respRaw []byte) (string, error) { return "trading", nil } } - h.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: h.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return "", nil } -func (h *HitBTC) wsHandleData(respRaw []byte) error { - name, err := h.wsGetTableName(respRaw) +func (e *Exchange) wsHandleData(respRaw []byte) error { + name, err := e.wsGetTableName(respRaw) if err != nil { return err } @@ -165,12 +165,12 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { return err } - pairs, err := h.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := h.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -182,8 +182,8 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { return err } - h.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: h.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Open: wsTicker.Params.Open, Volume: wsTicker.Params.Volume, QuoteVolume: wsTicker.Params.VolumeQuote, @@ -202,7 +202,7 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { if err != nil { return err } - err = h.WsProcessOrderbookSnapshot(&obSnapshot) + err = e.WsProcessOrderbookSnapshot(&obSnapshot) if err != nil { return err } @@ -212,12 +212,12 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { if err != nil { return err } - err = h.WsProcessOrderbookUpdate(&obUpdate) + err = e.WsProcessOrderbookUpdate(&obUpdate) if err != nil { return err } case "snapshotTrades", "updateTrades": - if !h.IsSaveTradeDataEnabled() { + if !e.IsSaveTradeDataEnabled() { return nil } var tradeSnapshot WsTrade @@ -229,7 +229,7 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { p, err := currency.NewPairFromString(tradeSnapshot.Params.Symbol) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, Err: err, } } @@ -237,13 +237,13 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { side, err := order.StringToOrderSide(tradeSnapshot.Params.Data[i].Side) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, Err: err, } } trades = append(trades, trade.Data{ Timestamp: tradeSnapshot.Params.Data[i].Timestamp, - Exchange: h.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: asset.Spot, Price: tradeSnapshot.Params.Data[i].Price, @@ -260,7 +260,7 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { return err } for i := range o.Params { - err = h.wsHandleOrderData(&o.Params[i]) + err = e.wsHandleOrderData(&o.Params[i]) if err != nil { return err } @@ -271,14 +271,14 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { if err != nil { return err } - h.Websocket.DataHandler <- trades + e.Websocket.DataHandler <- trades case "report": var o wsReportResponse err := json.Unmarshal(respRaw, &o) if err != nil { return err } - err = h.wsHandleOrderData(&o.OrderData) + err = e.wsHandleOrderData(&o.OrderData) if err != nil { return err } @@ -289,7 +289,7 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { return err } for i := range o.OrderData { - err = h.wsHandleOrderData(&o.OrderData[i]) + err = e.wsHandleOrderData(&o.OrderData[i]) if err != nil { return err } @@ -300,19 +300,19 @@ func (h *HitBTC) wsHandleData(respRaw []byte) error { if err != nil { return err } - err = h.wsHandleOrderData(&o.OrderData) + err = e.wsHandleOrderData(&o.OrderData) if err != nil { return err } default: - h.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: h.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } return nil } // WsProcessOrderbookSnapshot processes a full orderbook snapshot to a local cache -func (h *HitBTC) WsProcessOrderbookSnapshot(ob *WsOrderbook) error { +func (e *Exchange) WsProcessOrderbookSnapshot(ob *WsOrderbook) error { if len(ob.Params.Bid) == 0 || len(ob.Params.Ask) == 0 { return errors.New("no orderbooks to process") } @@ -334,12 +334,12 @@ func (h *HitBTC) WsProcessOrderbookSnapshot(ob *WsOrderbook) error { } } - pairs, err := h.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := h.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -348,35 +348,35 @@ func (h *HitBTC) WsProcessOrderbookSnapshot(ob *WsOrderbook) error { pairs, format) if err != nil { - h.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err return err } newOrderBook.Asset = asset.Spot newOrderBook.Pair = p - newOrderBook.Exchange = h.Name - newOrderBook.ValidateOrderbook = h.ValidateOrderbook + newOrderBook.Exchange = e.Name + newOrderBook.ValidateOrderbook = e.ValidateOrderbook newOrderBook.LastUpdated = ob.Params.Timestamp - return h.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } -func (h *HitBTC) wsHandleOrderData(o *wsOrderData) error { +func (e *Exchange) wsHandleOrderData(o *wsOrderData) error { var trades []order.TradeHistory if o.TradeID > 0 { trades = append(trades, order.TradeHistory{ Price: o.TradePrice, Amount: o.TradeQuantity, Fee: o.TradeFee, - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatFloat(o.TradeID, 'f', -1, 64), Timestamp: o.UpdatedAt, }) } oType, err := order.StringToOrderType(o.Type) if err != nil { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: o.ID, Err: err, } @@ -384,16 +384,16 @@ func (h *HitBTC) wsHandleOrderData(o *wsOrderData) error { o.Status = strings.Replace(o.Status, "canceled", "cancelled", 1) oStatus, err := order.StringToOrderStatus(o.Status) if err != nil { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: o.ID, Err: err, } } oSide, err := order.StringToOrderSide(o.Side) if err != nil { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: o.ID, Err: err, } @@ -401,24 +401,24 @@ func (h *HitBTC) wsHandleOrderData(o *wsOrderData) error { p, err := currency.NewPairFromString(o.Symbol) if err != nil { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: o.ID, Err: err, } } var a asset.Item - a, err = h.GetPairAssetType(p) + a, err = e.GetPairAssetType(p) if err != nil { return err } - h.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: o.Price, Amount: o.Quantity, ExecutedAmount: o.CumQuantity, RemainingAmount: o.Quantity - o.CumQuantity, - Exchange: h.Name, + Exchange: e.Name, OrderID: o.ID, Type: oType, Side: oSide, @@ -433,7 +433,7 @@ func (h *HitBTC) wsHandleOrderData(o *wsOrderData) error { } // WsProcessOrderbookUpdate updates a local cache -func (h *HitBTC) WsProcessOrderbookUpdate(update *WsOrderbook) error { +func (e *Exchange) WsProcessOrderbookUpdate(update *WsOrderbook) error { if len(update.Params.Bid) == 0 && len(update.Params.Ask) == 0 { // Periodically HitBTC sends empty updates which includes a sequence // can return this as nil. @@ -456,12 +456,12 @@ func (h *HitBTC) WsProcessOrderbookUpdate(update *WsOrderbook) error { } } - pairs, err := h.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } - format, err := h.GetPairFormat(asset.Spot, true) + format, err := e.GetPairFormat(asset.Spot, true) if err != nil { return err } @@ -473,7 +473,7 @@ func (h *HitBTC) WsProcessOrderbookUpdate(update *WsOrderbook) error { return err } - return h.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Asks: asks, Bids: bids, Pair: p, @@ -484,12 +484,12 @@ func (h *HitBTC) WsProcessOrderbookUpdate(update *WsOrderbook) error { } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (h *HitBTC) generateSubscriptions() (subscription.List, error) { - return h.Features.Subscriptions.ExpandTemplates(h) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (h *HitBTC) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(sprig.FuncMap()).Funcs(template.FuncMap{ "subToReq": subToReq, "isSymbolChannel": isSymbolChannel, @@ -502,36 +502,36 @@ const ( ) // Subscribe sends a websocket message to receive data from the channel -func (h *HitBTC) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - return h.ParallelChanOp(ctx, subs, func(ctx context.Context, subs subscription.List) error { return h.manageSubs(ctx, subscribeOp, subs) }, 1) + return e.ParallelChanOp(ctx, subs, func(ctx context.Context, subs subscription.List) error { return e.manageSubs(ctx, subscribeOp, subs) }, 1) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (h *HitBTC) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - return h.ParallelChanOp(ctx, subs, func(ctx context.Context, subs subscription.List) error { return h.manageSubs(ctx, unsubscribeOp, subs) }, 1) + return e.ParallelChanOp(ctx, subs, func(ctx context.Context, subs subscription.List) error { return e.manageSubs(ctx, unsubscribeOp, subs) }, 1) } -func (h *HitBTC) manageSubs(ctx context.Context, op string, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.List) error { var errs error - subs, errs = subs.ExpandTemplates(h) + subs, errs = subs.ExpandTemplates(e) for _, s := range subs { r := WsRequest{ JSONRPCVersion: rpcVersion, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } if err := json.Unmarshal([]byte(s.QualifiedChannel), &r); err != nil { errs = common.AppendError(errs, err) continue } r.Method = op + r.Method - err := h.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) // v2 api does not return an ID with errors, so we don't use ReturnResponse + err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, r) // v2 api does not return an ID with errors, so we don't use ReturnResponse if err == nil { if op == subscribeOp { - err = h.Websocket.AddSuccessfulSubscriptions(h.Websocket.Conn, s) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) } else { - err = h.Websocket.RemoveSubscriptions(h.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } } if err != nil { @@ -542,15 +542,15 @@ func (h *HitBTC) manageSubs(ctx context.Context, op string, subs subscription.Li } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (h *HitBTC) wsLogin(ctx context.Context) error { - if !h.IsWebsocketAuthenticationSupported() { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) +func (e *Exchange) wsLogin(ctx context.Context) error { + if !e.IsWebsocketAuthenticationSupported() { + return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", e.Name) } - creds, err := h.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - h.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) n := strconv.FormatInt(time.Now().Unix(), 10) hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte(n), []byte(creds.Secret)) if err != nil { @@ -565,12 +565,12 @@ func (h *HitBTC) wsLogin(ctx context.Context) error { Nonce: n, Signature: hex.EncodeToString(hmac), }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - err = h.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) if err != nil { - h.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) return err } @@ -578,13 +578,13 @@ func (h *HitBTC) wsLogin(ctx context.Context) error { } // wsPlaceOrder sends a websocket message to submit an order -func (h *HitBTC) wsPlaceOrder(ctx context.Context, pair currency.Pair, side string, price, quantity float64) (*WsSubmitOrderSuccessResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name) +func (e *Exchange) wsPlaceOrder(ctx context.Context, pair currency.Pair, side string, price, quantity float64) (*WsSubmitOrderSuccessResponse, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authenticated, cannot place order", e.Name) } - id := h.Websocket.Conn.GenerateMessageID(false) - fPair, err := h.FormatExchangeCurrency(pair, asset.Spot) + id := e.Websocket.Conn.GenerateMessageID(false) + fPair, err := e.FormatExchangeCurrency(pair, asset.Spot) if err != nil { return nil, err } @@ -600,52 +600,52 @@ func (h *HitBTC) wsPlaceOrder(ctx context.Context, pair currency.Pair, side stri }, ID: id, } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, id, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, id, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsSubmitOrderSuccessResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsCancelOrder sends a websocket message to cancel an order -func (h *HitBTC) wsCancelOrder(ctx context.Context, clientOrderID string) (*WsCancelOrderResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name) +func (e *Exchange) wsCancelOrder(ctx context.Context, clientOrderID string) (*WsCancelOrderResponse, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authenticated, cannot place order", e.Name) } req := WsCancelOrderRequest{ Method: "cancelOrder", Params: WsCancelOrderRequestData{ ClientOrderID: clientOrderID, }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsCancelOrderResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsReplaceOrder sends a websocket message to replace an order -func (h *HitBTC) wsReplaceOrder(ctx context.Context, clientOrderID string, quantity, price float64) (*WsReplaceOrderResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name) +func (e *Exchange) wsReplaceOrder(ctx context.Context, clientOrderID string, quantity, price float64) (*WsReplaceOrderResponse, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authenticated, cannot place order", e.Name) } req := WsReplaceOrderRequest{ Method: "cancelReplaceOrder", @@ -655,100 +655,100 @@ func (h *HitBTC) wsReplaceOrder(ctx context.Context, clientOrderID string, quant Quantity: quantity, Price: price, }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsReplaceOrderResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsGetActiveOrders sends a websocket message to get all active orders -func (h *HitBTC) wsGetActiveOrders(ctx context.Context) (*wsActiveOrdersResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated, cannot get active orders", h.Name) +func (e *Exchange) wsGetActiveOrders(ctx context.Context) (*wsActiveOrdersResponse, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authenticated, cannot get active orders", e.Name) } req := WsReplaceOrderRequest{ Method: "getOrders", Params: WsReplaceOrderRequestData{}, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response wsActiveOrdersResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsGetTradingBalance sends a websocket message to get trading balance -func (h *HitBTC) wsGetTradingBalance(ctx context.Context) (*WsGetTradingBalanceResponse, error) { - if !h.Websocket.CanUseAuthenticatedEndpoints() { - return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name) +func (e *Exchange) wsGetTradingBalance(ctx context.Context) (*WsGetTradingBalanceResponse, error) { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return nil, fmt.Errorf("%v not authenticated, cannot place order", e.Name) } req := WsReplaceOrderRequest{ Method: "getTradingBalance", Params: WsReplaceOrderRequestData{}, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsGetTradingBalanceResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsGetCurrencies sends a websocket message to get trading balance -func (h *HitBTC) wsGetCurrencies(ctx context.Context, currencyItem currency.Code) (*WsGetCurrenciesResponse, error) { +func (e *Exchange) wsGetCurrencies(ctx context.Context, currencyItem currency.Code) (*WsGetCurrenciesResponse, error) { req := WsGetCurrenciesRequest{ Method: "getCurrency", Params: WsGetCurrenciesRequestParameters{ Currency: currencyItem, }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsGetCurrenciesResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsGetSymbols sends a websocket message to get trading balance -func (h *HitBTC) wsGetSymbols(ctx context.Context, c currency.Pair) (*WsGetSymbolsResponse, error) { - fPair, err := h.FormatExchangeCurrency(c, asset.Spot) +func (e *Exchange) wsGetSymbols(ctx context.Context, c currency.Pair) (*WsGetSymbolsResponse, error) { + fPair, err := e.FormatExchangeCurrency(c, asset.Spot) if err != nil { return nil, err } @@ -758,26 +758,26 @@ func (h *HitBTC) wsGetSymbols(ctx context.Context, c currency.Pair) (*WsGetSymbo Params: WsGetSymbolsRequestParameters{ Symbol: fPair.String(), }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsGetSymbolsResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } // wsGetSymbols sends a websocket message to get trading balance -func (h *HitBTC) wsGetTrades(ctx context.Context, c currency.Pair, limit int64, sort, by string) (*WsGetTradesResponse, error) { - fPair, err := h.FormatExchangeCurrency(c, asset.Spot) +func (e *Exchange) wsGetTrades(ctx context.Context, c currency.Pair, limit int64, sort, by string) (*WsGetTradesResponse, error) { + fPair, err := e.FormatExchangeCurrency(c, asset.Spot) if err != nil { return nil, err } @@ -790,19 +790,19 @@ func (h *HitBTC) wsGetTrades(ctx context.Context, c currency.Pair, limit int64, Sort: sort, By: by, }, - ID: h.Websocket.Conn.GenerateMessageID(false), + ID: e.Websocket.Conn.GenerateMessageID(false), } - resp, err := h.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) + resp, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, req.ID, req) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } var response WsGetTradesResponse err = json.Unmarshal(resp, &response) if err != nil { - return nil, fmt.Errorf("%v %v", h.Name, err) + return nil, fmt.Errorf("%v %v", e.Name, err) } if response.Error.Code > 0 || response.Error.Message != "" { - return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message) + return &response, fmt.Errorf("%v Error:%v Message:%v", e.Name, response.Error.Code, response.Error.Message) } return &response, nil } diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 6da0bb9e995..18fa0609a2a 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -32,21 +32,21 @@ import ( ) // SetDefaults sets default settings for hitbtc -func (h *HitBTC) SetDefaults() { - h.Name = "HitBTC" - h.Enabled = true - h.Verbose = true - h.API.CredentialsValidator.RequiresKey = true - h.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "HitBTC" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{Uppercase: true} configFmt := ¤cy.PairFormat{Delimiter: currency.DashDelimiter, Uppercase: true} - err := h.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - h.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -111,55 +111,55 @@ func (h *HitBTC) SetDefaults() { Subscriptions: defaultSubscriptions.Clone(), } - h.Requester, err = request.New(h.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - h.API.Endpoints = h.NewEndpoints() - err = h.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: apiURL, exchange.WebsocketSpot: hitbtcWebsocketAddress, }) if err != nil { log.Errorln(log.ExchangeSys, err) } - h.Websocket = websocket.NewManager() - h.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - h.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - h.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets user exchange configuration settings -func (h *HitBTC) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - h.SetEnabled(false) + e.SetEnabled(false) return nil } - err = h.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := h.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = h.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: hitbtcWebsocketAddress, RunningURL: wsRunningURL, - Connector: h.WsConnect, - Subscriber: h.Subscribe, - Unsubscriber: h.Unsubscribe, - GenerateSubscriptions: h.generateSubscriptions, - Features: &h.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, @@ -169,7 +169,7 @@ func (h *HitBTC) Setup(exch *config.Exchange) error { return err } - return h.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ RateLimit: request.NewWeightedRateLimitByDuration(20 * time.Millisecond), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -177,8 +177,8 @@ func (h *HitBTC) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (h *HitBTC) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - symbols, err := h.GetSymbolsDetailed(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + symbols, err := e.GetSymbolsDetailed(ctx) if err != nil { return nil, err } @@ -198,21 +198,21 @@ func (h *HitBTC) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (h *HitBTC) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := h.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = h.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return h.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (h *HitBTC) UpdateTickers(ctx context.Context, a asset.Item) error { - tick, err := h.GetTickers(ctx) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := e.GetTickers(ctx) if err != nil { return err } @@ -220,7 +220,7 @@ func (h *HitBTC) UpdateTickers(ctx context.Context, a asset.Item) error { for x := range tick { var pair currency.Pair var enabled bool - pair, enabled, err = h.MatchSymbolCheckEnabled(tick[x].Symbol, a, false) + pair, enabled, err = e.MatchSymbolCheckEnabled(tick[x].Symbol, a, false) if err != nil { if !errors.Is(err, currency.ErrPairNotFound) { return err @@ -242,7 +242,7 @@ func (h *HitBTC) UpdateTickers(ctx context.Context, a asset.Item) error { Open: tick[x].Open, Pair: pair, LastUpdated: tick[x].Timestamp, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -253,33 +253,33 @@ func (h *HitBTC) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (h *HitBTC) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := h.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(h.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if c.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := h.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: h.Name, + Exchange: e.Name, Pair: c, Asset: assetType, - ValidateOrderbook: h.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := h.FormatExchangeCurrency(c, assetType) + fPair, err := e.FormatExchangeCurrency(c, assetType) if err != nil { return book, err } - orderbookNew, err := h.GetOrderbook(ctx, fPair.String(), 1000) + orderbookNew, err := e.GetOrderbook(ctx, fPair.String(), 1000) if err != nil { return book, err } @@ -302,15 +302,15 @@ func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(h.Name, c, assetType) + return orderbook.Get(e.Name, c, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // HitBTC exchange -func (h *HitBTC) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = h.Name - accountBalance, err := h.GetBalances(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetBalances(ctx) if err != nil { return response, err } @@ -330,7 +330,7 @@ func (h *HitBTC) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a Currencies: currencies, }) - creds, err := h.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -344,29 +344,29 @@ func (h *HitBTC) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (h *HitBTC) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { // TODO supported in v3 API return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (h *HitBTC) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { // TODO supported in v3 API return nil, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (h *HitBTC) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return h.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (h *HitBTC) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - p, err = h.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -376,7 +376,7 @@ func (h *HitBTC) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTy allTrades: for { var tradeData []TradeHistory - tradeData, err = h.GetTrades(ctx, + tradeData, err = e.GetTrades(ctx, p.String(), "", "", @@ -397,7 +397,7 @@ allTrades: return nil, err } resp = append(resp, trade.Data{ - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].ID, 10), CurrencyPair: p, AssetType: assetType, @@ -419,7 +419,7 @@ allTrades: } } - err = h.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -429,17 +429,17 @@ allTrades: } // SubmitOrder submits a new order -func (h *HitBTC) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { - err := o.Validate(h.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { + err := o.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } var orderID string status := order.New - if h.Websocket.IsConnected() && h.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedEndpoints() { var response *WsSubmitOrderSuccessResponse - response, err = h.wsPlaceOrder(ctx, o.Pair, o.Side.String(), o.Amount, o.Price) + response, err = e.wsPlaceOrder(ctx, o.Pair, o.Side.String(), o.Amount, o.Price) if err != nil { return nil, err } @@ -449,13 +449,13 @@ func (h *HitBTC) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Submi } } else { var fPair currency.Pair - fPair, err = h.FormatExchangeCurrency(o.Pair, o.AssetType) + fPair, err = e.FormatExchangeCurrency(o.Pair, o.AssetType) if err != nil { return nil, err } var response OrderResponse - response, err = h.PlaceOrder(ctx, + response, err = e.PlaceOrder(ctx, fPair.String(), o.Price, o.Amount, @@ -479,12 +479,12 @@ func (h *HitBTC) SubmitOrder(ctx context.Context, o *order.Submit) (*order.Submi // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HitBTC) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (h *HitBTC) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -494,27 +494,27 @@ func (h *HitBTC) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } - _, err = h.CancelExistingOrder(ctx, orderIDInt) + _, err = e.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (h *HitBTC) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (h *HitBTC) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) { return time.Time{}, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (h *HitBTC) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - resp, err := h.CancelAllExistingOrders(ctx) + resp, err := e.CancelAllExistingOrders(ctx) if err != nil { return cancelAllOrdersResponse, err } @@ -531,19 +531,19 @@ func (h *HitBTC) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Ca } // GetOrderInfo returns order information based on order ID -func (h *HitBTC) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := h.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - resp, err := h.GetActiveOrderByClientOrderID(ctx, orderID) + resp, err := e.GetActiveOrderByClientOrderID(ctx, orderID) if err != nil { return nil, err } - format, err := h.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -557,7 +557,7 @@ func (h *HitBTC) GetOrderInfo(ctx context.Context, orderID string, pair currency return &order.Detail{ OrderID: resp.ID, Amount: resp.Quantity, - Exchange: h.Name, + Exchange: e.Name, Price: resp.Price, Date: resp.CreatedAt, Side: side, @@ -566,8 +566,8 @@ func (h *HitBTC) GetOrderInfo(ctx context.Context, orderID string, pair currency } // GetDepositAddress returns a deposit address for a specified currency -func (h *HitBTC) GetDepositAddress(ctx context.Context, currency currency.Code, _, _ string) (*deposit.Address, error) { - resp, err := h.GetDepositAddresses(ctx, currency.String()) +func (e *Exchange) GetDepositAddress(ctx context.Context, currency currency.Code, _, _ string) (*deposit.Address, error) { + resp, err := e.GetDepositAddresses(ctx, currency.String()) if err != nil { return nil, err } @@ -580,11 +580,11 @@ func (h *HitBTC) GetDepositAddress(ctx context.Context, currency currency.Code, // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (h *HitBTC) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := h.Withdraw(ctx, + v, err := e.Withdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Amount) @@ -598,30 +598,30 @@ func (h *HitBTC) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (h *HitBTC) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (h *HitBTC) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (h *HitBTC) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !h.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return h.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -634,14 +634,14 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque var allOrders []OrderHistoryResponse for i := range req.Pairs { var resp []OrderHistoryResponse - resp, err = h.GetOpenOrders(ctx, req.Pairs[i].String()) + resp, err = e.GetOpenOrders(ctx, req.Pairs[i].String()) if err != nil { return nil, err } allOrders = append(allOrders, resp...) } - format, err := h.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -662,19 +662,19 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque orders[i] = order.Detail{ OrderID: allOrders[i].ID, Amount: allOrders[i].Quantity, - Exchange: h.Name, + Exchange: e.Name, Price: allOrders[i].Price, Date: allOrders[i].CreatedAt, Side: side, Pair: symbol, } } - return req.Filter(h.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -687,14 +687,14 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var allOrders []OrderHistoryResponse for i := range req.Pairs { var resp []OrderHistoryResponse - resp, err = h.GetOrders(ctx, req.Pairs[i].String()) + resp, err = e.GetOrders(ctx, req.Pairs[i].String()) if err != nil { return nil, err } allOrders = append(allOrders, resp...) } - format, err := h.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -710,19 +710,19 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque var side order.Side side, err = order.StringToOrderSide(allOrders[i].Side) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", h.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var status order.Status status, err = order.StringToOrderStatus(allOrders[i].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", h.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } detail := order.Detail{ OrderID: allOrders[i].ID, Amount: allOrders[i].Quantity, ExecutedAmount: allOrders[i].CumQuantity, RemainingAmount: allOrders[i].Quantity - allOrders[i].CumQuantity, - Exchange: h.Name, + Exchange: e.Name, Price: allOrders[i].Price, AverageExecutedPrice: allOrders[i].AvgPrice, Date: allOrders[i].CreatedAt, @@ -734,19 +734,19 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.MultiOrderReque detail.InferCostsAndTimes() orders[i] = detail } - return req.Filter(h.Name, orders), nil + return req.Filter(e.Name, orders), nil } // AuthenticateWebsocket sends an authentication message to the websocket -func (h *HitBTC) AuthenticateWebsocket(ctx context.Context) error { - return h.wsLogin(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.wsLogin(ctx) } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (h *HitBTC) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := h.UpdateAccountInfo(ctx, assetType) - return h.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // formatExchangeKlineInterval returns Interval to exchange formatted string @@ -777,8 +777,8 @@ func formatExchangeKlineInterval(in kline.Interval) (string, error) { } // GetHistoricCandles returns candles between a time period for a set time interval -func (h *HitBTC) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := h.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } @@ -788,7 +788,7 @@ func (h *HitBTC) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a return nil, err } - data, err := h.GetCandles(ctx, + data, err := e.GetCandles(ctx, req.RequestFormatted.String(), strconv.FormatUint(req.RequestLimit, 10), formattedInterval, @@ -813,8 +813,8 @@ func (h *HitBTC) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (h *HitBTC) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := h.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -827,7 +827,7 @@ func (h *HitBTC) GetHistoricCandlesExtended(ctx context.Context, pair currency.P timeSeries := make([]kline.Candle, 0, req.Size()) for y := range req.RangeHolder.Ranges { var data []ChartData - data, err = h.GetCandles(ctx, + data, err = e.GetCandles(ctx, req.RequestFormatted.String(), strconv.FormatUint(req.RequestLimit, 10), formattedInterval, @@ -852,23 +852,23 @@ func (h *HitBTC) GetHistoricCandlesExtended(ctx context.Context, pair currency.P } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (h *HitBTC) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (h *HitBTC) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (h *HitBTC) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (h *HitBTC) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := h.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 5c870992385..013f376beae 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -78,8 +78,8 @@ const ( huobiBatchContracts = "/v2/market/detail/batch_merged" ) -// HUOBI is the overarching type across this package -type HUOBI struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Huobi +type Exchange struct { exchange.Base AccountID string futureContractCodesMutex sync.RWMutex @@ -87,24 +87,24 @@ type HUOBI struct { } // GetMarginRates gets margin rates -func (h *HUOBI) GetMarginRates(ctx context.Context, symbol currency.Pair) (MarginRatesData, error) { +func (e *Exchange) GetMarginRates(ctx context.Context, symbol currency.Pair) (MarginRatesData, error) { var resp MarginRatesData vals := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp, err } vals.Set("symbol", symbolValue) } - return resp, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginRates, vals, nil, &resp, false) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginRates, vals, nil, &resp, false) } // GetSpotKline returns kline data // KlinesRequestParams contains symbol currency.Pair, period and size -func (h *HUOBI) GetSpotKline(ctx context.Context, arg KlinesRequestParams) ([]KlineItem, error) { +func (e *Exchange) GetSpotKline(ctx context.Context, arg KlinesRequestParams) ([]KlineItem, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return nil, err } @@ -122,7 +122,7 @@ func (h *HUOBI) GetSpotKline(ctx context.Context, arg KlinesRequestParams) ([]Kl var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketHistoryKline, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketHistoryKline, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -130,54 +130,54 @@ func (h *HUOBI) GetSpotKline(ctx context.Context, arg KlinesRequestParams) ([]Kl } // Get24HrMarketSummary returns 24hr market summary for a given market symbol -func (h *HUOBI) Get24HrMarketSummary(ctx context.Context, symbol currency.Pair) (MarketSummary24Hr, error) { +func (e *Exchange) Get24HrMarketSummary(ctx context.Context, symbol currency.Pair) (MarketSummary24Hr, error) { var result MarketSummary24Hr params := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return result, err } params.Set("symbol", symbolValue) - return result, h.SendHTTPRequest(ctx, exchange.RestSpot, huobi24HrMarketSummary+params.Encode(), &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, huobi24HrMarketSummary+params.Encode(), &result) } // GetBatchCoinMarginSwapContracts returns the tickers for coin margined swap contracts -func (h *HUOBI) GetBatchCoinMarginSwapContracts(ctx context.Context) ([]FuturesBatchTicker, error) { +func (e *Exchange) GetBatchCoinMarginSwapContracts(ctx context.Context) ([]FuturesBatchTicker, error) { var result struct { Data []FuturesBatchTicker `json:"ticks"` } - err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchCoinMarginSwapContracts, &result) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchCoinMarginSwapContracts, &result) return result.Data, err } // GetBatchLinearSwapContracts returns the tickers for linear swap contracts -func (h *HUOBI) GetBatchLinearSwapContracts(ctx context.Context) ([]FuturesBatchTicker, error) { +func (e *Exchange) GetBatchLinearSwapContracts(ctx context.Context) ([]FuturesBatchTicker, error) { var result struct { Data []FuturesBatchTicker `json:"ticks"` } - err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchLinearSwapContracts, &result) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchLinearSwapContracts, &result) return result.Data, err } // GetBatchFuturesContracts returns the tickers for futures contracts -func (h *HUOBI) GetBatchFuturesContracts(ctx context.Context) ([]FuturesBatchTicker, error) { +func (e *Exchange) GetBatchFuturesContracts(ctx context.Context) ([]FuturesBatchTicker, error) { var result struct { Data []FuturesBatchTicker `json:"ticks"` } - err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchContracts, &result) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, huobiBatchContracts, &result) return result.Data, err } // GetTickers returns the ticker for the specified symbol -func (h *HUOBI) GetTickers(ctx context.Context) (Tickers, error) { +func (e *Exchange) GetTickers(ctx context.Context) (Tickers, error) { var result Tickers - return result, h.SendHTTPRequest(ctx, exchange.RestSpot, huobiMarketTickers, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, huobiMarketTickers, &result) } // GetMarketDetailMerged returns the ticker for the specified symbol -func (h *HUOBI) GetMarketDetailMerged(ctx context.Context, symbol currency.Pair) (DetailMerged, error) { +func (e *Exchange) GetMarketDetailMerged(ctx context.Context, symbol currency.Pair) (DetailMerged, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return DetailMerged{}, err } @@ -190,7 +190,7 @@ func (h *HUOBI) GetMarketDetailMerged(ctx context.Context, symbol currency.Pair) var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDetailMerged, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDetailMerged, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -198,8 +198,8 @@ func (h *HUOBI) GetMarketDetailMerged(ctx context.Context, symbol currency.Pair) } // GetDepth returns the depth for the specified symbol -func (h *HUOBI) GetDepth(ctx context.Context, obd *OrderBookDataRequestParams) (*Orderbook, error) { - symbolValue, err := h.FormatSymbol(obd.Symbol, asset.Spot) +func (e *Exchange) GetDepth(ctx context.Context, obd *OrderBookDataRequestParams) (*Orderbook, error) { + symbolValue, err := e.FormatSymbol(obd.Symbol, asset.Spot) if err != nil { return nil, err } @@ -216,7 +216,7 @@ func (h *HUOBI) GetDepth(ctx context.Context, obd *OrderBookDataRequestParams) ( } var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDepth, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDepth, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -224,9 +224,9 @@ func (h *HUOBI) GetDepth(ctx context.Context, obd *OrderBookDataRequestParams) ( } // GetTrades returns the trades for the specified symbol -func (h *HUOBI) GetTrades(ctx context.Context, symbol currency.Pair) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, symbol currency.Pair) ([]Trade, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (h *HUOBI) GetTrades(ctx context.Context, symbol currency.Pair) ([]Trade, e var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketTrade, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketTrade, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -251,8 +251,8 @@ func (h *HUOBI) GetTrades(ctx context.Context, symbol currency.Pair) ([]Trade, e // GetLatestSpotPrice returns latest spot price of symbol // // symbol: string of currency pair -func (h *HUOBI) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (float64, error) { - list, err := h.GetTradeHistory(ctx, symbol, 1) +func (e *Exchange) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (float64, error) { + list, err := e.GetTradeHistory(ctx, symbol, 1) if err != nil { return 0, err } @@ -264,9 +264,9 @@ func (h *HUOBI) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (f } // GetTradeHistory returns the trades for the specified symbol -func (h *HUOBI) GetTradeHistory(ctx context.Context, symbol currency.Pair, size int64) ([]TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, symbol currency.Pair, size int64) ([]TradeHistory, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -283,7 +283,7 @@ func (h *HUOBI) GetTradeHistory(ctx context.Context, symbol currency.Pair, size var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketTradeHistory, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketTradeHistory, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -291,9 +291,9 @@ func (h *HUOBI) GetTradeHistory(ctx context.Context, symbol currency.Pair, size } // GetMarketDetail returns the ticker for the specified symbol -func (h *HUOBI) GetMarketDetail(ctx context.Context, symbol currency.Pair) (Detail, error) { +func (e *Exchange) GetMarketDetail(ctx context.Context, symbol currency.Pair) (Detail, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return Detail{}, err } @@ -306,7 +306,7 @@ func (h *HUOBI) GetMarketDetail(ctx context.Context, symbol currency.Pair) (Deta var result response - err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDetail, vals), &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(huobiMarketDetail, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -314,7 +314,7 @@ func (h *HUOBI) GetMarketDetail(ctx context.Context, symbol currency.Pair) (Deta } // GetSymbols returns an array of symbols supported by Huobi -func (h *HUOBI) GetSymbols(ctx context.Context) ([]Symbol, error) { +func (e *Exchange) GetSymbols(ctx context.Context) ([]Symbol, error) { type response struct { Response Symbols []Symbol `json:"data"` @@ -322,7 +322,7 @@ func (h *HUOBI) GetSymbols(ctx context.Context) ([]Symbol, error) { var result response - err := h.SendHTTPRequest(ctx, exchange.RestSpot, huobiSymbols, &result) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, huobiSymbols, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -330,7 +330,7 @@ func (h *HUOBI) GetSymbols(ctx context.Context) ([]Symbol, error) { } // GetCurrencies returns a list of currencies supported by Huobi -func (h *HUOBI) GetCurrencies(ctx context.Context) ([]string, error) { +func (e *Exchange) GetCurrencies(ctx context.Context) ([]string, error) { type response struct { Response Currencies []string `json:"data"` @@ -338,7 +338,7 @@ func (h *HUOBI) GetCurrencies(ctx context.Context) ([]string, error) { var result response - err := h.SendHTTPRequest(ctx, exchange.RestSpot, huobiCurrencies, &result) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, huobiCurrencies, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -346,7 +346,7 @@ func (h *HUOBI) GetCurrencies(ctx context.Context) ([]string, error) { } // GetCurrenciesIncludingChains returns currency and chain data -func (h *HUOBI) GetCurrenciesIncludingChains(ctx context.Context, curr currency.Code) ([]CurrenciesChainData, error) { +func (e *Exchange) GetCurrenciesIncludingChains(ctx context.Context, curr currency.Code) ([]CurrenciesChainData, error) { resp := struct { Data []CurrenciesChainData `json:"data"` }{} @@ -356,7 +356,7 @@ func (h *HUOBI) GetCurrenciesIncludingChains(ctx context.Context, curr currency. vals.Set("currency", curr.Lower().String()) } path := common.EncodeURLValues(huobiCurrenciesReference, vals) - err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return nil, err } @@ -364,12 +364,12 @@ func (h *HUOBI) GetCurrenciesIncludingChains(ctx context.Context, curr currency. } // GetCurrentServerTime returns the Huobi server time -func (h *HUOBI) GetCurrentServerTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (time.Time, error) { var result struct { Response Timestamp types.Time `json:"data"` } - err := h.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiTimestamp, &result) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiTimestamp, &result) if result.ErrorMessage != "" { return time.Time{}, errors.New(result.ErrorMessage) } @@ -377,32 +377,32 @@ func (h *HUOBI) GetCurrentServerTime(ctx context.Context) (time.Time, error) { } // GetAccounts returns the Huobi user accounts -func (h *HUOBI) GetAccounts(ctx context.Context) ([]Account, error) { +func (e *Exchange) GetAccounts(ctx context.Context) ([]Account, error) { result := struct { Accounts []Account `json:"data"` }{} - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false) return result.Accounts, err } // GetAccountBalance returns the users Huobi account balance -func (h *HUOBI) GetAccountBalance(ctx context.Context, accountID string) ([]AccountBalanceDetail, error) { +func (e *Exchange) GetAccountBalance(ctx context.Context, accountID string) ([]AccountBalanceDetail, error) { result := struct { AccountBalanceData AccountBalance `json:"data"` }{} endpoint := fmt.Sprintf(huobiAccountBalance, accountID) v := url.Values{} v.Set("account-id", accountID) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, v, nil, &result, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, v, nil, &result, false) return result.AccountBalanceData.AccountBalanceDetails, err } // GetAggregatedBalance returns the balances of all the sub-account aggregated. -func (h *HUOBI) GetAggregatedBalance(ctx context.Context) ([]AggregatedBalance, error) { +func (e *Exchange) GetAggregatedBalance(ctx context.Context) ([]AggregatedBalance, error) { result := struct { AggregatedBalances []AggregatedBalance `json:"data"` }{} - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAggregatedBalance, nil, @@ -414,8 +414,8 @@ func (h *HUOBI) GetAggregatedBalance(ctx context.Context) ([]AggregatedBalance, } // SpotNewOrder submits an order to Huobi -func (h *HUOBI) SpotNewOrder(ctx context.Context, arg *SpotNewOrderRequestParams) (int64, error) { - symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot) +func (e *Exchange) SpotNewOrder(ctx context.Context, arg *SpotNewOrderRequestParams) (int64, error) { + symbolValue, err := e.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return 0, err } @@ -446,7 +446,7 @@ func (h *HUOBI) SpotNewOrder(ctx context.Context, arg *SpotNewOrderRequestParams result := struct { OrderID int64 `json:"data,string"` }{} - err = h.SendAuthenticatedHTTPRequest(ctx, + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiOrderPlace, @@ -459,17 +459,17 @@ func (h *HUOBI) SpotNewOrder(ctx context.Context, arg *SpotNewOrderRequestParams } // CancelExistingOrder cancels an order on Huobi -func (h *HUOBI) CancelExistingOrder(ctx context.Context, orderID int64) (int64, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) (int64, error) { resp := struct { OrderID int64 `json:"data,string"` }{} endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, url.Values{}, nil, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, url.Values{}, nil, &resp, false) return resp.OrderID, err } // CancelOrderBatch cancels a batch of orders -func (h *HUOBI) CancelOrderBatch(ctx context.Context, orderIDs, clientOrderIDs []string) (*CancelOrderBatch, error) { +func (e *Exchange) CancelOrderBatch(ctx context.Context, orderIDs, clientOrderIDs []string) (*CancelOrderBatch, error) { resp := struct { Response Data *CancelOrderBatch `json:"data"` @@ -481,13 +481,13 @@ func (h *HUOBI) CancelOrderBatch(ctx context.Context, orderIDs, clientOrderIDs [ ClientOrderIDs: clientOrderIDs, OrderIDs: orderIDs, } - return resp.Data, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiOrderCancelBatch, nil, data, &resp, false) + return resp.Data, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiOrderCancelBatch, nil, data, &resp, false) } // CancelOpenOrdersBatch cancels a batch of orders -- to-do -func (h *HUOBI) CancelOpenOrdersBatch(ctx context.Context, accountID string, symbol currency.Pair) (CancelOpenOrdersBatch, error) { +func (e *Exchange) CancelOpenOrdersBatch(ctx context.Context, accountID string, symbol currency.Pair) (CancelOpenOrdersBatch, error) { params := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return CancelOpenOrdersBatch{}, err } @@ -502,7 +502,7 @@ func (h *HUOBI) CancelOpenOrdersBatch(ctx context.Context, accountID string, sym Symbol: symbolValue, } - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false) if result.Data.FailedCount > 0 { return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) } @@ -511,13 +511,13 @@ func (h *HUOBI) CancelOpenOrdersBatch(ctx context.Context, accountID string, sym } // GetOrder returns order information for the specified order -func (h *HUOBI) GetOrder(ctx context.Context, orderID int64) (OrderInfo, error) { +func (e *Exchange) GetOrder(ctx context.Context, orderID int64) (OrderInfo, error) { resp := struct { Order OrderInfo `json:"data"` }{} urlVal := url.Values{} urlVal.Set("clientOrderId", strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrder, urlVal, nil, @@ -527,23 +527,23 @@ func (h *HUOBI) GetOrder(ctx context.Context, orderID int64) (OrderInfo, error) } // GetOrderMatchResults returns matched order info for the specified order -func (h *HUOBI) GetOrderMatchResults(ctx context.Context, orderID int64) ([]OrderMatchInfo, error) { +func (e *Exchange) GetOrderMatchResults(ctx context.Context, orderID int64) ([]OrderMatchInfo, error) { resp := struct { Orders []OrderMatchInfo `json:"data"` }{} endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, url.Values{}, nil, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, url.Values{}, nil, &resp, false) return resp.Orders, err } // GetOrders returns a list of orders -func (h *HUOBI) GetOrders(ctx context.Context, symbol currency.Pair, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { +func (e *Exchange) GetOrders(ctx context.Context, symbol currency.Pair, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { resp := struct { Orders []OrderInfo `json:"data"` }{} vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -574,18 +574,18 @@ func (h *HUOBI) GetOrders(ctx context.Context, symbol currency.Pair, types, star vals.Set("size", size) } - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrders, vals, nil, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrders, vals, nil, &resp, false) return resp.Orders, err } // GetOpenOrders returns a list of orders -func (h *HUOBI) GetOpenOrders(ctx context.Context, symbol currency.Pair, accountID, side string, size int64) ([]OrderInfo, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, symbol currency.Pair, accountID, side string, size int64) ([]OrderInfo, error) { resp := struct { Orders []OrderInfo `json:"data"` }{} vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -596,18 +596,18 @@ func (h *HUOBI) GetOpenOrders(ctx context.Context, symbol currency.Pair, account } vals.Set("size", strconv.FormatInt(size, 10)) - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false) return resp.Orders, err } // GetOrdersMatch returns a list of matched orders -func (h *HUOBI) GetOrdersMatch(ctx context.Context, symbol currency.Pair, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { +func (e *Exchange) GetOrdersMatch(ctx context.Context, symbol currency.Pair, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { resp := struct { Orders []OrderMatchInfo `json:"data"` }{} vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -637,13 +637,13 @@ func (h *HUOBI) GetOrdersMatch(ctx context.Context, symbol currency.Pair, types, vals.Set("size", size) } - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false) return resp.Orders, err } // MarginTransfer transfers assets into or out of the margin account -func (h *HUOBI) MarginTransfer(ctx context.Context, symbol currency.Pair, currency string, amount float64, in bool) (int64, error) { - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) MarginTransfer(ctx context.Context, symbol currency.Pair, currency string, amount float64, in bool) (int64, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err } @@ -665,13 +665,13 @@ func (h *HUOBI) MarginTransfer(ctx context.Context, symbol currency.Pair, curren resp := struct { TransferID int64 `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, data, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, data, &resp, false) return resp.TransferID, err } // MarginOrder submits a margin order application -func (h *HUOBI) MarginOrder(ctx context.Context, symbol currency.Pair, currency string, amount float64) (int64, error) { - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) MarginOrder(ctx context.Context, symbol currency.Pair, currency string, amount float64) (int64, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err } @@ -688,12 +688,12 @@ func (h *HUOBI) MarginOrder(ctx context.Context, symbol currency.Pair, currency resp := struct { MarginOrderID int64 `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiMarginOrders, nil, data, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiMarginOrders, nil, data, &resp, false) return resp.MarginOrderID, err } // MarginRepayment repays a margin amount for a margin ID -func (h *HUOBI) MarginRepayment(ctx context.Context, orderID int64, amount float64) (int64, error) { +func (e *Exchange) MarginRepayment(ctx context.Context, orderID int64, amount float64) (int64, error) { data := struct { Amount string `json:"amount"` }{ @@ -705,14 +705,14 @@ func (h *HUOBI) MarginRepayment(ctx context.Context, orderID int64, amount float }{} endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, nil, data, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, nil, data, &resp, false) return resp.MarginOrderID, err } // GetMarginLoanOrders returns the margin loan orders -func (h *HUOBI) GetMarginLoanOrders(ctx context.Context, symbol currency.Pair, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { +func (e *Exchange) GetMarginLoanOrders(ctx context.Context, symbol currency.Pair, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { vals := url.Values{} - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -746,29 +746,29 @@ func (h *HUOBI) GetMarginLoanOrders(ctx context.Context, symbol currency.Pair, c resp := struct { MarginLoanOrders []MarginOrder `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false) return resp.MarginLoanOrders, err } // GetMarginAccountBalance returns the margin account balances -func (h *HUOBI) GetMarginAccountBalance(ctx context.Context, symbol currency.Pair) ([]MarginAccountBalance, error) { +func (e *Exchange) GetMarginAccountBalance(ctx context.Context, symbol currency.Pair) ([]MarginAccountBalance, error) { resp := struct { Balances []MarginAccountBalance `json:"data"` }{} vals := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := h.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return resp.Balances, err } vals.Set("symbol", symbolValue) } - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false) return resp.Balances, err } // Withdraw withdraws the desired amount and currency -func (h *HUOBI) Withdraw(ctx context.Context, c currency.Code, address, addrTag, chain string, amount, fee float64) (int64, error) { +func (e *Exchange) Withdraw(ctx context.Context, c currency.Code, address, addrTag, chain string, amount, fee float64) (int64, error) { if c.IsEmpty() || address == "" || amount <= 0 { return 0, errors.New("currency, address and amount must be set") } @@ -802,12 +802,12 @@ func (h *HUOBI) Withdraw(ctx context.Context, c currency.Code, address, addrTag, data.Chain = strings.ToLower(chain) } - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiWithdrawCreate, nil, data, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiWithdrawCreate, nil, data, &resp, false) return resp.WithdrawID, err } // CancelWithdraw cancels a withdraw request -func (h *HUOBI) CancelWithdraw(ctx context.Context, withdrawID int64) (int64, error) { +func (e *Exchange) CancelWithdraw(ctx context.Context, withdrawID int64) (int64, error) { resp := struct { WithdrawID int64 `json:"data"` }{} @@ -815,12 +815,12 @@ func (h *HUOBI) CancelWithdraw(ctx context.Context, withdrawID int64) (int64, er vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10)) endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10)) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, vals, nil, &resp, false) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, vals, nil, &resp, false) return resp.WithdrawID, err } // QueryDepositAddress returns the deposit address for a specified currency -func (h *HUOBI) QueryDepositAddress(ctx context.Context, cryptocurrency currency.Code) ([]DepositAddress, error) { +func (e *Exchange) QueryDepositAddress(ctx context.Context, cryptocurrency currency.Code) ([]DepositAddress, error) { resp := struct { DepositAddress []DepositAddress `json:"data"` }{} @@ -828,7 +828,7 @@ func (h *HUOBI) QueryDepositAddress(ctx context.Context, cryptocurrency currency vals := url.Values{} vals.Set("currency", cryptocurrency.Lower().String()) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true) if err != nil { return nil, err } @@ -839,7 +839,7 @@ func (h *HUOBI) QueryDepositAddress(ctx context.Context, cryptocurrency currency } // QueryWithdrawQuotas returns the users cryptocurrency withdraw quotas -func (h *HUOBI) QueryWithdrawQuotas(ctx context.Context, cryptocurrency string) (WithdrawQuota, error) { +func (e *Exchange) QueryWithdrawQuotas(ctx context.Context, cryptocurrency string) (WithdrawQuota, error) { resp := struct { WithdrawQuota WithdrawQuota `json:"data"` }{} @@ -847,7 +847,7 @@ func (h *HUOBI) QueryWithdrawQuotas(ctx context.Context, cryptocurrency string) vals := url.Values{} vals.Set("currency", cryptocurrency) - err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true) if err != nil { return WithdrawQuota{}, err } @@ -855,7 +855,7 @@ func (h *HUOBI) QueryWithdrawQuotas(ctx context.Context, cryptocurrency string) } // SearchForExistedWithdrawsAndDeposits returns withdrawal and deposit data -func (h *HUOBI) SearchForExistedWithdrawsAndDeposits(ctx context.Context, c currency.Code, transferType, direction string, fromID, limit int64) (WithdrawalHistory, error) { +func (e *Exchange) SearchForExistedWithdrawsAndDeposits(ctx context.Context, c currency.Code, transferType, direction string, fromID, limit int64) (WithdrawalHistory, error) { var resp WithdrawalHistory vals := url.Values{} vals.Set("type", transferType) @@ -871,12 +871,12 @@ func (h *HUOBI) SearchForExistedWithdrawsAndDeposits(ctx context.Context, c curr if limit > 0 { vals.Set("size", strconv.FormatInt(limit, 10)) } - return resp, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiWithdrawHistory, vals, nil, &resp, false) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiWithdrawHistory, vals, nil, &resp, false) } // SendHTTPRequest sends an unauthenticated HTTP request -func (h *HUOBI) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := h.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -886,12 +886,12 @@ func (h *HUOBI) SendHTTPRequest(ctx context.Context, ep exchange.URL, path strin Method: http.MethodGet, Path: endpoint + path, Result: &tempResp, - Verbose: h.Verbose, - HTTPDebugging: h.HTTPDebugging, - HTTPRecording: h.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - err = h.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) if err != nil { @@ -913,13 +913,13 @@ func (h *HUOBI) SendHTTPRequest(ctx context.Context, ep exchange.URL, path strin } // SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result any, isVersion2API bool) error { +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result any, isVersion2API bool) error { var err error - creds, err := h.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := h.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -972,13 +972,13 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.UR Headers: headers, Body: bytes.NewReader(body), Result: &interim, - Verbose: h.Verbose, - HTTPDebugging: h.HTTPDebugging, - HTTPRecording: h.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - err = h.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) + err = e.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) if err != nil { return err } @@ -1006,7 +1006,7 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.UR } // GetFee returns an estimate of fee based on type of transaction -func (h *HUOBI) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 if feeBuilder.FeeType == exchange.OfflineTradeFee || feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { fee = calculateTradingFee(feeBuilder.Pair, feeBuilder.PurchasePrice, feeBuilder.Amount) diff --git a/exchanges/huobi/huobi_cfutures.go b/exchanges/huobi/huobi_cfutures.go index d779c6d653d..4ac8fd25432 100644 --- a/exchanges/huobi/huobi_cfutures.go +++ b/exchanges/huobi/huobi_cfutures.go @@ -70,11 +70,11 @@ const ( ) // QuerySwapIndexPriceInfo gets perpetual swap index's price info -func (h *HUOBI) QuerySwapIndexPriceInfo(ctx context.Context, code currency.Pair) (SwapIndexPriceData, error) { +func (e *Exchange) QuerySwapIndexPriceInfo(ctx context.Context, code currency.Pair) (SwapIndexPriceData, error) { var resp SwapIndexPriceData path := huobiSwapIndexPriceInfo if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -82,26 +82,26 @@ func (h *HUOBI) QuerySwapIndexPriceInfo(ctx context.Context, code currency.Pair) params.Set("contract_code", codeValue) path = common.EncodeURLValues(path, params) } - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapPriceLimits gets price caps for perpetual futures -func (h *HUOBI) GetSwapPriceLimits(ctx context.Context, code currency.Pair) (SwapPriceLimitsData, error) { +func (e *Exchange) GetSwapPriceLimits(ctx context.Context, code currency.Pair) (SwapPriceLimitsData, error) { var resp SwapPriceLimitsData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } params := url.Values{} params.Set("contract_code", codeValue) path := common.EncodeURLValues(huobiSwapPriceLimitation, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // SwapOpenInterestInformation gets open interest data for perpetual futures -func (h *HUOBI) SwapOpenInterestInformation(ctx context.Context, code currency.Pair) (SwapOpenInterestData, error) { +func (e *Exchange) SwapOpenInterestInformation(ctx context.Context, code currency.Pair) (SwapOpenInterestData, error) { var resp SwapOpenInterestData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -110,13 +110,13 @@ func (h *HUOBI) SwapOpenInterestInformation(ctx context.Context, code currency.P params.Set("contract_code", codeValue) } path := common.EncodeURLValues(huobiSwapOpenInterestInfo, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapMarketDepth gets market depth for perpetual futures -func (h *HUOBI) GetSwapMarketDepth(ctx context.Context, code currency.Pair, dataType string) (SwapMarketDepthData, error) { +func (e *Exchange) GetSwapMarketDepth(ctx context.Context, code currency.Pair, dataType string) (SwapMarketDepthData, error) { var resp SwapMarketDepthData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -124,13 +124,13 @@ func (h *HUOBI) GetSwapMarketDepth(ctx context.Context, code currency.Pair, data params.Set("contract_code", codeValue) params.Set("type", dataType) path := common.EncodeURLValues(huobiSwapMarketDepth, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapKlineData gets kline data for perpetual futures -func (h *HUOBI) GetSwapKlineData(ctx context.Context, code currency.Pair, period string, size int64, startTime, endTime time.Time) (SwapKlineData, error) { +func (e *Exchange) GetSwapKlineData(ctx context.Context, code currency.Pair, period string, size int64, startTime, endTime time.Time) (SwapKlineData, error) { var resp SwapKlineData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -151,39 +151,39 @@ func (h *HUOBI) GetSwapKlineData(ctx context.Context, code currency.Pair, period params.Set("to", strconv.FormatInt(endTime.Unix(), 10)) } path := common.EncodeURLValues(huobiKLineData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapMarketOverview gets market data overview for perpetual futures -func (h *HUOBI) GetSwapMarketOverview(ctx context.Context, code currency.Pair) (MarketOverviewData, error) { +func (e *Exchange) GetSwapMarketOverview(ctx context.Context, code currency.Pair) (MarketOverviewData, error) { var resp MarketOverviewData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } params := url.Values{} params.Set("contract_code", codeValue) path := common.EncodeURLValues(huobiMarketDataOverview, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetLastTrade gets the last trade for a given perpetual contract -func (h *HUOBI) GetLastTrade(ctx context.Context, code currency.Pair) (LastTradeData, error) { +func (e *Exchange) GetLastTrade(ctx context.Context, code currency.Pair) (LastTradeData, error) { var resp LastTradeData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } params := url.Values{} params.Set("contract_code", codeValue) path := common.EncodeURLValues(huobiLastTradeContract, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetBatchTrades gets batch trades for a specified contract (fetching size cannot be bigger than 2000) -func (h *HUOBI) GetBatchTrades(ctx context.Context, code currency.Pair, size int64) (BatchTradesData, error) { +func (e *Exchange) GetBatchTrades(ctx context.Context, code currency.Pair, size int64) (BatchTradesData, error) { var resp BatchTradesData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -191,26 +191,26 @@ func (h *HUOBI) GetBatchTrades(ctx context.Context, code currency.Pair, size int params.Set("contract_code", codeValue) params.Set("size", strconv.FormatInt(size, 10)) path := common.EncodeURLValues(huobiRequestBatchOfTradingRecords, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetTieredAjustmentFactorInfo gets tiered adjustment factor data -func (h *HUOBI) GetTieredAjustmentFactorInfo(ctx context.Context, code currency.Pair) (TieredAdjustmentFactorData, error) { +func (e *Exchange) GetTieredAjustmentFactorInfo(ctx context.Context, code currency.Pair) (TieredAdjustmentFactorData, error) { var resp TieredAdjustmentFactorData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } params := url.Values{} params.Set("contract_code", codeValue) path := common.EncodeURLValues(huobiTieredAdjustmentFactor, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetOpenInterestInfo gets open interest data -func (h *HUOBI) GetOpenInterestInfo(ctx context.Context, code currency.Pair, period, amountType string, size int64) (OpenInterestData, error) { +func (e *Exchange) GetOpenInterestInfo(ctx context.Context, code currency.Pair, period, amountType string, size int64) (OpenInterestData, error) { var resp OpenInterestData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -230,26 +230,26 @@ func (h *HUOBI) GetOpenInterestInfo(ctx context.Context, code currency.Pair, per params.Set("size", strconv.FormatInt(size, 10)) params.Set("amount_type", strconv.FormatInt(aType, 10)) path := common.EncodeURLValues(huobiOpenInterestInfo, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSystemStatusInfo gets system status data -func (h *HUOBI) GetSystemStatusInfo(ctx context.Context, code currency.Pair) (SystemStatusData, error) { +func (e *Exchange) GetSystemStatusInfo(ctx context.Context, code currency.Pair) (SystemStatusData, error) { var resp SystemStatusData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } params := url.Values{} params.Set("contract_code", codeValue) path := common.EncodeURLValues(huobiSwapSystemStatus, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetTraderSentimentIndexAccount gets top trader sentiment function-account -func (h *HUOBI) GetTraderSentimentIndexAccount(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexAccountData, error) { +func (e *Exchange) GetTraderSentimentIndexAccount(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexAccountData, error) { var resp TraderSentimentIndexAccountData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -260,13 +260,13 @@ func (h *HUOBI) GetTraderSentimentIndexAccount(ctx context.Context, code currenc params.Set("contract_code", codeValue) params.Set("period", period) path := common.EncodeURLValues(huobiSwapSentimentAccountData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetTraderSentimentIndexPosition gets top trader sentiment function-position -func (h *HUOBI) GetTraderSentimentIndexPosition(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexPositionData, error) { +func (e *Exchange) GetTraderSentimentIndexPosition(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexPositionData, error) { var resp TraderSentimentIndexPositionData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -278,13 +278,13 @@ func (h *HUOBI) GetTraderSentimentIndexPosition(ctx context.Context, code curren params.Set("contract_code", codeValue) params.Set("period", period) path := common.EncodeURLValues(huobiSwapSentimentPosition, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetLiquidationOrders gets liquidation orders for a given perp -func (h *HUOBI) GetLiquidationOrders(ctx context.Context, contract currency.Pair, tradeType string, startTime, endTime time.Time, direction string, fromID int64) (LiquidationOrdersData, error) { +func (e *Exchange) GetLiquidationOrders(ctx context.Context, contract currency.Pair, tradeType string, startTime, endTime time.Time, direction string, fromID int64) (LiquidationOrdersData, error) { var resp LiquidationOrdersData - formattedContract, err := h.FormatSymbol(contract, asset.CoinMarginedFutures) + formattedContract, err := e.FormatSymbol(contract, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -309,13 +309,13 @@ func (h *HUOBI) GetLiquidationOrders(ctx context.Context, contract currency.Pair params.Set("from_id", strconv.FormatInt(fromID, 10)) } path := common.EncodeURLValues(huobiSwapLiquidationOrders, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetHistoricalFundingRatesForPair gets historical funding rates for perpetual futures -func (h *HUOBI) GetHistoricalFundingRatesForPair(ctx context.Context, code currency.Pair, pageSize, pageIndex int64) (HistoricalFundingRateData, error) { +func (e *Exchange) GetHistoricalFundingRatesForPair(ctx context.Context, code currency.Pair, pageSize, pageIndex int64) (HistoricalFundingRateData, error) { var resp HistoricalFundingRateData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -328,13 +328,13 @@ func (h *HUOBI) GetHistoricalFundingRatesForPair(ctx context.Context, code curre params.Set("page_size", strconv.FormatInt(pageIndex, 10)) } path := common.EncodeURLValues(huobiSwapHistoricalFundingRate, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetPremiumIndexKlineData gets kline data for premium index -func (h *HUOBI) GetPremiumIndexKlineData(ctx context.Context, code currency.Pair, period string, size int64) (PremiumIndexKlineData, error) { +func (e *Exchange) GetPremiumIndexKlineData(ctx context.Context, code currency.Pair, period string, size int64) (PremiumIndexKlineData, error) { var resp PremiumIndexKlineData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -349,13 +349,13 @@ func (h *HUOBI) GetPremiumIndexKlineData(ctx context.Context, code currency.Pair params.Set("size", strconv.FormatInt(size, 10)) params.Set("period", period) path := common.EncodeURLValues(huobiPremiumIndexKlineData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetEstimatedFundingRates gets estimated funding rates for perpetual futures -func (h *HUOBI) GetEstimatedFundingRates(ctx context.Context, code currency.Pair, period string, size int64) (EstimatedFundingRateData, error) { +func (e *Exchange) GetEstimatedFundingRates(ctx context.Context, code currency.Pair, period string, size int64) (EstimatedFundingRateData, error) { var resp EstimatedFundingRateData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -370,13 +370,13 @@ func (h *HUOBI) GetEstimatedFundingRates(ctx context.Context, code currency.Pair params.Set("period", period) params.Set("size", strconv.FormatInt(size, 10)) path := common.EncodeURLValues(huobiPredictedFundingRateData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetBasisData gets basis data for perpetual futures -func (h *HUOBI) GetBasisData(ctx context.Context, code currency.Pair, period, basisPriceType string, size int64) (BasisData, error) { +func (e *Exchange) GetBasisData(ctx context.Context, code currency.Pair, period, basisPriceType string, size int64) (BasisData, error) { var resp BasisData - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -394,92 +394,92 @@ func (h *HUOBI) GetBasisData(ctx context.Context, code currency.Pair, period, ba params.Set("period", period) params.Set("size", strconv.FormatInt(size, 10)) path := common.EncodeURLValues(huobiBasisData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapAccountInfo gets swap account info -func (h *HUOBI) GetSwapAccountInfo(ctx context.Context, code currency.Pair) (SwapAccountInformation, error) { +func (e *Exchange) GetSwapAccountInfo(ctx context.Context, code currency.Pair) (SwapAccountInformation, error) { var resp SwapAccountInformation req := make(map[string]any) if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAccInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAccInfo, nil, req, &resp) } // GetSwapPositionsInfo gets swap positions' info -func (h *HUOBI) GetSwapPositionsInfo(ctx context.Context, code currency.Pair) (SwapPositionInfo, error) { +func (e *Exchange) GetSwapPositionsInfo(ctx context.Context, code currency.Pair) (SwapPositionInfo, error) { var resp SwapPositionInfo req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPosInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPosInfo, nil, req, &resp) } // GetSwapAssetsAndPositions gets swap positions and asset info -func (h *HUOBI) GetSwapAssetsAndPositions(ctx context.Context, code currency.Pair) (SwapAssetsAndPositionsData, error) { +func (e *Exchange) GetSwapAssetsAndPositions(ctx context.Context, code currency.Pair) (SwapAssetsAndPositionsData, error) { var resp SwapAssetsAndPositionsData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAssetsAndPos, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAssetsAndPos, nil, req, &resp) } // GetSwapAllSubAccAssets gets asset info for all subaccounts -func (h *HUOBI) GetSwapAllSubAccAssets(ctx context.Context, code currency.Pair) (SubAccountsAssetData, error) { +func (e *Exchange) GetSwapAllSubAccAssets(ctx context.Context, code currency.Pair) (SubAccountsAssetData, error) { var resp SubAccountsAssetData req := make(map[string]any) if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccList, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccList, nil, req, &resp) } // SwapSingleSubAccAssets gets a subaccount's assets info -func (h *HUOBI) SwapSingleSubAccAssets(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountAssetsInfo, error) { +func (e *Exchange) SwapSingleSubAccAssets(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountAssetsInfo, error) { var resp SingleSubAccountAssetsInfo req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccInfo, nil, req, &resp) } // GetSubAccPositionInfo gets a subaccount's positions info -func (h *HUOBI) GetSubAccPositionInfo(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountPositionsInfo, error) { +func (e *Exchange) GetSubAccPositionInfo(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountPositionsInfo, error) { var resp SingleSubAccountPositionsInfo req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccPosInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccPosInfo, nil, req, &resp) } // GetAccountFinancialRecords gets the account's financial records -func (h *HUOBI) GetAccountFinancialRecords(ctx context.Context, code currency.Pair, orderType string, createDate, pageIndex, pageSize int64) (FinancialRecordData, error) { +func (e *Exchange) GetAccountFinancialRecords(ctx context.Context, code currency.Pair, orderType string, createDate, pageIndex, pageSize int64) (FinancialRecordData, error) { var resp FinancialRecordData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -496,14 +496,14 @@ func (h *HUOBI) GetAccountFinancialRecords(ctx context.Context, code currency.Pa if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapFinancialRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapFinancialRecords, nil, req, &resp) } // GetSwapSettlementRecords gets the swap account's settlement records -func (h *HUOBI) GetSwapSettlementRecords(ctx context.Context, code currency.Pair, startTime, endTime time.Time, pageIndex, pageSize int64) (FinancialRecordData, error) { +func (e *Exchange) GetSwapSettlementRecords(ctx context.Context, code currency.Pair, startTime, endTime time.Time, pageIndex, pageSize int64) (FinancialRecordData, error) { var resp FinancialRecordData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -521,28 +521,28 @@ func (h *HUOBI) GetSwapSettlementRecords(ctx context.Context, code currency.Pair if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSettlementRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSettlementRecords, nil, req, &resp) } // GetAvailableLeverage gets user's available leverage data -func (h *HUOBI) GetAvailableLeverage(ctx context.Context, code currency.Pair) (AvailableLeverageData, error) { +func (e *Exchange) GetAvailableLeverage(ctx context.Context, code currency.Pair) (AvailableLeverageData, error) { var resp AvailableLeverageData req := make(map[string]any) if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAvailableLeverage, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAvailableLeverage, nil, req, &resp) } // GetSwapOrderLimitInfo gets order limit info for swaps -func (h *HUOBI) GetSwapOrderLimitInfo(ctx context.Context, code currency.Pair, orderType string) (SwapOrderLimitInfo, error) { +func (e *Exchange) GetSwapOrderLimitInfo(ctx context.Context, code currency.Pair, orderType string) (SwapOrderLimitInfo, error) { var resp SwapOrderLimitInfo req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -551,50 +551,50 @@ func (h *HUOBI) GetSwapOrderLimitInfo(ctx context.Context, code currency.Pair, o return resp, errors.New("invalid ordertype provided") } req["order_price_type"] = orderType - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderLimitInfo, nil, req, &resp) } // GetSwapTradingFeeInfo gets trading fee info for swaps -func (h *HUOBI) GetSwapTradingFeeInfo(ctx context.Context, code currency.Pair) (SwapTradingFeeData, error) { +func (e *Exchange) GetSwapTradingFeeInfo(ctx context.Context, code currency.Pair) (SwapTradingFeeData, error) { var resp SwapTradingFeeData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradingFeeInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradingFeeInfo, nil, req, &resp) } // GetSwapTransferLimitInfo gets transfer limit info for swaps -func (h *HUOBI) GetSwapTransferLimitInfo(ctx context.Context, code currency.Pair) (TransferLimitData, error) { +func (e *Exchange) GetSwapTransferLimitInfo(ctx context.Context, code currency.Pair) (TransferLimitData, error) { var resp TransferLimitData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTransferLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTransferLimitInfo, nil, req, &resp) } // GetSwapPositionLimitInfo gets transfer limit info for swaps -func (h *HUOBI) GetSwapPositionLimitInfo(ctx context.Context, code currency.Pair) (PositionLimitData, error) { +func (e *Exchange) GetSwapPositionLimitInfo(ctx context.Context, code currency.Pair) (PositionLimitData, error) { var resp PositionLimitData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPositionLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPositionLimitInfo, nil, req, &resp) } // AccountTransferData gets asset transfer data between master and subaccounts -func (h *HUOBI) AccountTransferData(ctx context.Context, code currency.Pair, subUID, transferType string, amount float64) (InternalAccountTransferData, error) { +func (e *Exchange) AccountTransferData(ctx context.Context, code currency.Pair, subUID, transferType string, amount float64) (InternalAccountTransferData, error) { var resp InternalAccountTransferData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -605,14 +605,14 @@ func (h *HUOBI) AccountTransferData(ctx context.Context, code currency.Pair, sub return resp, errors.New("invalid transferType received") } req["type"] = transferType - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferData, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferData, nil, req, &resp) } // AccountTransferRecords gets asset transfer records between master and subaccounts -func (h *HUOBI) AccountTransferRecords(ctx context.Context, code currency.Pair, transferType string, createDate, pageIndex, pageSize int64) (InternalAccountTransferData, error) { +func (e *Exchange) AccountTransferRecords(ctx context.Context, code currency.Pair, transferType string, createDate, pageIndex, pageSize int64) (InternalAccountTransferData, error) { var resp InternalAccountTransferData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -631,14 +631,14 @@ func (h *HUOBI) AccountTransferRecords(ctx context.Context, code currency.Pair, if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferRecords, nil, req, &resp) } // PlaceSwapOrders places orders for swaps -func (h *HUOBI) PlaceSwapOrders(ctx context.Context, code currency.Pair, clientOrderID, direction, offset, orderPriceType string, price, volume, leverage float64) (SwapOrderData, error) { +func (e *Exchange) PlaceSwapOrders(ctx context.Context, code currency.Pair, clientOrderID, direction, offset, orderPriceType string, price, volume, leverage float64) (SwapOrderData, error) { var resp SwapOrderData req := make(map[string]any) - codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(code, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -655,11 +655,11 @@ func (h *HUOBI) PlaceSwapOrders(ctx context.Context, code currency.Pair, clientO req["price"] = price req["volume"] = volume req["lever_rate"] = leverage - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceOrder, nil, req, &resp) } // PlaceSwapBatchOrders places a batch of orders for swaps -func (h *HUOBI) PlaceSwapBatchOrders(ctx context.Context, data BatchOrderRequestType) (BatchOrderData, error) { +func (e *Exchange) PlaceSwapBatchOrders(ctx context.Context, data BatchOrderRequestType) (BatchOrderData, error) { var resp BatchOrderData req := make(map[string]any) if len(data.Data) > 10 || len(data.Data) == 0 { @@ -673,18 +673,18 @@ func (h *HUOBI) PlaceSwapBatchOrders(ctx context.Context, data BatchOrderRequest if err != nil { return resp, err } - codeValue, err := h.FormatSymbol(unformattedPair, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(unformattedPair, asset.CoinMarginedFutures) if err != nil { return resp, err } data.Data[x].ContractCode = codeValue } req["orders_data"] = data.Data - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceBatchOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceBatchOrder, nil, req, &resp) } // CancelSwapOrder sends a request to cancel an order -func (h *HUOBI) CancelSwapOrder(ctx context.Context, orderID, clientOrderID string, contractCode currency.Pair) (CancelOrdersData, error) { +func (e *Exchange) CancelSwapOrder(ctx context.Context, orderID, clientOrderID string, contractCode currency.Pair) (CancelOrdersData, error) { var resp CancelOrdersData req := make(map[string]any) if orderID != "" { @@ -694,19 +694,19 @@ func (h *HUOBI) CancelSwapOrder(ctx context.Context, orderID, clientOrderID stri req["client_order_id"] = clientOrderID } req["contract_code"] = contractCode - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelOrder, nil, req, &resp) } // CancelAllSwapOrders sends a request to cancel an order -func (h *HUOBI) CancelAllSwapOrders(ctx context.Context, contractCode currency.Pair) (CancelOrdersData, error) { +func (e *Exchange) CancelAllSwapOrders(ctx context.Context, contractCode currency.Pair) (CancelOrdersData, error) { var resp CancelOrdersData req := make(map[string]any) req["contract_code"] = contractCode - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllOrders, nil, req, &resp) } // PlaceLightningCloseOrder places a lightning close order -func (h *HUOBI) PlaceLightningCloseOrder(ctx context.Context, contractCode currency.Pair, direction, orderPriceType string, volume float64, clientOrderID int64) (LightningCloseOrderData, error) { +func (e *Exchange) PlaceLightningCloseOrder(ctx context.Context, contractCode currency.Pair, direction, orderPriceType string, volume float64, clientOrderID int64) (LightningCloseOrderData, error) { var resp LightningCloseOrderData req := make(map[string]any) req["contract_code"] = contractCode @@ -721,11 +721,11 @@ func (h *HUOBI) PlaceLightningCloseOrder(ctx context.Context, contractCode curre } req["order_price_type"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapLightningCloseOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapLightningCloseOrder, nil, req, &resp) } // GetSwapOrderDetails gets order info -func (h *HUOBI) GetSwapOrderDetails(ctx context.Context, contractCode currency.Pair, orderID, createdAt, orderType string, pageIndex, pageSize int64) (SwapOrderData, error) { +func (e *Exchange) GetSwapOrderDetails(ctx context.Context, contractCode currency.Pair, orderID, createdAt, orderType string, pageIndex, pageSize int64) (SwapOrderData, error) { var resp SwapOrderData req := make(map[string]any) req["contract_code"] = contractCode @@ -742,15 +742,15 @@ func (h *HUOBI) GetSwapOrderDetails(ctx context.Context, contractCode currency.P if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderDetails, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderDetails, nil, req, &resp) } // GetSwapOrderInfo gets info on a swap order -func (h *HUOBI) GetSwapOrderInfo(ctx context.Context, contractCode currency.Pair, orderID, clientOrderID string) (SwapOrderInfo, error) { +func (e *Exchange) GetSwapOrderInfo(ctx context.Context, contractCode currency.Pair, orderID, clientOrderID string) (SwapOrderInfo, error) { var resp SwapOrderInfo req := make(map[string]any) if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -762,14 +762,14 @@ func (h *HUOBI) GetSwapOrderInfo(ctx context.Context, contractCode currency.Pair if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderInfo, nil, req, &resp) } // GetSwapOpenOrders gets open orders for swap -func (h *HUOBI) GetSwapOpenOrders(ctx context.Context, contractCode currency.Pair, pageIndex, pageSize int64) (SwapOpenOrdersData, error) { +func (e *Exchange) GetSwapOpenOrders(ctx context.Context, contractCode currency.Pair, pageIndex, pageSize int64) (SwapOpenOrdersData, error) { var resp SwapOpenOrdersData req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -780,14 +780,14 @@ func (h *HUOBI) GetSwapOpenOrders(ctx context.Context, contractCode currency.Pai if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOpenOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOpenOrders, nil, req, &resp) } // GetSwapOrderHistory gets swap order history -func (h *HUOBI) GetSwapOrderHistory(ctx context.Context, contractCode currency.Pair, tradeType, reqType string, status []order.Status, createDate, pageIndex, pageSize int64) (SwapOrderHistory, error) { +func (e *Exchange) GetSwapOrderHistory(ctx context.Context, contractCode currency.Pair, tradeType, reqType string, status []order.Status, createDate, pageIndex, pageSize int64) (SwapOrderHistory, error) { var resp SwapOrderHistory req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -829,14 +829,14 @@ func (h *HUOBI) GetSwapOrderHistory(ctx context.Context, contractCode currency.P if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderHistory, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderHistory, nil, req, &resp) } // GetSwapTradeHistory gets swap trade history -func (h *HUOBI) GetSwapTradeHistory(ctx context.Context, contractCode currency.Pair, tradeType string, createDate, pageIndex, pageSize int64) (AccountTradeHistoryData, error) { +func (e *Exchange) GetSwapTradeHistory(ctx context.Context, contractCode currency.Pair, tradeType string, createDate, pageIndex, pageSize int64) (AccountTradeHistoryData, error) { var resp AccountTradeHistoryData req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -856,14 +856,14 @@ func (h *HUOBI) GetSwapTradeHistory(ctx context.Context, contractCode currency.P if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradeHistory, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradeHistory, nil, req, &resp) } // PlaceSwapTriggerOrder places a trigger order for a swap -func (h *HUOBI) PlaceSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, triggerType, direction, offset, orderPriceType string, triggerPrice, orderPrice, volume, leverageRate float64) (AccountTradeHistoryData, error) { +func (e *Exchange) PlaceSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, triggerType, direction, offset, orderPriceType string, triggerPrice, orderPrice, volume, leverageRate float64) (AccountTradeHistoryData, error) { var resp AccountTradeHistoryData req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -883,35 +883,35 @@ func (h *HUOBI) PlaceSwapTriggerOrder(ctx context.Context, contractCode currency return resp, errors.New("invalid order price type") } req["order_price_type"] = orderPriceType - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrder, nil, req, &resp) } // CancelSwapTriggerOrder cancels swap trigger order -func (h *HUOBI) CancelSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, orderID string) (CancelTriggerOrdersData, error) { +func (e *Exchange) CancelSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, orderID string) (CancelTriggerOrdersData, error) { var resp CancelTriggerOrdersData req := make(map[string]any) req["contract_code"] = contractCode req["order_id"] = orderID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelTriggerOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelTriggerOrder, nil, req, &resp) } // CancelAllSwapTriggerOrders cancels all swap trigger orders -func (h *HUOBI) CancelAllSwapTriggerOrders(ctx context.Context, contractCode currency.Pair) (CancelTriggerOrdersData, error) { +func (e *Exchange) CancelAllSwapTriggerOrders(ctx context.Context, contractCode currency.Pair) (CancelTriggerOrdersData, error) { var resp CancelTriggerOrdersData req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllTriggerOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllTriggerOrders, nil, req, &resp) } // GetSwapTriggerOrderHistory gets history for swap trigger orders -func (h *HUOBI) GetSwapTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, status, tradeType string, createDate, pageIndex, pageSize int64) (TriggerOrderHistory, error) { +func (e *Exchange) GetSwapTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, status, tradeType string, createDate, pageIndex, pageSize int64) (TriggerOrderHistory, error) { var resp TriggerOrderHistory req := make(map[string]any) - codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contractCode, asset.CoinMarginedFutures) if err != nil { return resp, err } @@ -932,14 +932,14 @@ func (h *HUOBI) GetSwapTriggerOrderHistory(ctx context.Context, contractCode cur if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrderHistory, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrderHistory, nil, req, &resp) } // GetSwapMarkets gets data of swap markets -func (h *HUOBI) GetSwapMarkets(ctx context.Context, contract currency.Pair) ([]SwapMarketsData, error) { +func (e *Exchange) GetSwapMarkets(ctx context.Context, contract currency.Pair) ([]SwapMarketsData, error) { vals := url.Values{} if !contract.IsEmpty() { - codeValue, err := h.FormatSymbol(contract, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contract, asset.CoinMarginedFutures) if err != nil { return nil, err } @@ -950,7 +950,7 @@ func (h *HUOBI) GetSwapMarkets(ctx context.Context, contract currency.Pair) ([]S Data []SwapMarketsData `json:"data"` } var result response - err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapMarkets+"?"+vals.Encode(), &result) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapMarkets+"?"+vals.Encode(), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -958,9 +958,9 @@ func (h *HUOBI) GetSwapMarkets(ctx context.Context, contract currency.Pair) ([]S } // GetSwapFundingRate gets funding rate data for one currency -func (h *HUOBI) GetSwapFundingRate(ctx context.Context, contract currency.Pair) (FundingRatesData, error) { +func (e *Exchange) GetSwapFundingRate(ctx context.Context, contract currency.Pair) (FundingRatesData, error) { vals := url.Values{} - codeValue, err := h.FormatSymbol(contract, asset.CoinMarginedFutures) + codeValue, err := e.FormatSymbol(contract, asset.CoinMarginedFutures) if err != nil { return FundingRatesData{}, err } @@ -970,7 +970,7 @@ func (h *HUOBI) GetSwapFundingRate(ctx context.Context, contract currency.Pair) Data FundingRatesData `json:"data"` } var result response - err = h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapFunding+"?"+vals.Encode(), &result) + err = e.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapFunding+"?"+vals.Encode(), &result) if result.ErrorMessage != "" { return FundingRatesData{}, errors.New(result.ErrorMessage) } @@ -978,8 +978,8 @@ func (h *HUOBI) GetSwapFundingRate(ctx context.Context, contract currency.Pair) } // GetSwapFundingRates gets funding rates data -func (h *HUOBI) GetSwapFundingRates(ctx context.Context) (SwapFundingRatesResponse, error) { +func (e *Exchange) GetSwapFundingRates(ctx context.Context) (SwapFundingRatesResponse, error) { var result SwapFundingRatesResponse - err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapBatchFunding, &result) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapBatchFunding, &result) return result, err } diff --git a/exchanges/huobi/huobi_futures.go b/exchanges/huobi/huobi_futures.go index 001efd097fd..41b025f6bf7 100644 --- a/exchanges/huobi/huobi_futures.go +++ b/exchanges/huobi/huobi_futures.go @@ -86,7 +86,7 @@ var ( ) // FGetContractInfo gets contract info for futures -func (h *HUOBI) FGetContractInfo(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractInfoData, error) { +func (e *Exchange) FGetContractInfo(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractInfoData, error) { var resp FContractInfoData params := url.Values{} if symbol != "" { @@ -99,33 +99,33 @@ func (h *HUOBI) FGetContractInfo(ctx context.Context, symbol, contractType strin params.Set("contract_type", t) } if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.Futures) + codeValue, err := e.FormatSymbol(code, asset.Futures) if err != nil { return resp, err } params.Set("contract_code", codeValue) } path := common.EncodeURLValues(fContractInfo, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FIndexPriceInfo gets index price info for a futures contract -func (h *HUOBI) FIndexPriceInfo(ctx context.Context, symbol currency.Code) (FContractIndexPriceInfo, error) { +func (e *Exchange) FIndexPriceInfo(ctx context.Context, symbol currency.Code) (FContractIndexPriceInfo, error) { var resp FContractIndexPriceInfo params := url.Values{} if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } params.Set("symbol", codeValue) } path := common.EncodeURLValues(fContractIndexPrice, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FContractPriceLimitations gets price limits for a futures contract -func (h *HUOBI) FContractPriceLimitations(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractIndexPriceInfo, error) { +func (e *Exchange) FContractPriceLimitations(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractIndexPriceInfo, error) { var resp FContractIndexPriceInfo params := url.Values{} if symbol != "" { @@ -138,28 +138,28 @@ func (h *HUOBI) FContractPriceLimitations(ctx context.Context, symbol, contractT params.Set("contract_type", t) } if !code.IsEmpty() { - codeValue, err := h.FormatSymbol(code, asset.Futures) + codeValue, err := e.FormatSymbol(code, asset.Futures) if err != nil { return resp, err } params.Set("contract_code", codeValue) } path := common.EncodeURLValues(fContractPriceLimitation, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // ContractOpenInterestUSDT gets open interest data for futures contracts -func (h *HUOBI) ContractOpenInterestUSDT(ctx context.Context, contractCode, pair currency.Pair, contractType, businessType string) ([]UContractOpenInterest, error) { +func (e *Exchange) ContractOpenInterestUSDT(ctx context.Context, contractCode, pair currency.Pair, contractType, businessType string) ([]UContractOpenInterest, error) { params := url.Values{} if !contractCode.IsEmpty() { - cc, err := h.formatFuturesPair(contractCode, true) + cc, err := e.formatFuturesPair(contractCode, true) if err != nil { return nil, err } params.Set("contract_code", cc) } if !pair.IsEmpty() { - p, err := h.formatFuturesPair(pair, true) + p, err := e.formatFuturesPair(pair, true) if err != nil { return nil, err } @@ -178,11 +178,11 @@ func (h *HUOBI) ContractOpenInterestUSDT(ctx context.Context, contractCode, pair var resp struct { Data []UContractOpenInterest `json:"data"` } - return resp.Data, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp.Data, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FContractOpenInterest gets open interest data for futures contracts -func (h *HUOBI) FContractOpenInterest(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractOIData, error) { +func (e *Exchange) FContractOpenInterest(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractOIData, error) { var resp FContractOIData params := url.Values{} if symbol != "" { @@ -195,32 +195,32 @@ func (h *HUOBI) FContractOpenInterest(ctx context.Context, symbol, contractType params.Set("contract_type", t) } if !code.IsEmpty() { - codeValue, err := h.formatFuturesPair(code, true) + codeValue, err := e.formatFuturesPair(code, true) if err != nil { return resp, err } params.Set("contract_code", codeValue) } path := common.EncodeURLValues(fContractOpenInterest, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetEstimatedDeliveryPrice gets estimated delivery price info for futures -func (h *HUOBI) FGetEstimatedDeliveryPrice(ctx context.Context, symbol currency.Code) (FEstimatedDeliveryPriceInfo, error) { +func (e *Exchange) FGetEstimatedDeliveryPrice(ctx context.Context, symbol currency.Code) (FEstimatedDeliveryPriceInfo, error) { var resp FEstimatedDeliveryPriceInfo params := url.Values{} - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } params.Set("symbol", codeValue) path := common.EncodeURLValues(fEstimatedDeliveryPrice, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetMarketDepth gets market depth data for futures contracts -func (h *HUOBI) FGetMarketDepth(ctx context.Context, symbol currency.Pair, dataType string) (*OBData, error) { - symbolValue, err := h.formatFuturesPair(symbol, false) +func (e *Exchange) FGetMarketDepth(ctx context.Context, symbol currency.Pair, dataType string) (*OBData, error) { + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (h *HUOBI) FGetMarketDepth(ctx context.Context, symbol currency.Pair, dataT path := common.EncodeURLValues(fContractMarketDepth, params) var tempData FMarketDepth - err = h.SendHTTPRequest(ctx, exchange.RestFutures, path, &tempData) + err = e.SendHTTPRequest(ctx, exchange.RestFutures, path, &tempData) if err != nil { return nil, err } @@ -257,10 +257,10 @@ func (h *HUOBI) FGetMarketDepth(ctx context.Context, symbol currency.Pair, dataT } // FGetKlineData gets kline data for futures -func (h *HUOBI) FGetKlineData(ctx context.Context, symbol currency.Pair, period string, size int64, startTime, endTime time.Time) (FKlineData, error) { +func (e *Exchange) FGetKlineData(ctx context.Context, symbol currency.Pair, period string, size int64, startTime, endTime time.Time) (FKlineData, error) { var resp FKlineData params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return resp, err } @@ -280,39 +280,39 @@ func (h *HUOBI) FGetKlineData(ctx context.Context, symbol currency.Pair, period params.Set("to", strconv.FormatInt(endTime.Unix(), 10)) } path := common.EncodeURLValues(fContractKline, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetMarketOverviewData gets market overview data for futures -func (h *HUOBI) FGetMarketOverviewData(ctx context.Context, symbol currency.Pair) (FMarketOverviewData, error) { +func (e *Exchange) FGetMarketOverviewData(ctx context.Context, symbol currency.Pair) (FMarketOverviewData, error) { var resp FMarketOverviewData params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return resp, err } params.Set("symbol", symbolValue) path := common.EncodeURLValues(fMarketOverview, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FLastTradeData gets last trade data for a futures contract -func (h *HUOBI) FLastTradeData(ctx context.Context, symbol currency.Pair) (FLastTradeData, error) { +func (e *Exchange) FLastTradeData(ctx context.Context, symbol currency.Pair) (FLastTradeData, error) { var resp FLastTradeData params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return resp, err } params.Set("symbol", symbolValue) path := common.EncodeURLValues(fLastTradeContract, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FRequestPublicBatchTrades gets public batch trades for a futures contract -func (h *HUOBI) FRequestPublicBatchTrades(ctx context.Context, symbol currency.Pair, size int64) (FBatchTradesForContractData, error) { +func (e *Exchange) FRequestPublicBatchTrades(ctx context.Context, symbol currency.Pair, size int64) (FBatchTradesForContractData, error) { params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return FBatchTradesForContractData{}, err } @@ -322,26 +322,26 @@ func (h *HUOBI) FRequestPublicBatchTrades(ctx context.Context, symbol currency.P } var resp FBatchTradesForContractData path := common.EncodeURLValues(fContractBatchTradeRecords, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTieredAdjustmentFactor gets tiered adjustment factor for futures contracts -func (h *HUOBI) FQueryTieredAdjustmentFactor(ctx context.Context, symbol currency.Code) (FTieredAdjustmentFactorInfo, error) { +func (e *Exchange) FQueryTieredAdjustmentFactor(ctx context.Context, symbol currency.Code) (FTieredAdjustmentFactorInfo, error) { var resp FTieredAdjustmentFactorInfo params := url.Values{} if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } params.Set("symbol", codeValue) } path := common.EncodeURLValues(fTieredAdjustmentFactor, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryHisOpenInterest gets open interest for futures contract -func (h *HUOBI) FQueryHisOpenInterest(ctx context.Context, symbol, contractType, period, amountType string, size int64) (FOIData, error) { +func (e *Exchange) FQueryHisOpenInterest(ctx context.Context, symbol, contractType, period, amountType string, size int64) (FOIData, error) { var resp FOIData params := url.Values{} if symbol != "" { @@ -365,26 +365,26 @@ func (h *HUOBI) FQueryHisOpenInterest(ctx context.Context, symbol, contractType, } params.Set("amount_type", strconv.FormatInt(validAmount, 10)) path := common.EncodeURLValues(fHisContractOpenInterest, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQuerySystemStatus gets system status data -func (h *HUOBI) FQuerySystemStatus(ctx context.Context, symbol currency.Code) (FContractOIData, error) { +func (e *Exchange) FQuerySystemStatus(ctx context.Context, symbol currency.Code) (FContractOIData, error) { var resp FContractOIData params := url.Values{} if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } params.Set("symbol", codeValue) } path := common.EncodeURLValues(fSystemStatus, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTopAccountsRatio gets top accounts' ratio -func (h *HUOBI) FQueryTopAccountsRatio(ctx context.Context, symbol, period string) (FTopAccountsLongShortRatio, error) { +func (e *Exchange) FQueryTopAccountsRatio(ctx context.Context, symbol, period string) (FTopAccountsLongShortRatio, error) { var resp FTopAccountsLongShortRatio params := url.Values{} if symbol != "" { @@ -395,11 +395,11 @@ func (h *HUOBI) FQueryTopAccountsRatio(ctx context.Context, symbol, period strin } params.Set("period", period) path := common.EncodeURLValues(fTopAccountsSentiment, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTopPositionsRatio gets top positions' long/short ratio for futures -func (h *HUOBI) FQueryTopPositionsRatio(ctx context.Context, symbol, period string) (FTopPositionsLongShortRatio, error) { +func (e *Exchange) FQueryTopPositionsRatio(ctx context.Context, symbol, period string) (FTopPositionsLongShortRatio, error) { var resp FTopPositionsLongShortRatio params := url.Values{} if symbol != "" { @@ -410,11 +410,11 @@ func (h *HUOBI) FQueryTopPositionsRatio(ctx context.Context, symbol, period stri } params.Set("period", period) path := common.EncodeURLValues(fTopPositionsSentiment, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FLiquidationOrders gets liquidation orders for futures contracts -func (h *HUOBI) FLiquidationOrders(ctx context.Context, symbol currency.Code, tradeType string, startTime, endTime int64, direction string, fromID int64) (LiquidationOrdersData, error) { +func (e *Exchange) FLiquidationOrders(ctx context.Context, symbol currency.Code, tradeType string, startTime, endTime int64, direction string, fromID int64) (LiquidationOrdersData, error) { var resp LiquidationOrdersData tType, ok := validTradeTypes[tradeType] if !ok { @@ -437,14 +437,14 @@ func (h *HUOBI) FLiquidationOrders(ctx context.Context, symbol currency.Code, tr params.Set("from_id", strconv.FormatInt(fromID, 10)) } path := common.EncodeURLValues(fLiquidationOrders, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FIndexKline gets index kline data for futures contracts -func (h *HUOBI) FIndexKline(ctx context.Context, symbol currency.Pair, period string, size int64) (FIndexKlineData, error) { +func (e *Exchange) FIndexKline(ctx context.Context, symbol currency.Pair, period string, size int64) (FIndexKlineData, error) { var resp FIndexKlineData params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return resp, err } @@ -458,14 +458,14 @@ func (h *HUOBI) FIndexKline(ctx context.Context, symbol currency.Pair, period st } params.Set("size", strconv.FormatInt(size, 10)) path := common.EncodeURLValues(fIndexKline, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetBasisData gets basis data futures contracts -func (h *HUOBI) FGetBasisData(ctx context.Context, symbol currency.Pair, period, basisPriceType string, size int64) (FBasisData, error) { +func (e *Exchange) FGetBasisData(ctx context.Context, symbol currency.Pair, period, basisPriceType string, size int64) (FBasisData, error) { var resp FBasisData params := url.Values{} - symbolValue, err := h.formatFuturesPair(symbol, false) + symbolValue, err := e.formatFuturesPair(symbol, false) if err != nil { return resp, err } @@ -483,75 +483,75 @@ func (h *HUOBI) FGetBasisData(ctx context.Context, symbol currency.Pair, period, params.Set("size", strconv.FormatInt(size, 10)) } path := common.EncodeURLValues(fBasisData, params) - return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetAccountInfo gets user info for futures account -func (h *HUOBI) FGetAccountInfo(ctx context.Context, symbol currency.Code) (FUserAccountData, error) { +func (e *Exchange) FGetAccountInfo(ctx context.Context, symbol currency.Code) (FUserAccountData, error) { var resp FUserAccountData req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAccountData, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAccountData, nil, req, &resp) } // FGetPositionsInfo gets positions info for futures account -func (h *HUOBI) FGetPositionsInfo(ctx context.Context, symbol currency.Code) (FUsersPositionsInfo, error) { +func (e *Exchange) FGetPositionsInfo(ctx context.Context, symbol currency.Code) (FUsersPositionsInfo, error) { var resp FUsersPositionsInfo req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionInformation, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionInformation, nil, req, &resp) } // FGetAllSubAccountAssets gets assets info for all futures subaccounts -func (h *HUOBI) FGetAllSubAccountAssets(ctx context.Context, symbol currency.Code) (FSubAccountAssetsInfo, error) { +func (e *Exchange) FGetAllSubAccountAssets(ctx context.Context, symbol currency.Code) (FSubAccountAssetsInfo, error) { var resp FSubAccountAssetsInfo req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAllSubAccountAssets, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAllSubAccountAssets, nil, req, &resp) } // FGetSingleSubAccountInfo gets assets info for a futures subaccount -func (h *HUOBI) FGetSingleSubAccountInfo(ctx context.Context, symbol, subUID string) (FSingleSubAccountAssetsInfo, error) { +func (e *Exchange) FGetSingleSubAccountInfo(ctx context.Context, symbol, subUID string) (FSingleSubAccountAssetsInfo, error) { var resp FSingleSubAccountAssetsInfo req := make(map[string]any) if symbol != "" { req["symbol"] = symbol } req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountAssets, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountAssets, nil, req, &resp) } // FGetSingleSubPositions gets positions info for a single sub account -func (h *HUOBI) FGetSingleSubPositions(ctx context.Context, symbol, subUID string) (FSingleSubAccountPositionsInfo, error) { +func (e *Exchange) FGetSingleSubPositions(ctx context.Context, symbol, subUID string) (FSingleSubAccountPositionsInfo, error) { var resp FSingleSubAccountPositionsInfo req := make(map[string]any) if symbol != "" { req["symbol"] = symbol } req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountPositions, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountPositions, nil, req, &resp) } // FGetFinancialRecords gets financial records for futures -func (h *HUOBI) FGetFinancialRecords(ctx context.Context, symbol, recordType string, createDate, pageIndex, pageSize int64) (FFinancialRecords, error) { +func (e *Exchange) FGetFinancialRecords(ctx context.Context, symbol, recordType string, createDate, pageIndex, pageSize int64) (FFinancialRecords, error) { var resp FFinancialRecords req := make(map[string]any) if symbol != "" { @@ -573,11 +573,11 @@ func (h *HUOBI) FGetFinancialRecords(ctx context.Context, symbol, recordType str if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFinancialRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFinancialRecords, nil, req, &resp) } // FGetSettlementRecords gets settlement records for futures -func (h *HUOBI) FGetSettlementRecords(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64, startTime, endTime time.Time) (FSettlementRecords, error) { +func (e *Exchange) FGetSettlementRecords(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64, startTime, endTime time.Time) (FSettlementRecords, error) { var resp FSettlementRecords req := make(map[string]any) req["symbol"] = symbol @@ -594,11 +594,11 @@ func (h *HUOBI) FGetSettlementRecords(ctx context.Context, symbol currency.Code, req["start_time"] = strconv.FormatInt(startTime.Unix()*1000, 10) req["end_time"] = strconv.FormatInt(endTime.Unix()*1000, 10) } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSettlementRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSettlementRecords, nil, req, &resp) } // FGetOrderLimits gets order limits for futures contracts -func (h *HUOBI) FGetOrderLimits(ctx context.Context, symbol, orderPriceType string) (FContractInfoOnOrderLimit, error) { +func (e *Exchange) FGetOrderLimits(ctx context.Context, symbol, orderPriceType string) (FContractInfoOnOrderLimit, error) { var resp FContractInfoOnOrderLimit req := make(map[string]any) if symbol != "" { @@ -610,61 +610,61 @@ func (h *HUOBI) FGetOrderLimits(ctx context.Context, symbol, orderPriceType stri } req["order_price_type"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderLimitInfo, nil, req, &resp) } // FContractTradingFee gets futures contract trading fees -func (h *HUOBI) FContractTradingFee(ctx context.Context, symbol currency.Code) (FContractTradingFeeData, error) { +func (e *Exchange) FContractTradingFee(ctx context.Context, symbol currency.Code) (FContractTradingFeeData, error) { var resp FContractTradingFeeData req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fContractTradingFee, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fContractTradingFee, nil, req, &resp) } // FGetTransferLimits gets transfer limits for futures -func (h *HUOBI) FGetTransferLimits(ctx context.Context, symbol currency.Code) (FTransferLimitData, error) { +func (e *Exchange) FGetTransferLimits(ctx context.Context, symbol currency.Code) (FTransferLimitData, error) { var resp FTransferLimitData req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferLimitInfo, nil, req, &resp) } // FGetPositionLimits gets position limits for futures -func (h *HUOBI) FGetPositionLimits(ctx context.Context, symbol currency.Code) (FPositionLimitData, error) { +func (e *Exchange) FGetPositionLimits(ctx context.Context, symbol currency.Code) (FPositionLimitData, error) { var resp FPositionLimitData req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionLimitInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionLimitInfo, nil, req, &resp) } // FGetAssetsAndPositions gets assets and positions for futures -func (h *HUOBI) FGetAssetsAndPositions(ctx context.Context, symbol currency.Code) (FAssetsAndPositionsData, error) { +func (e *Exchange) FGetAssetsAndPositions(ctx context.Context, symbol currency.Code) (FAssetsAndPositionsData, error) { var resp FAssetsAndPositionsData req := make(map[string]any) req["symbol"] = symbol - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryAssetsAndPositions, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryAssetsAndPositions, nil, req, &resp) } // FTransfer transfers assets between master and subaccounts -func (h *HUOBI) FTransfer(ctx context.Context, subUID, symbol, transferType string, amount float64) (FAccountTransferData, error) { +func (e *Exchange) FTransfer(ctx context.Context, subUID, symbol, transferType string, amount float64) (FAccountTransferData, error) { var resp FAccountTransferData req := make(map[string]any) req["symbol"] = symbol @@ -674,11 +674,11 @@ func (h *HUOBI) FTransfer(ctx context.Context, subUID, symbol, transferType stri return resp, errors.New("invalid transferType received") } req["type"] = transferType - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransfer, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransfer, nil, req, &resp) } // FGetTransferRecords gets transfer records data for futures -func (h *HUOBI) FGetTransferRecords(ctx context.Context, symbol, transferType string, createDate, pageIndex, pageSize int64) (FTransferRecords, error) { +func (e *Exchange) FGetTransferRecords(ctx context.Context, symbol, transferType string, createDate, pageIndex, pageSize int64) (FTransferRecords, error) { var resp FTransferRecords req := make(map[string]any) if symbol != "" { @@ -698,25 +698,25 @@ func (h *HUOBI) FGetTransferRecords(ctx context.Context, symbol, transferType st if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferRecords, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferRecords, nil, req, &resp) } // FGetAvailableLeverage gets available leverage data for futures -func (h *HUOBI) FGetAvailableLeverage(ctx context.Context, symbol currency.Code) (FAvailableLeverageData, error) { +func (e *Exchange) FGetAvailableLeverage(ctx context.Context, symbol currency.Code) (FAvailableLeverageData, error) { var resp FAvailableLeverageData req := make(map[string]any) if !symbol.IsEmpty() { - codeValue, err := h.formatFuturesCode(symbol) + codeValue, err := e.formatFuturesCode(symbol) if err != nil { return resp, err } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAvailableLeverage, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAvailableLeverage, nil, req, &resp) } // FOrder places an order for futures -func (h *HUOBI) FOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, clientOrderID, direction, offset, orderPriceType string, price, volume, leverageRate float64) (FOrderData, error) { +func (e *Exchange) FOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, clientOrderID, direction, offset, orderPriceType string, price, volume, leverageRate float64) (FOrderData, error) { var resp FOrderData req := make(map[string]any) if symbol != "" { @@ -729,7 +729,7 @@ func (h *HUOBI) FOrder(ctx context.Context, contractCode currency.Pair, symbol, req["contract_type"] = t } if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -757,11 +757,11 @@ func (h *HUOBI) FOrder(ctx context.Context, contractCode currency.Pair, symbol, req["volume"] = volume req["price"] = price req["offset"] = offset - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrder, nil, req, &resp) } // FPlaceBatchOrder places a batch of orders for futures -func (h *HUOBI) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (FBatchOrderResponse, error) { +func (e *Exchange) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (FBatchOrderResponse, error) { var resp FBatchOrderResponse req := make(map[string]any) if len(data) > 10 || len(data) == 0 { @@ -773,7 +773,7 @@ func (h *HUOBI) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (F if err != nil { return resp, err } - formattedPair, err := h.FormatExchangeCurrency(unformattedPair, asset.Futures) + formattedPair, err := e.FormatExchangeCurrency(unformattedPair, asset.Futures) if err != nil { return resp, err } @@ -792,11 +792,11 @@ func (h *HUOBI) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (F } } req["orders_data"] = data - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fBatchOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fBatchOrder, nil, req, &resp) } // FCancelOrder cancels a futures order -func (h *HUOBI) FCancelOrder(ctx context.Context, baseCurrency currency.Code, orderID, clientOrderID string) (FCancelOrderData, error) { +func (e *Exchange) FCancelOrder(ctx context.Context, baseCurrency currency.Code, orderID, clientOrderID string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]any) if baseCurrency.IsEmpty() { @@ -809,11 +809,11 @@ func (h *HUOBI) FCancelOrder(ctx context.Context, baseCurrency currency.Code, or if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelOrder, nil, req, &resp) } // FCancelAllOrders cancels all futures order for a given symbol -func (h *HUOBI) FCancelAllOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { +func (e *Exchange) FCancelAllOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]any) if symbol != "" { @@ -826,17 +826,17 @@ func (h *HUOBI) FCancelAllOrders(ctx context.Context, contractCode currency.Pair req["contract_type"] = t } if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllOrders, nil, req, &resp) } // FFlashCloseOrder flash closes a futures order -func (h *HUOBI) FFlashCloseOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, direction, orderPriceType, clientOrderID string, volume float64) (FOrderData, error) { +func (e *Exchange) FFlashCloseOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, direction, orderPriceType, clientOrderID string, volume float64) (FOrderData, error) { var resp FOrderData req := make(map[string]any) req["symbol"] = symbol @@ -847,7 +847,7 @@ func (h *HUOBI) FFlashCloseOrder(ctx context.Context, contractCode currency.Pair req["contract_type"] = t } if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -864,11 +864,11 @@ func (h *HUOBI) FFlashCloseOrder(ctx context.Context, contractCode currency.Pair } req["orderPriceType"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFlashCloseOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFlashCloseOrder, nil, req, &resp) } // FGetOrderInfo gets order info for futures -func (h *HUOBI) FGetOrderInfo(ctx context.Context, symbol, clientOrderID, orderID string) (FOrderInfo, error) { +func (e *Exchange) FGetOrderInfo(ctx context.Context, symbol, clientOrderID, orderID string) (FOrderInfo, error) { var resp FOrderInfo req := make(map[string]any) req["symbol"] = symbol @@ -878,11 +878,11 @@ func (h *HUOBI) FGetOrderInfo(ctx context.Context, symbol, clientOrderID, orderI if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderInfo, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderInfo, nil, req, &resp) } // FOrderDetails gets order details for futures orders -func (h *HUOBI) FOrderDetails(ctx context.Context, symbol, orderID, orderType string, createdAt time.Time, pageIndex, pageSize int64) (FOrderDetailsData, error) { +func (e *Exchange) FOrderDetails(ctx context.Context, symbol, orderID, orderType string, createdAt time.Time, pageIndex, pageSize int64) (FOrderDetailsData, error) { var resp FOrderDetailsData req := make(map[string]any) req["symbol"] = symbol @@ -899,11 +899,11 @@ func (h *HUOBI) FOrderDetails(ctx context.Context, symbol, orderID, orderType st if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderDetails, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderDetails, nil, req, &resp) } // FGetOpenOrders gets order details for futures orders -func (h *HUOBI) FGetOpenOrders(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64) (FOpenOrdersData, error) { +func (e *Exchange) FGetOpenOrders(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64) (FOpenOrdersData, error) { var resp FOpenOrdersData req := make(map[string]any) req["symbol"] = symbol @@ -913,11 +913,11 @@ func (h *HUOBI) FGetOpenOrders(ctx context.Context, symbol currency.Code, pageIn if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryOpenOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryOpenOrders, nil, req, &resp) } // FGetOrderHistory gets order history for futures -func (h *HUOBI) FGetOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, reqType, orderType string, status []order.Status, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { +func (e *Exchange) FGetOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, reqType, orderType string, status []order.Status, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { var resp FOrderHistoryData req := make(map[string]any) req["symbol"] = symbol @@ -953,7 +953,7 @@ func (h *HUOBI) FGetOrderHistory(ctx context.Context, contractCode currency.Pair } req["create_date"] = createDate if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -972,11 +972,11 @@ func (h *HUOBI) FGetOrderHistory(ctx context.Context, contractCode currency.Pair if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderHistory, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderHistory, nil, req, &resp) } // FTradeHistory gets trade history data for futures -func (h *HUOBI) FTradeHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType string, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { +func (e *Exchange) FTradeHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType string, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { var resp FOrderHistoryData req := make(map[string]any) req["symbol"] = symbol @@ -986,7 +986,7 @@ func (h *HUOBI) FTradeHistory(ctx context.Context, contractCode currency.Pair, s } req["trade_type"] = tType if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -1002,11 +1002,11 @@ func (h *HUOBI) FTradeHistory(ctx context.Context, contractCode currency.Pair, s if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fMatchResult, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fMatchResult, nil, req, &resp) } // FPlaceTriggerOrder places a trigger order for futures -func (h *HUOBI) FPlaceTriggerOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, triggerType, orderPriceType, direction, offset string, triggerPrice, orderPrice, volume, leverageRate float64) (FTriggerOrderData, error) { +func (e *Exchange) FPlaceTriggerOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, triggerType, orderPriceType, direction, offset string, triggerPrice, orderPrice, volume, leverageRate float64) (FTriggerOrderData, error) { var resp FTriggerOrderData req := make(map[string]any) if symbol != "" { @@ -1019,7 +1019,7 @@ func (h *HUOBI) FPlaceTriggerOrder(ctx context.Context, contractCode currency.Pa req["contract_type"] = t } if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -1043,25 +1043,25 @@ func (h *HUOBI) FPlaceTriggerOrder(ctx context.Context, contractCode currency.Pa return resp, errors.New("invalid order price type") } req["order_price_type"] = orderPriceType - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrder, nil, req, &resp) } // FCancelTriggerOrder cancels trigger order for futures -func (h *HUOBI) FCancelTriggerOrder(ctx context.Context, symbol, orderID string) (FCancelOrderData, error) { +func (e *Exchange) FCancelTriggerOrder(ctx context.Context, symbol, orderID string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]any) req["symbol"] = symbol req["order_id"] = orderID - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelTriggerOrder, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelTriggerOrder, nil, req, &resp) } // FCancelAllTriggerOrders cancels all trigger order for futures -func (h *HUOBI) FCancelAllTriggerOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { +func (e *Exchange) FCancelAllTriggerOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]any) req["symbol"] = symbol if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -1073,16 +1073,16 @@ func (h *HUOBI) FCancelAllTriggerOrders(ctx context.Context, contractCode curren } req["contract_type"] = t } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllTriggerOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllTriggerOrders, nil, req, &resp) } // FQueryTriggerOpenOrders queries open trigger orders for futures -func (h *HUOBI) FQueryTriggerOpenOrders(ctx context.Context, contractCode currency.Pair, symbol string, pageIndex, pageSize int64) (FTriggerOpenOrders, error) { +func (e *Exchange) FQueryTriggerOpenOrders(ctx context.Context, contractCode currency.Pair, symbol string, pageIndex, pageSize int64) (FTriggerOpenOrders, error) { var resp FTriggerOpenOrders req := make(map[string]any) req["symbol"] = symbol if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -1094,16 +1094,16 @@ func (h *HUOBI) FQueryTriggerOpenOrders(ctx context.Context, contractCode curren if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOpenOrders, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOpenOrders, nil, req, &resp) } // FQueryTriggerOrderHistory queries trigger order history for futures -func (h *HUOBI) FQueryTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, status string, createDate, pageIndex, pageSize int64) (FTriggerOrderHistoryData, error) { +func (e *Exchange) FQueryTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, status string, createDate, pageIndex, pageSize int64) (FTriggerOrderHistoryData, error) { var resp FTriggerOrderHistoryData req := make(map[string]any) req["symbol"] = symbol if !contractCode.IsEmpty() { - codeValue, err := h.FormatSymbol(contractCode, asset.Futures) + codeValue, err := e.FormatSymbol(contractCode, asset.Futures) if err != nil { return resp, err } @@ -1131,16 +1131,16 @@ func (h *HUOBI) FQueryTriggerOrderHistory(ctx context.Context, contractCode curr if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrderHistory, nil, req, &resp) + return resp, e.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrderHistory, nil, req, &resp) } // FuturesAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result any) error { - creds, err := h.GetCredentials(ctx) +func (e *Exchange) FuturesAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := h.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -1190,13 +1190,13 @@ func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ctx context.Context, ep exchange Headers: headers, Body: body, Result: &tempResp, - Verbose: h.Verbose, - HTTPDebugging: h.HTTPDebugging, - HTTPRecording: h.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - err = h.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) + err = e.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) if err != nil { return err } @@ -1213,8 +1213,8 @@ func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ctx context.Context, ep exchange return json.Unmarshal(tempResp, result) } -func (h *HUOBI) formatFuturesCode(p currency.Code) (string, error) { - pairFmt, err := h.GetPairFormat(asset.Futures, true) +func (e *Exchange) formatFuturesCode(p currency.Code) (string, error) { + pairFmt, err := e.GetPairFormat(asset.Futures, true) if err != nil { return "", err } @@ -1225,10 +1225,10 @@ func (h *HUOBI) formatFuturesCode(p currency.Code) (string, error) { } // formatFuturesPair handles pairs in the format as "BTC-NW" and "BTC210827" -func (h *HUOBI) formatFuturesPair(p currency.Pair, convertQuoteToExpiry bool) (string, error) { +func (e *Exchange) formatFuturesPair(p currency.Pair, convertQuoteToExpiry bool) (string, error) { if slices.Contains(validContractExpiryCodes, strings.ToUpper(p.Quote.String())) { if convertQuoteToExpiry { - cp, err := h.pairFromContractExpiryCode(p) + cp, err := e.pairFromContractExpiryCode(p) if err != nil { return "", err } @@ -1240,16 +1240,16 @@ func (h *HUOBI) formatFuturesPair(p currency.Pair, convertQuoteToExpiry bool) (s return p.Format(currency.PairFormat{Delimiter: "-", Uppercase: true}).String(), nil } - return h.FormatSymbol(p, asset.Futures) + return e.FormatSymbol(p, asset.Futures) } // pairFromContractExpiryCode converts a pair with contract expiry shorthand in the Quote to a concrete tradable pair // We need this because some apis, such as ticker, use BTC_CW, NW, CQ, NQ // Other apis, such as contract_info, use contract type of this_week, next_week, quarter (sic), and next_quater -func (h *HUOBI) pairFromContractExpiryCode(p currency.Pair) (currency.Pair, error) { - h.futureContractCodesMutex.RLock() - defer h.futureContractCodesMutex.RUnlock() - exp, ok := h.futureContractCodes[p.Quote.String()] +func (e *Exchange) pairFromContractExpiryCode(p currency.Pair) (currency.Pair, error) { + e.futureContractCodesMutex.RLock() + defer e.futureContractCodesMutex.RUnlock() + exp, ok := e.futureContractCodes[p.Quote.String()] if !ok { return p, fmt.Errorf("%w: %s", errInvalidContractType, p.Quote.String()) } diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index b7727894fba..66307e4dae6 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -45,7 +45,7 @@ const ( ) var ( - h *HUOBI + e *Exchange btcFutureDatedPair currency.Pair btccwPair = currency.NewPair(currency.BTC, currency.NewCode("CW")) btcusdPair = currency.NewPairWithDelimiter("BTC", "USD", "-") @@ -54,15 +54,15 @@ var ( ) func TestMain(m *testing.M) { - h = new(HUOBI) - if err := testexch.Setup(h); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("HUOBI Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - h.API.AuthenticatedSupport = true - h.API.AuthenticatedWebsocketSupport = true - h.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -70,234 +70,234 @@ func TestMain(m *testing.M) { func TestGetCurrenciesIncludingChains(t *testing.T) { t.Parallel() - r, err := h.GetCurrenciesIncludingChains(t.Context(), currency.EMPTYCODE) + r, err := e.GetCurrenciesIncludingChains(t.Context(), currency.EMPTYCODE) require.NoError(t, err) assert.Greater(t, len(r), 1, "should get more than one currency back") - r, err = h.GetCurrenciesIncludingChains(t.Context(), currency.USDT) + r, err = e.GetCurrenciesIncludingChains(t.Context(), currency.USDT) require.NoError(t, err) assert.Equal(t, 1, len(r), "Should only get one currency back") } func TestFGetContractInfo(t *testing.T) { t.Parallel() - _, err := h.FGetContractInfo(t.Context(), "", "", currency.EMPTYPAIR) + _, err := e.FGetContractInfo(t.Context(), "", "", currency.EMPTYPAIR) require.NoError(t, err) } func TestFIndexPriceInfo(t *testing.T) { t.Parallel() - _, err := h.FIndexPriceInfo(t.Context(), currency.BTC) + _, err := e.FIndexPriceInfo(t.Context(), currency.BTC) require.NoError(t, err) } func TestFContractPriceLimitations(t *testing.T) { t.Parallel() - _, err := h.FContractPriceLimitations(t.Context(), + _, err := e.FContractPriceLimitations(t.Context(), "BTC", "this_week", currency.EMPTYPAIR) require.NoError(t, err) } func TestFContractOpenInterest(t *testing.T) { t.Parallel() - _, err := h.FContractOpenInterest(t.Context(), "BTC", "this_week", currency.EMPTYPAIR) + _, err := e.FContractOpenInterest(t.Context(), "BTC", "this_week", currency.EMPTYPAIR) require.NoError(t, err) } func TestFGetEstimatedDeliveryPrice(t *testing.T) { t.Parallel() - _, err := h.FGetEstimatedDeliveryPrice(t.Context(), currency.BTC) + _, err := e.FGetEstimatedDeliveryPrice(t.Context(), currency.BTC) require.NoError(t, err) } func TestFGetMarketDepth(t *testing.T) { t.Parallel() - _, err := h.FGetMarketDepth(t.Context(), btccwPair, "step5") + _, err := e.FGetMarketDepth(t.Context(), btccwPair, "step5") require.NoError(t, err) } func TestFGetKlineData(t *testing.T) { t.Parallel() - _, err := h.FGetKlineData(t.Context(), btccwPair, "5min", 5, time.Now().Add(-time.Minute*5), time.Now()) + _, err := e.FGetKlineData(t.Context(), btccwPair, "5min", 5, time.Now().Add(-time.Minute*5), time.Now()) require.NoError(t, err) } func TestFGetMarketOverviewData(t *testing.T) { t.Parallel() - _, err := h.FGetMarketOverviewData(t.Context(), btccwPair) + _, err := e.FGetMarketOverviewData(t.Context(), btccwPair) require.NoError(t, err) } func TestFLastTradeData(t *testing.T) { t.Parallel() - _, err := h.FLastTradeData(t.Context(), btccwPair) + _, err := e.FLastTradeData(t.Context(), btccwPair) require.NoError(t, err) } func TestFRequestPublicBatchTrades(t *testing.T) { t.Parallel() - _, err := h.FRequestPublicBatchTrades(t.Context(), btccwPair, 50) + _, err := e.FRequestPublicBatchTrades(t.Context(), btccwPair, 50) require.NoError(t, err) } func TestFQueryTieredAdjustmentFactor(t *testing.T) { t.Parallel() - _, err := h.FQueryTieredAdjustmentFactor(t.Context(), currency.BTC) + _, err := e.FQueryTieredAdjustmentFactor(t.Context(), currency.BTC) require.NoError(t, err) } func TestFQueryHisOpenInterest(t *testing.T) { t.Parallel() - _, err := h.FQueryHisOpenInterest(t.Context(), "BTC", "this_week", "60min", "cont", 3) + _, err := e.FQueryHisOpenInterest(t.Context(), "BTC", "this_week", "60min", "cont", 3) require.NoError(t, err) } func TestFQuerySystemStatus(t *testing.T) { t.Parallel() - _, err := h.FQuerySystemStatus(t.Context(), currency.BTC) + _, err := e.FQuerySystemStatus(t.Context(), currency.BTC) require.NoError(t, err) } func TestFQueryTopAccountsRatio(t *testing.T) { t.Parallel() - _, err := h.FQueryTopAccountsRatio(t.Context(), "BTC", "5min") + _, err := e.FQueryTopAccountsRatio(t.Context(), "BTC", "5min") require.NoError(t, err) } func TestFQueryTopPositionsRatio(t *testing.T) { t.Parallel() - _, err := h.FQueryTopPositionsRatio(t.Context(), "BTC", "5min") + _, err := e.FQueryTopPositionsRatio(t.Context(), "BTC", "5min") require.NoError(t, err) } func TestFLiquidationOrders(t *testing.T) { t.Parallel() - if _, err := h.FLiquidationOrders(t.Context(), currency.BTC, "filled", 0, 0, "", 0); err != nil { + if _, err := e.FLiquidationOrders(t.Context(), currency.BTC, "filled", 0, 0, "", 0); err != nil { t.Error(err) } } func TestFIndexKline(t *testing.T) { t.Parallel() - _, err := h.FIndexKline(t.Context(), btccwPair, "5min", 5) + _, err := e.FIndexKline(t.Context(), btccwPair, "5min", 5) require.NoError(t, err) } func TestFGetBasisData(t *testing.T) { t.Parallel() - _, err := h.FGetBasisData(t.Context(), btccwPair, "5min", "open", 3) + _, err := e.FGetBasisData(t.Context(), btccwPair, "5min", "open", 3) require.NoError(t, err) } func TestFGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetAccountInfo(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetAccountInfo(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetPositionsInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetPositionsInfo(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetPositionsInfo(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetAllSubAccountAssets(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetAllSubAccountAssets(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetAllSubAccountAssets(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetSingleSubAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetSingleSubAccountInfo(t.Context(), "", "154263566") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetSingleSubAccountInfo(t.Context(), "", "154263566") require.NoError(t, err) } func TestFGetSingleSubPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetSingleSubPositions(t.Context(), "", "154263566") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetSingleSubPositions(t.Context(), "", "154263566") require.NoError(t, err) } func TestFGetFinancialRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetFinancialRecords(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetFinancialRecords(t.Context(), "BTC", "closeLong", 2, 0, 0) require.NoError(t, err) } func TestFGetSettlementRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetSettlementRecords(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetSettlementRecords(t.Context(), currency.BTC, 0, 0, time.Now().Add(-48*time.Hour), time.Now()) require.NoError(t, err) } func TestFContractTradingFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FContractTradingFee(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FContractTradingFee(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetTransferLimits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetTransferLimits(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetTransferLimits(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetPositionLimits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetPositionLimits(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetPositionLimits(t.Context(), currency.EMPTYCODE) require.NoError(t, err) } func TestFGetAssetsAndPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetAssetsAndPositions(t.Context(), currency.HT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetAssetsAndPositions(t.Context(), currency.HT) require.NoError(t, err) } func TestFTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FTransfer(t.Context(), "154263566", "HT", "sub_to_master", 5) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FTransfer(t.Context(), "154263566", "HT", "sub_to_master", 5) require.NoError(t, err) } func TestFGetTransferRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetTransferRecords(t.Context(), "HT", "master_to_sub", 90, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetTransferRecords(t.Context(), "HT", "master_to_sub", 90, 0, 0) require.NoError(t, err) } func TestFGetAvailableLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetAvailableLeverage(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetAvailableLeverage(t.Context(), currency.BTC) require.NoError(t, err) } func TestFOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FOrder(t.Context(), currency.EMPTYPAIR, "BTC", "quarter", "123", "BUY", "open", "limit", 1, 1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FOrder(t.Context(), currency.EMPTYPAIR, "BTC", "quarter", "123", "BUY", "open", "limit", 1, 1, 1) require.NoError(t, err) } func TestFPlaceBatchOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) var req []fBatchOrderData order1 := fBatchOrderData{ Symbol: "btc", @@ -322,58 +322,58 @@ func TestFPlaceBatchOrder(t *testing.T) { OrderPriceType: "limit", } req = append(req, order1, order2) - _, err := h.FPlaceBatchOrder(t.Context(), req) + _, err := e.FPlaceBatchOrder(t.Context(), req) require.NoError(t, err) } func TestFCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FCancelOrder(t.Context(), currency.BTC, "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FCancelOrder(t.Context(), currency.BTC, "123", "") require.NoError(t, err) } func TestFCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - updatePairsOnce(t, h) - _, err := h.FCancelAllOrders(t.Context(), btcFutureDatedPair, "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + updatePairsOnce(t, e) + _, err := e.FCancelAllOrders(t.Context(), btcFutureDatedPair, "", "") require.NoError(t, err) } func TestFFlashCloseOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FFlashCloseOrder(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FFlashCloseOrder(t.Context(), currency.EMPTYPAIR, "BTC", "quarter", "BUY", "lightning", "", 1) require.NoError(t, err) } func TestFGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetOrderInfo(t.Context(), "BTC", "", "123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetOrderInfo(t.Context(), "BTC", "", "123") require.NoError(t, err) } func TestFOrderDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FOrderDetails(t.Context(), "BTC", "123", "quotation", time.Now().Add(-1*time.Hour), 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FOrderDetails(t.Context(), "BTC", "123", "quotation", time.Now().Add(-1*time.Hour), 0, 0) require.NoError(t, err) } func TestFGetOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetOpenOrders(t.Context(), currency.BTC, 1, 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetOpenOrders(t.Context(), currency.BTC, 1, 2) require.NoError(t, err) } func TestFGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FGetOrderHistory(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FGetOrderHistory(t.Context(), currency.EMPTYPAIR, "BTC", "all", "all", "limit", []order.Status{}, @@ -383,350 +383,350 @@ func TestFGetOrderHistory(t *testing.T) { func TestFTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.FTradeHistory(t.Context(), currency.EMPTYPAIR, "BTC", "all", 10, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.FTradeHistory(t.Context(), currency.EMPTYPAIR, "BTC", "all", 10, 0, 0) require.NoError(t, err) } func TestFPlaceTriggerOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FPlaceTriggerOrder(t.Context(), currency.EMPTYPAIR, "EOS", "quarter", "greaterOrEqual", "limit", "buy", "close", 1.1, 1.05, 5, 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FPlaceTriggerOrder(t.Context(), currency.EMPTYPAIR, "EOS", "quarter", "greaterOrEqual", "limit", "buy", "close", 1.1, 1.05, 5, 2) require.NoError(t, err) } func TestFCancelTriggerOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FCancelTriggerOrder(t.Context(), "ETH", "123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FCancelTriggerOrder(t.Context(), "ETH", "123") require.NoError(t, err) } func TestFCancelAllTriggerOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FCancelAllTriggerOrders(t.Context(), currency.EMPTYPAIR, "BTC", "this_week") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FCancelAllTriggerOrders(t.Context(), currency.EMPTYPAIR, "BTC", "this_week") require.NoError(t, err) } func TestFQueryTriggerOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FQueryTriggerOpenOrders(t.Context(), currency.EMPTYPAIR, "BTC", 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FQueryTriggerOpenOrders(t.Context(), currency.EMPTYPAIR, "BTC", 0, 0) require.NoError(t, err) } func TestFQueryTriggerOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.FQueryTriggerOrderHistory(t.Context(), currency.EMPTYPAIR, "EOS", "all", "all", 10, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.FQueryTriggerOrderHistory(t.Context(), currency.EMPTYPAIR, "EOS", "all", "all", 10, 0, 0) require.NoError(t, err) } func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := h.FetchTradablePairs(t.Context(), asset.Futures) + _, err := e.FetchTradablePairs(t.Context(), asset.Futures) require.NoError(t, err) } func TestUpdateTickerSpot(t *testing.T) { t.Parallel() - _, err := h.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("INV", "ALID", "-"), asset.Spot) + _, err := e.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("INV", "ALID", "-"), asset.Spot) assert.ErrorContains(t, err, "invalid symbol") - _, err = h.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("BTC", "USDT", "_"), asset.Spot) + _, err = e.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("BTC", "USDT", "_"), asset.Spot) require.NoError(t, err) } func TestUpdateTickerCMF(t *testing.T) { t.Parallel() - _, err := h.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("INV", "ALID", "_"), asset.CoinMarginedFutures) + _, err := e.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("INV", "ALID", "_"), asset.CoinMarginedFutures) assert.ErrorContains(t, err, "symbol data error") - _, err = h.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("BTC", "USD", "_"), asset.CoinMarginedFutures) + _, err = e.UpdateTicker(t.Context(), currency.NewPairWithDelimiter("BTC", "USD", "_"), asset.CoinMarginedFutures) require.NoError(t, err) } func TestUpdateTickerFutures(t *testing.T) { t.Parallel() - _, err := h.UpdateTicker(t.Context(), btccwPair, asset.Futures) + _, err := e.UpdateTicker(t.Context(), btccwPair, asset.Futures) require.NoError(t, err) } func TestUpdateOrderbookSpot(t *testing.T) { t.Parallel() - _, err := h.UpdateOrderbook(t.Context(), btcusdtPair, asset.Spot) + _, err := e.UpdateOrderbook(t.Context(), btcusdtPair, asset.Spot) require.NoError(t, err) } func TestUpdateOrderbookCMF(t *testing.T) { t.Parallel() - _, err := h.UpdateOrderbook(t.Context(), btcusdPair, asset.CoinMarginedFutures) + _, err := e.UpdateOrderbook(t.Context(), btcusdPair, asset.CoinMarginedFutures) require.NoError(t, err) } func TestUpdateOrderbookFuture(t *testing.T) { t.Parallel() - _, err := h.UpdateOrderbook(t.Context(), btccwPair, asset.Futures) + _, err := e.UpdateOrderbook(t.Context(), btccwPair, asset.Futures) require.NoError(t, err) - _, err = h.UpdateOrderbook(t.Context(), btcusdPair, asset.CoinMarginedFutures) + _, err = e.UpdateOrderbook(t.Context(), btcusdPair, asset.CoinMarginedFutures) require.NoError(t, err) } func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - updatePairsOnce(t, h) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + updatePairsOnce(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, Pairs: []currency.Pair{currency.NewBTCUSDT()}, AssetType: asset.Spot, Side: order.AnySide, } - _, err := h.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) require.NoError(t, err) getOrdersRequest.Pairs = []currency.Pair{btcusdPair} getOrdersRequest.AssetType = asset.CoinMarginedFutures - _, err = h.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) require.NoError(t, err) getOrdersRequest.Pairs = []currency.Pair{btcFutureDatedPair} getOrdersRequest.AssetType = asset.Futures - _, err = h.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) require.NoError(t, err) } func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Futures}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Futures}) require.NoError(t, err) } func TestQuerySwapIndexPriceInfo(t *testing.T) { t.Parallel() - _, err := h.QuerySwapIndexPriceInfo(t.Context(), btcusdPair) + _, err := e.QuerySwapIndexPriceInfo(t.Context(), btcusdPair) require.NoError(t, err) } func TestSwapOpenInterestInformation(t *testing.T) { t.Parallel() - _, err := h.SwapOpenInterestInformation(t.Context(), btcusdPair) + _, err := e.SwapOpenInterestInformation(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetSwapMarketDepth(t *testing.T) { t.Parallel() - _, err := h.GetSwapMarketDepth(t.Context(), btcusdPair, "step0") + _, err := e.GetSwapMarketDepth(t.Context(), btcusdPair, "step0") require.NoError(t, err) } func TestGetSwapKlineData(t *testing.T) { t.Parallel() - r, err := h.GetSwapKlineData(t.Context(), btcusdPair, "5min", 5, time.Now().Add(-time.Hour), time.Now()) + r, err := e.GetSwapKlineData(t.Context(), btcusdPair, "5min", 5, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotEmpty(t, r.Data, "GetSwapKlineData should return some data") } func TestGetSwapMarketOverview(t *testing.T) { t.Parallel() - _, err := h.GetSwapMarketOverview(t.Context(), btcusdPair) + _, err := e.GetSwapMarketOverview(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetLastTrade(t *testing.T) { t.Parallel() - _, err := h.GetLastTrade(t.Context(), btcusdPair) + _, err := e.GetLastTrade(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetBatchTrades(t *testing.T) { t.Parallel() - _, err := h.GetBatchTrades(t.Context(), btcusdPair, 5) + _, err := e.GetBatchTrades(t.Context(), btcusdPair, 5) require.NoError(t, err) } func TestGetTieredAjustmentFactorInfo(t *testing.T) { t.Parallel() - _, err := h.GetTieredAjustmentFactorInfo(t.Context(), btcusdPair) + _, err := e.GetTieredAjustmentFactorInfo(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetOpenInterestInfo(t *testing.T) { t.Parallel() - updatePairsOnce(t, h) - _, err := h.GetOpenInterestInfo(t.Context(), btcusdPair, "5min", "cryptocurrency", 50) + updatePairsOnce(t, e) + _, err := e.GetOpenInterestInfo(t.Context(), btcusdPair, "5min", "cryptocurrency", 50) require.NoError(t, err) } func TestGetTraderSentimentIndexAccount(t *testing.T) { t.Parallel() - _, err := h.GetTraderSentimentIndexAccount(t.Context(), btcusdPair, "5min") + _, err := e.GetTraderSentimentIndexAccount(t.Context(), btcusdPair, "5min") require.NoError(t, err) } func TestGetTraderSentimentIndexPosition(t *testing.T) { t.Parallel() - _, err := h.GetTraderSentimentIndexPosition(t.Context(), btcusdPair, "5min") + _, err := e.GetTraderSentimentIndexPosition(t.Context(), btcusdPair, "5min") require.NoError(t, err) } func TestGetLiquidationOrders(t *testing.T) { t.Parallel() - _, err := h.GetLiquidationOrders(t.Context(), btcusdPair, "closed", time.Now().AddDate(0, 0, -2), time.Now(), "", 0) + _, err := e.GetLiquidationOrders(t.Context(), btcusdPair, "closed", time.Now().AddDate(0, 0, -2), time.Now(), "", 0) assert.NoError(t, err, "GetLiquidationOrders should not error") } func TestGetHistoricalFundingRates(t *testing.T) { t.Parallel() - _, err := h.GetHistoricalFundingRatesForPair(t.Context(), btcusdPair, 0, 0) + _, err := e.GetHistoricalFundingRatesForPair(t.Context(), btcusdPair, 0, 0) require.NoError(t, err) } func TestGetPremiumIndexKlineData(t *testing.T) { t.Parallel() - _, err := h.GetPremiumIndexKlineData(t.Context(), btcusdPair, "5min", 15) + _, err := e.GetPremiumIndexKlineData(t.Context(), btcusdPair, "5min", 15) require.NoError(t, err) } func TestGetEstimatedFundingRates(t *testing.T) { t.Parallel() - _, err := h.GetPremiumIndexKlineData(t.Context(), btcusdPair, "5min", 15) + _, err := e.GetPremiumIndexKlineData(t.Context(), btcusdPair, "5min", 15) require.NoError(t, err) } func TestGetBasisData(t *testing.T) { t.Parallel() - _, err := h.GetBasisData(t.Context(), btcusdPair, "5min", "close", 5) + _, err := e.GetBasisData(t.Context(), btcusdPair, "5min", "close", 5) require.NoError(t, err) } func TestGetSystemStatusInfo(t *testing.T) { t.Parallel() - _, err := h.GetSystemStatusInfo(t.Context(), btcusdPair) + _, err := e.GetSystemStatusInfo(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetSwapPriceLimits(t *testing.T) { t.Parallel() - _, err := h.GetSwapPriceLimits(t.Context(), btcusdPair) + _, err := e.GetSwapPriceLimits(t.Context(), btcusdPair) require.NoError(t, err) } func TestGetMarginRates(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetMarginRates(t.Context(), btcusdtPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginRates(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetSwapAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapAccountInfo(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapAccountInfo(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapPositionsInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapPositionsInfo(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapPositionsInfo(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapAssetsAndPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapAssetsAndPositions(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapAssetsAndPositions(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapAllSubAccAssets(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapAllSubAccAssets(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapAllSubAccAssets(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSubAccPositionInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSubAccPositionInfo(t.Context(), ethusdPair, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSubAccPositionInfo(t.Context(), ethusdPair, 0) require.NoError(t, err) } func TestGetAccountFinancialRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetAccountFinancialRecords(t.Context(), ethusdPair, "3,4", 15, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountFinancialRecords(t.Context(), ethusdPair, "3,4", 15, 0, 0) require.NoError(t, err) } func TestGetSwapSettlementRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - r, err := h.GetSwapSettlementRecords(t.Context(), ethusdPair, time.Now().AddDate(0, -1, 0), time.Now(), 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + r, err := e.GetSwapSettlementRecords(t.Context(), ethusdPair, time.Now().AddDate(0, -1, 0), time.Now(), 0, 0) require.NoError(t, err) assert.NotEmpty(t, r.Data, "GetSwapSettlementRecords should return some data") } func TestGetAvailableLeverage(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetAvailableLeverage(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAvailableLeverage(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapOrderLimitInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapOrderLimitInfo(t.Context(), ethusdPair, "limit") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapOrderLimitInfo(t.Context(), ethusdPair, "limit") require.NoError(t, err) } func TestGetSwapTradingFeeInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapTradingFeeInfo(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapTradingFeeInfo(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapTransferLimitInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapTransferLimitInfo(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapTransferLimitInfo(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapPositionLimitInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapPositionLimitInfo(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapPositionLimitInfo(t.Context(), ethusdPair) require.NoError(t, err) } func TestAccountTransferData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.AccountTransferData(t.Context(), ethusdPair, "123", "master_to_sub", 15) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.AccountTransferData(t.Context(), ethusdPair, "123", "master_to_sub", 15) require.NoError(t, err) } func TestAccountTransferRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.AccountTransferRecords(t.Context(), ethusdPair, "master_to_sub", 12, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.AccountTransferRecords(t.Context(), ethusdPair, "master_to_sub", 12, 0, 0) require.NoError(t, err) } func TestPlaceSwapOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.PlaceSwapOrders(t.Context(), ethusdPair, "", "buy", "open", "limit", 0.01, 1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceSwapOrders(t.Context(), ethusdPair, "", "buy", "open", "limit", 0.01, 1, 1) require.NoError(t, err) } func TestPlaceSwapBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) var req BatchOrderRequestType order1 := batchOrderData{ ContractCode: "ETH-USD", @@ -750,161 +750,161 @@ func TestPlaceSwapBatchOrders(t *testing.T) { } req.Data = append(req.Data, order1, order2) - _, err := h.PlaceSwapBatchOrders(t.Context(), req) + _, err := e.PlaceSwapBatchOrders(t.Context(), req) require.NoError(t, err) } func TestCancelSwapOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelSwapOrder(t.Context(), "test123", "", ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelSwapOrder(t.Context(), "test123", "", ethusdPair) require.NoError(t, err) } func TestCancelAllSwapOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelAllSwapOrders(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllSwapOrders(t.Context(), ethusdPair) require.NoError(t, err) } func TestPlaceLightningCloseOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.PlaceLightningCloseOrder(t.Context(), ethusdPair, "buy", "lightning", 5, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceLightningCloseOrder(t.Context(), ethusdPair, "buy", "lightning", 5, 1) require.NoError(t, err) } func TestGetSwapOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapOrderInfo(t.Context(), ethusdPair, "123", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapOrderInfo(t.Context(), ethusdPair, "123", "") require.NoError(t, err) } func TestGetSwapOrderDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapOrderDetails(t.Context(), ethusdPair, "123", "10", "cancelledOrder", 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapOrderDetails(t.Context(), ethusdPair, "123", "10", "cancelledOrder", 0, 0) require.NoError(t, err) } func TestGetSwapOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapOpenOrders(t.Context(), ethusdPair, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapOpenOrders(t.Context(), ethusdPair, 0, 0) require.NoError(t, err) } func TestGetSwapOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapOrderHistory(t.Context(), ethusdPair, "all", "all", []order.Status{order.PartiallyCancelled, order.Active}, 25, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapOrderHistory(t.Context(), ethusdPair, "all", "all", []order.Status{order.PartiallyCancelled, order.Active}, 25, 0, 0) require.NoError(t, err) } func TestGetSwapTradeHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapTradeHistory(t.Context(), ethusdPair, "liquidateShort", 10, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapTradeHistory(t.Context(), ethusdPair, "liquidateShort", 10, 0, 0) require.NoError(t, err) } func TestPlaceSwapTriggerOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.PlaceSwapTriggerOrder(t.Context(), ethusdPair, "greaterOrEqual", "buy", "open", "optimal_5", 5, 3, 1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.PlaceSwapTriggerOrder(t.Context(), ethusdPair, "greaterOrEqual", "buy", "open", "optimal_5", 5, 3, 1, 1) require.NoError(t, err) } func TestCancelSwapTriggerOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelSwapTriggerOrder(t.Context(), ethusdPair, "test123") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelSwapTriggerOrder(t.Context(), ethusdPair, "test123") require.NoError(t, err) } func TestCancelAllSwapTriggerOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelAllSwapTriggerOrders(t.Context(), ethusdPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelAllSwapTriggerOrders(t.Context(), ethusdPair) require.NoError(t, err) } func TestGetSwapTriggerOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetSwapTriggerOrderHistory(t.Context(), ethusdPair, "open", "all", 15, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSwapTriggerOrderHistory(t.Context(), ethusdPair, "open", "all", 15, 0, 0) require.NoError(t, err) } func TestGetSwapMarkets(t *testing.T) { t.Parallel() - _, err := h.GetSwapMarkets(t.Context(), currency.EMPTYPAIR) + _, err := e.GetSwapMarkets(t.Context(), currency.EMPTYPAIR) require.NoError(t, err) } func TestGetSpotKline(t *testing.T) { t.Parallel() - _, err := h.GetSpotKline(t.Context(), KlinesRequestParams{Symbol: btcusdtPair, Period: "1min"}) + _, err := e.GetSpotKline(t.Context(), KlinesRequestParams{Symbol: btcusdtPair, Period: "1min"}) require.NoError(t, err) } func TestGetHistoricCandles(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - updatePairsOnce(t, h) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + updatePairsOnce(t, e) endTime := time.Now().Add(-time.Hour).Truncate(time.Hour) - _, err := h.GetHistoricCandles(t.Context(), btcusdtPair, asset.Spot, kline.OneMin, endTime.Add(-time.Hour), endTime) + _, err := e.GetHistoricCandles(t.Context(), btcusdtPair, asset.Spot, kline.OneMin, endTime.Add(-time.Hour), endTime) require.NoError(t, err) - _, err = h.GetHistoricCandles(t.Context(), btcusdtPair, asset.Spot, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) + _, err = e.GetHistoricCandles(t.Context(), btcusdtPair, asset.Spot, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) require.NoError(t, err) - _, err = h.GetHistoricCandles(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) + _, err = e.GetHistoricCandles(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) require.NoError(t, err) - _, err = h.GetHistoricCandles(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) + _, err = e.GetHistoricCandles(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) require.NoError(t, err) } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - updatePairsOnce(t, h) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + updatePairsOnce(t, e) endTime := time.Now().Add(-time.Hour).Truncate(time.Hour) - _, err := h.GetHistoricCandlesExtended(t.Context(), btcusdtPair, asset.Spot, kline.OneMin, endTime.Add(-time.Hour), endTime) + _, err := e.GetHistoricCandlesExtended(t.Context(), btcusdtPair, asset.Spot, kline.OneMin, endTime.Add(-time.Hour), endTime) require.ErrorIs(t, err, common.ErrFunctionNotSupported) - _, err = h.GetHistoricCandlesExtended(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) + _, err = e.GetHistoricCandlesExtended(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneDay, endTime.AddDate(0, 0, -7), endTime) require.NoError(t, err) // demonstrate that adjusting time doesn't wreck non-day intervals - _, err = h.GetHistoricCandlesExtended(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneHour, endTime.AddDate(0, 0, -1), endTime) + _, err = e.GetHistoricCandlesExtended(t.Context(), btcFutureDatedPair, asset.Futures, kline.OneHour, endTime.AddDate(0, 0, -1), endTime) require.NoError(t, err) - _, err = h.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneDay, endTime.AddDate(0, 0, -7), time.Now()) + _, err = e.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneDay, endTime.AddDate(0, 0, -7), time.Now()) require.NoError(t, err) - _, err = h.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneHour, endTime.AddDate(0, 0, -1), time.Now()) + _, err = e.GetHistoricCandlesExtended(t.Context(), btcusdPair, asset.CoinMarginedFutures, kline.OneHour, endTime.AddDate(0, 0, -1), time.Now()) require.NoError(t, err) } func TestGetMarketDetailMerged(t *testing.T) { t.Parallel() - _, err := h.GetMarketDetailMerged(t.Context(), btcusdtPair) + _, err := e.GetMarketDetailMerged(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetDepth(t *testing.T) { t.Parallel() - _, err := h.GetDepth(t.Context(), + _, err := e.GetDepth(t.Context(), &OrderBookDataRequestParams{ Symbol: btcusdtPair, Type: OrderBookDataRequestParamsTypeStep1, @@ -914,94 +914,94 @@ func TestGetDepth(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := h.GetTrades(t.Context(), btcusdtPair) + _, err := e.GetTrades(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetLatestSpotPrice(t *testing.T) { t.Parallel() - _, err := h.GetLatestSpotPrice(t.Context(), btcusdtPair) + _, err := e.GetLatestSpotPrice(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := h.GetTradeHistory(t.Context(), btcusdtPair, 50) + _, err := e.GetTradeHistory(t.Context(), btcusdtPair, 50) require.NoError(t, err) } func TestGetMarketDetail(t *testing.T) { t.Parallel() - _, err := h.GetMarketDetail(t.Context(), btcusdtPair) + _, err := e.GetMarketDetail(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetSymbols(t *testing.T) { t.Parallel() - _, err := h.GetSymbols(t.Context()) + _, err := e.GetSymbols(t.Context()) require.NoError(t, err) } func TestGetCurrencies(t *testing.T) { t.Parallel() - _, err := h.GetCurrencies(t.Context()) + _, err := e.GetCurrencies(t.Context()) require.NoError(t, err) } func TestGet24HrMarketSummary(t *testing.T) { t.Parallel() - _, err := h.Get24HrMarketSummary(t.Context(), btcusdtPair) + _, err := e.Get24HrMarketSummary(t.Context(), btcusdtPair) require.NoError(t, err) } func TestGetTicker(t *testing.T) { t.Parallel() - _, err := h.GetTickers(t.Context()) + _, err := e.GetTickers(t.Context()) require.NoError(t, err) } func TestGetTimestamp(t *testing.T) { t.Parallel() - st, err := h.GetCurrentServerTime(t.Context()) + st, err := e.GetCurrentServerTime(t.Context()) require.NoError(t, err) assert.NotEmpty(t, st, "GetCurrentServerTime should return a time") } func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := h.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) assert.NotEmpty(t, st, "GetServerTime should return a time") } func TestGetAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.GetAccounts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.GetAccounts(t.Context()) require.NoError(t, err) } func TestGetAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - result, err := h.GetAccounts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.GetAccounts(t.Context()) require.NoError(t, err, "GetAccounts must not error") userID := strconv.FormatInt(result[0].ID, 10) - _, err = h.GetAccountBalance(t.Context(), userID) + _, err = e.GetAccountBalance(t.Context(), userID) require.NoError(t, err, "GetAccountBalance must not error") } func TestGetAggregatedBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetAggregatedBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAggregatedBalance(t.Context()) require.NoError(t, err) } func TestSpotNewOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) arg := SpotNewOrderRequestParams{ Symbol: btcusdtPair, AccountID: 1997024, @@ -1010,42 +1010,42 @@ func TestSpotNewOrder(t *testing.T) { Type: SpotNewOrderRequestTypeBuyLimit, } - _, err := h.SpotNewOrder(t.Context(), &arg) + _, err := e.SpotNewOrder(t.Context(), &arg) require.NoError(t, err) } func TestCancelExistingOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelExistingOrder(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelExistingOrder(t.Context(), 1337) assert.Error(t, err) } func TestGetOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.GetOrder(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.GetOrder(t.Context(), 1337) require.NoError(t, err) } func TestGetMarginLoanOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetMarginLoanOrders(t.Context(), btcusdtPair, "", "", "", "", "", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginLoanOrders(t.Context(), btcusdtPair, "", "", "", "", "", "", "") require.NoError(t, err) } func TestGetMarginAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetMarginAccountBalance(t.Context(), btcusdtPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetMarginAccountBalance(t.Context(), btcusdtPair) require.NoError(t, err) } func TestCancelWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelWithdraw(t.Context(), 1337) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelWithdraw(t.Context(), 1337) require.Error(t, err) } @@ -1065,9 +1065,9 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := h.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err) - if !sharedtestvalues.AreAPICredentialsSet(h) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType) } else { assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType) @@ -1078,65 +1078,65 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() // CryptocurrencyTradeFee Basic - _, err := h.GetFee(feeBuilder) + _, err := e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee High quantity feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyWithdrawalFee Invalid currency feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - _, err = h.GetFee(feeBuilder) + _, err = e.GetFee(feeBuilder) require.NoError(t, err) } func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := h.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() assert.Equal(t, expectedResult, withdrawPermissions) } @@ -1149,8 +1149,8 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := h.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(h) { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -1161,12 +1161,12 @@ func TestGetActiveOrders(t *testing.T) { // ---------------------------------------------------------------------------------------------------------------------------- func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - accounts, err := h.GetAccounts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + accounts, err := e.GetAccounts(t.Context()) require.NoError(t, err, "GetAccounts must not error") orderSubmission := &order.Submit{ - Exchange: h.Name, + Exchange: e.Name, Pair: currency.Pair{ Base: currency.BTC, Quote: currency.USDT, @@ -1178,14 +1178,14 @@ func TestSubmitOrder(t *testing.T) { ClientID: strconv.FormatInt(accounts[0].ID, 10), AssetType: asset.Spot, } - response, err := h.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) require.NoError(t, err) assert.Equal(t, order.New, response.Status, "response status should be correct") } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", AccountID: "1", @@ -1193,13 +1193,13 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := h.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) require.NoError(t, err) } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := order.Cancel{ OrderID: "1", @@ -1208,32 +1208,32 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := h.CancelAllOrders(t.Context(), &orderCancellation) + _, err := e.CancelAllOrders(t.Context(), &orderCancellation) require.NoError(t, err) } func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) for _, a := range []asset.Item{asset.Spot, asset.CoinMarginedFutures, asset.Futures} { - _, err := h.UpdateAccountInfo(t.Context(), a) + _, err := e.UpdateAccountInfo(t.Context(), a) assert.NoErrorf(t, err, "UpdateAccountInfo should not error for asset %s", a) } } func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) - _, err := h.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) require.Error(t, err, "ModifyOrder must error without any order details") } func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, h, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: h.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -1242,26 +1242,26 @@ func TestWithdraw(t *testing.T) { }, } - _, err := h.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) require.ErrorContains(t, err, withdraw.ErrStrAmountMustBeGreaterThanZero) } func TestWithdrawFiat(t *testing.T) { t.Parallel() - _, err := h.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) + _, err := e.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - _, err := h.WithdrawFiatFundsToInternationalBank(t.Context(), &withdraw.Request{}) + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdraw.Request{}) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestQueryDepositAddress(t *testing.T) { t.Parallel() - _, err := h.QueryDepositAddress(t.Context(), currency.USDT) - if sharedtestvalues.AreAPICredentialsSet(h) { + _, err := e.QueryDepositAddress(t.Context(), currency.USDT) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -1270,8 +1270,8 @@ func TestQueryDepositAddress(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := h.GetDepositAddress(t.Context(), currency.USDT, "", "uSdTeRc20") - if sharedtestvalues.AreAPICredentialsSet(h) { + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", "uSdTeRc20") + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -1280,8 +1280,8 @@ func TestGetDepositAddress(t *testing.T) { func TestQueryWithdrawQuota(t *testing.T) { t.Parallel() - _, err := h.QueryWithdrawQuotas(t.Context(), currency.BTC.Lower().String()) - if sharedtestvalues.AreAPICredentialsSet(h) { + _, err := e.QueryWithdrawQuotas(t.Context(), currency.BTC.Lower().String()) + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err) } else { require.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled) @@ -1290,21 +1290,21 @@ func TestQueryWithdrawQuota(t *testing.T) { func TestWSCandles(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.kline.1min", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.CandlesChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.kline.1min", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.CandlesChannel}) require.NoError(t, err, "AddSubscriptions must not error") - testexch.FixtureToDataHandler(t, "testdata/wsCandles.json", h.wsHandleData) - close(h.Websocket.DataHandler) - require.Len(t, h.Websocket.DataHandler, 1, "Must see correct number of records") - cAny := <-h.Websocket.DataHandler + testexch.FixtureToDataHandler(t, "testdata/wsCandles.json", e.wsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 1, "Must see correct number of records") + cAny := <-e.Websocket.DataHandler c, ok := cAny.(websocket.KlineData) require.True(t, ok, "Must get the correct type from DataHandler") exp := websocket.KlineData{ Timestamp: time.UnixMilli(1489474082831), Pair: btcusdtPair, AssetType: asset.Spot, - Exchange: h.Name, + Exchange: e.Name, OpenPrice: 7962.62, ClosePrice: 8014.56, HighPrice: 14962.77, @@ -1317,14 +1317,14 @@ func TestWSCandles(t *testing.T) { func TestWSOrderbook(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.depth.step0", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.OrderbookChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.depth.step0", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.OrderbookChannel}) require.NoError(t, err, "AddSubscriptions must not error") - testexch.FixtureToDataHandler(t, "testdata/wsOrderbook.json", h.wsHandleData) - close(h.Websocket.DataHandler) - require.Len(t, h.Websocket.DataHandler, 1, "Must see correct number of records") - dAny := <-h.Websocket.DataHandler + testexch.FixtureToDataHandler(t, "testdata/wsOrderbook.json", e.wsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 1, "Must see correct number of records") + dAny := <-e.Websocket.DataHandler d, ok := dAny.(*orderbook.Depth) require.True(t, ok, "Must get the correct type from DataHandler") require.NotNil(t, d) @@ -1345,16 +1345,16 @@ func TestWSOrderbook(t *testing.T) { // TestWSHandleAllTradesMsg ensures wsHandleAllTrades sends trade.Data to the ws.DataHandler func TestWSHandleAllTradesMsg(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.trade.detail", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.AllTradesChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.trade.detail", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.AllTradesChannel}) require.NoError(t, err, "AddSubscriptions must not error") - h.SetSaveTradeDataStatus(true) - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", h.wsHandleData) - close(h.Websocket.DataHandler) + e.SetSaveTradeDataStatus(true) + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) exp := []trade.Data{ { - Exchange: h.Name, + Exchange: e.Name, CurrencyPair: btcusdtPair, Timestamp: time.UnixMilli(1630994963173).UTC(), Price: 52648.62, @@ -1364,7 +1364,7 @@ func TestWSHandleAllTradesMsg(t *testing.T) { AssetType: asset.Spot, }, { - Exchange: h.Name, + Exchange: e.Name, CurrencyPair: btcusdtPair, Timestamp: time.UnixMilli(1630994963184).UTC(), Price: 52648.73, @@ -1374,11 +1374,11 @@ func TestWSHandleAllTradesMsg(t *testing.T) { AssetType: asset.Spot, }, } - require.Len(t, h.Websocket.DataHandler, 2, "Must see correct number of trades") - for resp := range h.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, 2, "Must see correct number of trades") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 1 - len(h.Websocket.DataHandler) + i := 1 - len(e.Websocket.DataHandler) require.Equalf(t, exp[i], v, "Trade [%d] must be correct", i) case error: t.Error(v) @@ -1386,19 +1386,19 @@ func TestWSHandleAllTradesMsg(t *testing.T) { t.Errorf("Unexpected type in DataHandler: %T(%s)", v, v) } } - require.Empty(t, h.Websocket.DataHandler, "Must not see any errors going to datahandler") + require.Empty(t, e.Websocket.DataHandler, "Must not see any errors going to datahandler") } func TestWSTicker(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.detail", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.TickerChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "market.btcusdt.detail", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.TickerChannel}) require.NoError(t, err, "AddSubscriptions must not error") - testexch.FixtureToDataHandler(t, "testdata/wsTicker.json", h.wsHandleData) - close(h.Websocket.DataHandler) - require.Len(t, h.Websocket.DataHandler, 1, "Must see correct number of records") - tickAny := <-h.Websocket.DataHandler + testexch.FixtureToDataHandler(t, "testdata/wsTicker.json", e.wsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 1, "Must see correct number of records") + tickAny := <-e.Websocket.DataHandler tick, ok := tickAny.(*ticker.Price) require.True(t, ok, "Must get the correct type from DataHandler") require.NotNil(t, tick) @@ -1411,7 +1411,7 @@ func TestWSTicker(t *testing.T) { Open: 51823.62, Close: 52379.99, Pair: btcusdtPair, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: asset.Spot, LastUpdated: time.UnixMilli(1630998026649), } @@ -1420,43 +1420,43 @@ func TestWSTicker(t *testing.T) { func TestWSAccountUpdate(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "accounts.update#2", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyAccountChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "accounts.update#2", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyAccountChannel}) require.NoError(t, err, "AddSubscriptions must not error") - h.SetSaveTradeDataStatus(true) - testexch.FixtureToDataHandler(t, "testdata/wsMyAccount.json", h.wsHandleData) - close(h.Websocket.DataHandler) - require.Len(t, h.Websocket.DataHandler, 3, "Must see correct number of records") + e.SetSaveTradeDataStatus(true) + testexch.FixtureToDataHandler(t, "testdata/wsMyAccount.json", e.wsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 3, "Must see correct number of records") exp := []WsAccountUpdate{ {Currency: "btc", AccountID: 123456, Balance: 23.111, ChangeType: "transfer", AccountType: "trade", ChangeTime: types.Time(time.UnixMilli(1568601800000)), SeqNum: 1}, {Currency: "btc", AccountID: 33385, Available: 2028.69, ChangeType: "order.match", AccountType: "trade", ChangeTime: types.Time(time.UnixMilli(1574393385167)), SeqNum: 2}, {Currency: "usdt", AccountID: 14884859, Available: 20.29388158, Balance: 20.29388158, AccountType: "trade", SeqNum: 3}, } - for _, e := range exp { - uAny := <-h.Websocket.DataHandler + for _, ex := range exp { + uAny := <-e.Websocket.DataHandler u, ok := uAny.(WsAccountUpdate) require.True(t, ok, "Must get the correct type from DataHandler") require.NotNil(t, u) - assert.Equal(t, e, u) + assert.Equal(t, ex, u) } } func TestWSOrderUpdate(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "orders#*", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyOrdersChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "orders#*", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyOrdersChannel}) require.NoError(t, err, "AddSubscriptions must not error") - h.SetSaveTradeDataStatus(true) - errs := testexch.FixtureToDataHandlerWithErrors(t, "testdata/wsMyOrders.json", h.wsHandleData) - close(h.Websocket.DataHandler) + e.SetSaveTradeDataStatus(true) + errs := testexch.FixtureToDataHandlerWithErrors(t, "testdata/wsMyOrders.json", e.wsHandleData) + close(e.Websocket.DataHandler) require.Equal(t, 1, len(errs), "Must receive the correct number of errors back") require.ErrorContains(t, errs[0].Err, "error with order \"test1\": invalid.client.order.id (NT) (2002)") - require.Len(t, h.Websocket.DataHandler, 4, "Must see correct number of records") + require.Len(t, e.Websocket.DataHandler, 4, "Must see correct number of records") exp := []*order.Detail{ { - Exchange: h.Name, + Exchange: e.Name, Pair: btcusdtPair, Side: order.Buy, Status: order.Rejected, @@ -1465,7 +1465,7 @@ func TestWSOrderUpdate(t *testing.T) { LastUpdated: time.UnixMicro(1583853365586000), }, { - Exchange: h.Name, + Exchange: e.Name, Pair: btcusdtPair, Side: order.Buy, Status: order.Cancelled, @@ -1474,7 +1474,7 @@ func TestWSOrderUpdate(t *testing.T) { LastUpdated: time.UnixMicro(1583853365586000), }, { - Exchange: h.Name, + Exchange: e.Name, Pair: btcusdtPair, Side: order.Sell, Status: order.New, @@ -1487,7 +1487,7 @@ func TestWSOrderUpdate(t *testing.T) { LastUpdated: time.UnixMicro(1583853365586000), }, { - Exchange: h.Name, + Exchange: e.Name, Pair: btcusdtPair, Side: order.Buy, Status: order.New, @@ -1499,28 +1499,28 @@ func TestWSOrderUpdate(t *testing.T) { LastUpdated: time.UnixMicro(1731039387696000), }, } - for _, e := range exp { - m := <-h.Websocket.DataHandler + for _, ex := range exp { + m := <-e.Websocket.DataHandler require.IsType(t, &order.Detail{}, m, "Must get the correct type from DataHandler") d, _ := m.(*order.Detail) require.NotNil(t, d) - assert.Equal(t, e, d, "Order Detail should match") + assert.Equal(t, ex, d, "Order Detail should match") } } func TestWSMyTrades(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Setup Instance must not error") - err := h.Websocket.AddSubscriptions(h.Websocket.Conn, &subscription.Subscription{Key: "trade.clearing#btcusdt#1", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyTradesChannel}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Key: "trade.clearing#btcusdt#1", Asset: asset.Spot, Pairs: currency.Pairs{btcusdtPair}, Channel: subscription.MyTradesChannel}) require.NoError(t, err, "AddSubscriptions must not error") - h.SetSaveTradeDataStatus(true) - testexch.FixtureToDataHandler(t, "testdata/wsMyTrades.json", h.wsHandleData) - close(h.Websocket.DataHandler) - require.Len(t, h.Websocket.DataHandler, 1, "Must see correct number of records") - m := <-h.Websocket.DataHandler + e.SetSaveTradeDataStatus(true) + testexch.FixtureToDataHandler(t, "testdata/wsMyTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 1, "Must see correct number of records") + m := <-e.Websocket.DataHandler exp := &order.Detail{ - Exchange: h.Name, + Exchange: e.Name, Pair: btcusdtPair, Side: order.Buy, Status: order.PartiallyFilled, @@ -1536,7 +1536,7 @@ func TestWSMyTrades(t *testing.T) { Price: 9999.99, Amount: 0.96, Fee: 19.88, - Exchange: h.Name, + Exchange: e.Name, TID: "919219323232", Side: order.Buy, IsMaker: false, @@ -1623,75 +1623,75 @@ func TestFormatExchangeKlineInterval(t *testing.T) { {kline.OneYear, "1year"}, {kline.TwoWeek, ""}, } { - assert.Equalf(t, tt.output, h.FormatExchangeKlineInterval(tt.interval), "FormatExchangeKlineInterval should return correctly for %s", tt.output) + assert.Equalf(t, tt.output, e.FormatExchangeKlineInterval(tt.interval), "FormatExchangeKlineInterval should return correctly for %s", tt.output) } } func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := h.GetRecentTrades(t.Context(), btcusdtPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), btcusdtPair, asset.Spot) require.NoError(t, err) - _, err = h.GetRecentTrades(t.Context(), btccwPair, asset.Futures) + _, err = e.GetRecentTrades(t.Context(), btccwPair, asset.Futures) require.NoError(t, err) - _, err = h.GetRecentTrades(t.Context(), btcusdPair, asset.CoinMarginedFutures) + _, err = e.GetRecentTrades(t.Context(), btcusdPair, asset.CoinMarginedFutures) require.NoError(t, err) } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := h.GetHistoricTrades(t.Context(), btcusdtPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), btcusdtPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) require.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - c, err := h.GetAvailableTransferChains(t.Context(), currency.USDT) + c, err := e.GetAvailableTransferChains(t.Context(), currency.USDT) require.NoError(t, err) require.Greater(t, len(c), 2, "Must get more than 2 chains") } func TestFormatFuturesPair(t *testing.T) { t.Parallel() - updatePairsOnce(t, h) + updatePairsOnce(t, e) - r, err := h.formatFuturesPair(btccwPair, false) + r, err := e.formatFuturesPair(btccwPair, false) require.NoError(t, err) assert.Equal(t, "BTC_CW", r) // pair in the format of BTC210827 but make it lower case to test correct formatting - r, err = h.formatFuturesPair(btcFutureDatedPair.Lower(), false) + r, err = e.formatFuturesPair(btcFutureDatedPair.Lower(), false) require.NoError(t, err) assert.Len(t, r, 9, "Should be an 9 character string") assert.Equal(t, "BTC2", r[0:4], "Should start with btc and a date this millennium") - r, err = h.formatFuturesPair(btccwPair, true) + r, err = e.formatFuturesPair(btccwPair, true) require.NoError(t, err) assert.Len(t, r, 9, "Should be an 9 character string") assert.Equal(t, "BTC2", r[0:4], "Should start with btc and a date this millennium") - r, err = h.formatFuturesPair(currency.NewBTCUSDT(), false) + r, err = e.formatFuturesPair(currency.NewBTCUSDT(), false) require.NoError(t, err) assert.Equal(t, "BTC-USDT", r) } func TestSearchForExistedWithdrawsAndDeposits(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.SearchForExistedWithdrawsAndDeposits(t.Context(), currency.BTC, "deposit", "", 0, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.SearchForExistedWithdrawsAndDeposits(t.Context(), currency.BTC, "deposit", "", 0, 100) require.NoError(t, err) } func TestCancelOrderBatch(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelOrderBatch(t.Context(), []string{"1234"}, nil) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelOrderBatch(t.Context(), []string{"1234"}, nil) require.NoError(t, err) } func TestCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h, canManipulateRealOrders) - _, err := h.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1234", AssetType: asset.Spot, @@ -1703,48 +1703,48 @@ func TestCancelBatchOrders(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, h) - _, err := h.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) require.NoError(t, err) } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := h.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = h.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) require.ErrorIs(t, err, asset.ErrNotSupported) - _, err = h.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.CoinMarginedFutures) require.NoError(t, err) - _, err = h.GetFuturesContractDetails(t.Context(), asset.Futures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.Futures) require.NoError(t, err) } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Test Instance Setup must not fail") - updatePairsOnce(t, h) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test Instance Setup must not fail") + updatePairsOnce(t, e) - _, err := h.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSD(), IncludePredictedRate: true, }) require.ErrorIs(t, err, asset.ErrNotSupported) - _, err = h.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.CoinMarginedFutures, Pair: currency.NewBTCUSD(), IncludePredictedRate: true, }) require.NoError(t, err) - err = h.CurrencyPairs.EnablePair(asset.CoinMarginedFutures, currency.NewBTCUSD()) + err = e.CurrencyPairs.EnablePair(asset.CoinMarginedFutures, currency.NewBTCUSD()) require.ErrorIs(t, err, currency.ErrPairAlreadyEnabled) - _, err = h.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.CoinMarginedFutures, IncludePredictedRate: true, }) @@ -1753,52 +1753,52 @@ func TestGetLatestFundingRates(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := h.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) + is, err := e.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) require.NoError(t, err) assert.False(t, is) - is, err = h.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSDT()) + is, err = e.IsPerpetualFutureCurrency(asset.CoinMarginedFutures, currency.NewBTCUSDT()) require.NoError(t, err) assert.True(t, is) } func TestGetSwapFundingRates(t *testing.T) { t.Parallel() - _, err := h.GetSwapFundingRates(t.Context()) + _, err := e.GetSwapFundingRates(t.Context()) require.NoError(t, err) } func TestGetBatchCoinMarginSwapContracts(t *testing.T) { t.Parallel() - resp, err := h.GetBatchCoinMarginSwapContracts(t.Context()) + resp, err := e.GetBatchCoinMarginSwapContracts(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestGetBatchLinearSwapContracts(t *testing.T) { t.Parallel() - resp, err := h.GetBatchLinearSwapContracts(t.Context()) + resp, err := e.GetBatchLinearSwapContracts(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestGetBatchFuturesContracts(t *testing.T) { t.Parallel() - resp, err := h.GetBatchFuturesContracts(t.Context()) + resp, err := e.GetBatchFuturesContracts(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestUpdateTickers(t *testing.T) { t.Parallel() - updatePairsOnce(t, h) - for _, a := range h.GetAssetTypes(false) { - err := h.UpdateTickers(t.Context(), a) + updatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateTickers(t.Context(), a) require.NoErrorf(t, err, "asset %s", a) - avail, err := h.GetAvailablePairs(a) + avail, err := e.GetAvailablePairs(a) require.NoError(t, err) for _, p := range avail { - _, err = ticker.GetTicker(h.Name, p, a) + _, err = ticker.GetTicker(e.Name, p, a) assert.NoErrorf(t, err, "Could not get ticker for %s %s", a, p) } } @@ -1814,10 +1814,10 @@ var expiryWindows = map[string]uint{ func TestPairFromContractExpiryCode(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Test Instance Setup must not fail") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test Instance Setup must not fail") - _, err := h.FetchTradablePairs(t.Context(), asset.Futures) + _, err := e.FetchTradablePairs(t.Context(), asset.Futures) require.NoError(t, err) tz, err := time.LoadLocation("Asia/Singapore") // Huobi HQ and apparent local time for when codes become effective @@ -1827,7 +1827,7 @@ func TestPairFromContractExpiryCode(t *testing.T) { today = time.Date(today.Year(), today.Month(), today.Day(), 0, 0, 0, 0, tz) // Do not use Truncate; https://github.com/golang/go/issues/55921 for _, cType := range contractExpiryNames { - p, err := h.pairFromContractExpiryCode(currency.Pair{ + p, err := e.pairFromContractExpiryCode(currency.Pair{ Base: currency.BTC, Quote: currency.NewCode(cType), }) @@ -1836,9 +1836,9 @@ func TestPairFromContractExpiryCode(t *testing.T) { } require.NoErrorf(t, err, "pairFromContractExpiryCode must not error for %s code", cType) assert.Equal(t, currency.BTC, p.Base, "pair Base should be BTC") - h.futureContractCodesMutex.RLock() - cachedContract, ok := h.futureContractCodes[cType] - h.futureContractCodesMutex.RUnlock() + e.futureContractCodesMutex.RLock() + cachedContract, ok := e.futureContractCodes[cType] + e.futureContractCodesMutex.RUnlock() require.Truef(t, ok, "%s type must be in futureContractCodes", cType) assert.Equal(t, cachedContract, p.Quote, "pair Quote should match contractExpiryNames") exp, err := time.ParseInLocation("060102", p.Quote.String(), tz) @@ -1855,16 +1855,16 @@ func TestPairFromContractExpiryCode(t *testing.T) { func TestGetOpenInterest(t *testing.T) { t.Parallel() - updatePairsOnce(t, h) + updatePairsOnce(t, e) - _, err := h.GetOpenInterest(t.Context(), key.PairAsset{ + _, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.ETH.Item, Quote: currency.USDT.Item, Asset: asset.USDTMarginedFutures, }) assert.ErrorIs(t, err, asset.ErrNotSupported) - resp, err := h.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.BTC.Item, Quote: currency.USD.Item, Asset: asset.CoinMarginedFutures, @@ -1872,7 +1872,7 @@ func TestGetOpenInterest(t *testing.T) { require.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = h.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: btccwPair.Base.Item, Quote: btccwPair.Quote.Item, Asset: asset.Futures, @@ -1880,43 +1880,43 @@ func TestGetOpenInterest(t *testing.T) { require.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = h.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) require.NoError(t, err) assert.NotEmpty(t, resp) } func TestContractOpenInterestUSDT(t *testing.T) { t.Parallel() - resp, err := h.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, currency.EMPTYPAIR, "", "") + resp, err := e.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, currency.EMPTYPAIR, "", "") assert.NoError(t, err) assert.NotEmpty(t, resp) cp := currency.NewBTCUSDT() - resp, err = h.ContractOpenInterestUSDT(t.Context(), cp, currency.EMPTYPAIR, "", "") + resp, err = e.ContractOpenInterestUSDT(t.Context(), cp, currency.EMPTYPAIR, "", "") assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = h.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, cp, "", "") + resp, err = e.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, cp, "", "") assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = h.ContractOpenInterestUSDT(t.Context(), cp, currency.EMPTYPAIR, "this_week", "") + resp, err = e.ContractOpenInterestUSDT(t.Context(), cp, currency.EMPTYPAIR, "this_week", "") assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = h.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, currency.EMPTYPAIR, "", "swap") + resp, err = e.ContractOpenInterestUSDT(t.Context(), currency.EMPTYPAIR, currency.EMPTYPAIR, "", "swap") assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - updatePairsOnce(t, h) - for _, a := range h.GetAssetTypes(false) { - pairs, err := h.CurrencyPairs.GetPairs(a, false) + updatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := h.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) if (a == asset.Futures || a == asset.CoinMarginedFutures) && !pairs[0].Quote.Equal(currency.USD) && !pairs[0].Quote.Equal(currency.USDT) { require.ErrorIs(t, err, common.ErrNotYetImplemented) } else { @@ -1929,25 +1929,25 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - h.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := h.generateSubscriptions() + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{} - for _, s := range h.Features.Subscriptions { + for _, s := range e.Features.Subscriptions { if s.Asset == asset.Empty { s := s.Clone() //nolint:govet // Intentional lexical scope shadow s.QualifiedChannel = channelName(s) exp = append(exp, s) continue } - for _, a := range h.GetAssetTypes(true) { + for _, a := range e.GetAssetTypes(true) { if s.Asset != asset.All && s.Asset != a { continue } - pairs, err := h.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) pairs = common.SortStrings(pairs).Format(currency.PairFormat{Uppercase: false, Delimiter: ""}) s := s.Clone() //nolint:govet // Intentional lexical scope shadow @@ -1996,14 +1996,14 @@ func wsFixture(tb testing.TB, msg []byte, w *gws.Conn) error { // TestSubscribe exercises live public subscriptions func TestSubscribe(t *testing.T) { t.Parallel() - h := new(HUOBI) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(h), "Test instance Setup must not error") - subs, err := h.Features.Subscriptions.ExpandTemplates(h) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + subs, err := e.Features.Subscriptions.ExpandTemplates(e) require.NoError(t, err, "ExpandTemplates must not error") - testexch.SetupWs(t, h) - err = h.Subscribe(subs) + testexch.SetupWs(t, e) + err = e.Subscribe(subs) require.NoError(t, err, "Subscribe must not error") - got := h.Websocket.GetSubscriptions() + got := e.Websocket.GetSubscriptions() require.Equal(t, 8, len(got), "Must get correct number of subscriptions") for _, s := range got { assert.Equal(t, subscription.SubscribedState, s.State()) @@ -2013,8 +2013,8 @@ func TestSubscribe(t *testing.T) { // TestAuthSubscribe exercises mock subscriptions including private func TestAuthSubscribe(t *testing.T) { t.Parallel() - subCfg := h.Features.Subscriptions - h := testexch.MockWsInstance[HUOBI](t, mockws.CurryWsMockUpgrader(t, wsFixture)) + subCfg := e.Features.Subscriptions + h := testexch.MockWsInstance[Exchange](t, mockws.CurryWsMockUpgrader(t, wsFixture)) h.Websocket.SetCanUseAuthenticatedEndpoints(true) subs, err := subCfg.ExpandTemplates(h) require.NoError(t, err, "ExpandTemplates must not error") @@ -2054,18 +2054,18 @@ func TestGetErrResp(t *testing.T) { func TestBootstrap(t *testing.T) { t.Parallel() - h := new(HUOBI) - require.NoError(t, testexch.Setup(h), "Test Instance Setup must not fail") + e := new(Exchange) + require.NoError(t, testexch.Setup(e), "Test Instance Setup must not fail") - c, err := h.Bootstrap(t.Context()) + c, err := e.Bootstrap(t.Context()) require.NoError(t, err) assert.True(t, c, "Bootstrap should return true to continue") - h.futureContractCodes = nil - h.Features.Enabled.AutoPairUpdates = false - _, err = h.Bootstrap(t.Context()) + e.futureContractCodes = nil + e.Features.Enabled.AutoPairUpdates = false + _, err = e.Bootstrap(t.Context()) require.NoError(t, err) - require.NotNil(t, h.futureContractCodes) + require.NotNil(t, e.futureContractCodes) } var ( @@ -2074,7 +2074,7 @@ var ( ) // updatePairsOnce updates the pairs once, and ensures a future dated contract is enabled -func updatePairsOnce(tb testing.TB, h *HUOBI) { +func updatePairsOnce(tb testing.TB, h *Exchange) { tb.Helper() updatePairsMutex.Lock() diff --git a/exchanges/huobi/huobi_websocket.go b/exchanges/huobi/huobi_websocket.go index cf7f23dc994..0c7192e4494 100644 --- a/exchanges/huobi/huobi_websocket.go +++ b/exchanges/huobi/huobi_websocket.go @@ -75,63 +75,63 @@ var subscriptionNames = map[string]string{ } // WsConnect initiates a new websocket connection -func (h *HUOBI) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !h.Websocket.IsEnabled() || !h.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } - if err := h.Websocket.Conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { + if err := e.Websocket.Conn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { return err } - h.Websocket.Wg.Add(1) - go h.wsReadMsgs(ctx, h.Websocket.Conn) + e.Websocket.Wg.Add(1) + go e.wsReadMsgs(ctx, e.Websocket.Conn) - if h.IsWebsocketAuthenticationSupported() { - if err := h.wsAuthConnect(ctx); err != nil { - h.Websocket.SetCanUseAuthenticatedEndpoints(false) + if e.IsWebsocketAuthenticationSupported() { + if err := e.wsAuthConnect(ctx); err != nil { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) return fmt.Errorf("error authenticating websocket: %w", err) } - h.Websocket.SetCanUseAuthenticatedEndpoints(true) - h.Websocket.Wg.Add(1) - go h.wsReadMsgs(ctx, h.Websocket.AuthConn) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.Wg.Add(1) + go e.wsReadMsgs(ctx, e.Websocket.AuthConn) } return nil } // wsReadMsgs reads and processes messages from a websocket connection -func (h *HUOBI) wsReadMsgs(ctx context.Context, s websocket.Connection) { - defer h.Websocket.Wg.Done() +func (e *Exchange) wsReadMsgs(ctx context.Context, s websocket.Connection) { + defer e.Websocket.Wg.Done() for { msg := s.ReadMessage() if msg.Raw == nil { return } - if err := h.wsHandleData(ctx, msg.Raw); err != nil { - h.Websocket.DataHandler <- err + if err := e.wsHandleData(ctx, msg.Raw); err != nil { + e.Websocket.DataHandler <- err } } } -func (h *HUOBI) wsHandleData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, respRaw []byte) error { if id, err := jsonparser.GetString(respRaw, "id"); err == nil { - if h.Websocket.Match.IncomingWithData(id, respRaw) { + if e.Websocket.Match.IncomingWithData(id, respRaw) { return nil } } if pingValue, err := jsonparser.GetInt(respRaw, "ping"); err == nil { - return h.wsHandleV1ping(ctx, int(pingValue)) + return e.wsHandleV1ping(ctx, int(pingValue)) } if action, err := jsonparser.GetString(respRaw, "action"); err == nil { switch action { case "ping": - return h.wsHandleV2ping(ctx, respRaw) + return e.wsHandleV2ping(ctx, respRaw) case wsSubOp, wsUnsubOp: - return h.wsHandleV2subResp(action, respRaw) + return e.wsHandleV2subResp(action, respRaw) } } @@ -140,68 +140,68 @@ func (h *HUOBI) wsHandleData(ctx context.Context, respRaw []byte) error { } if ch, err := jsonparser.GetString(respRaw, "ch"); err == nil { - s := h.Websocket.GetSubscription(ch) + s := e.Websocket.GetSubscription(ch) if s == nil { return fmt.Errorf("%w: %q", subscription.ErrNotFound, ch) } - return h.wsHandleChannelMsgs(s, respRaw) + return e.wsHandleChannelMsgs(s, respRaw) } - h.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: h.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } return nil } // wsHandleV1ping handles v1 style pings, currently only used with public connections -func (h *HUOBI) wsHandleV1ping(ctx context.Context, pingValue int) error { - if err := h.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(`{"pong":`+strconv.Itoa(pingValue)+`}`)); err != nil { +func (e *Exchange) wsHandleV1ping(ctx context.Context, pingValue int) error { + if err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(`{"pong":`+strconv.Itoa(pingValue)+`}`)); err != nil { return fmt.Errorf("error sending pong response: %w", err) } return nil } // wsHandleV2ping handles v2 style pings, currently only used with private connections -func (h *HUOBI) wsHandleV2ping(ctx context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleV2ping(ctx context.Context, respRaw []byte) error { ts, err := jsonparser.GetInt(respRaw, "data", "ts") if err != nil { return fmt.Errorf("error getting ts from auth ping: %w", err) } - if err := h.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, json.RawMessage(`{"action":"pong","data":{"ts":`+strconv.Itoa(int(ts))+`}}`)); err != nil { + if err := e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, json.RawMessage(`{"action":"pong","data":{"ts":`+strconv.Itoa(int(ts))+`}}`)); err != nil { return fmt.Errorf("error sending auth pong response: %w", err) } return nil } -func (h *HUOBI) wsHandleV2subResp(action string, respRaw []byte) error { +func (e *Exchange) wsHandleV2subResp(action string, respRaw []byte) error { if ch, err := jsonparser.GetString(respRaw, "ch"); err == nil { - return h.Websocket.Match.RequireMatchWithData(action+":"+ch, respRaw) + return e.Websocket.Match.RequireMatchWithData(action+":"+ch, respRaw) } return nil } -func (h *HUOBI) wsHandleChannelMsgs(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleChannelMsgs(s *subscription.Subscription, respRaw []byte) error { switch s.Channel { case subscription.TickerChannel: - return h.wsHandleTickerMsg(s, respRaw) + return e.wsHandleTickerMsg(s, respRaw) case subscription.OrderbookChannel: - return h.wsHandleOrderbookMsg(s, respRaw) + return e.wsHandleOrderbookMsg(s, respRaw) case subscription.CandlesChannel: - return h.wsHandleCandleMsg(s, respRaw) + return e.wsHandleCandleMsg(s, respRaw) case subscription.AllTradesChannel: - return h.wsHandleAllTradesMsg(s, respRaw) + return e.wsHandleAllTradesMsg(s, respRaw) case subscription.MyAccountChannel: - return h.wsHandleMyAccountMsg(respRaw) + return e.wsHandleMyAccountMsg(respRaw) case subscription.MyOrdersChannel: - return h.wsHandleMyOrdersMsg(s, respRaw) + return e.wsHandleMyOrdersMsg(s, respRaw) case subscription.MyTradesChannel: - return h.wsHandleMyTradesMsg(s, respRaw) + return e.wsHandleMyTradesMsg(s, respRaw) } return fmt.Errorf("%w: %s", common.ErrNotYetImplemented, s.Channel) } -func (h *HUOBI) wsHandleCandleMsg(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleCandleMsg(s *subscription.Subscription, respRaw []byte) error { if len(s.Pairs) != 1 { return subscription.ErrNotSinglePair } @@ -209,9 +209,9 @@ func (h *HUOBI) wsHandleCandleMsg(s *subscription.Subscription, respRaw []byte) if err := json.Unmarshal(respRaw, &c); err != nil { return err } - h.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: c.Timestamp.Time(), - Exchange: h.Name, + Exchange: e.Name, AssetType: s.Asset, Pair: s.Pairs[0], OpenPrice: c.Tick.Open, @@ -224,9 +224,9 @@ func (h *HUOBI) wsHandleCandleMsg(s *subscription.Subscription, respRaw []byte) return nil } -func (h *HUOBI) wsHandleAllTradesMsg(s *subscription.Subscription, respRaw []byte) error { - saveTradeData := h.IsSaveTradeDataEnabled() - tradeFeed := h.IsTradeFeedEnabled() +func (e *Exchange) wsHandleAllTradesMsg(s *subscription.Subscription, respRaw []byte) error { + saveTradeData := e.IsSaveTradeDataEnabled() + tradeFeed := e.IsTradeFeedEnabled() if !saveTradeData && !tradeFeed { return nil } @@ -244,7 +244,7 @@ func (h *HUOBI) wsHandleAllTradesMsg(s *subscription.Subscription, respRaw []byt side = order.Sell } trades = append(trades, trade.Data{ - Exchange: h.Name, + Exchange: e.Name, AssetType: s.Asset, CurrencyPair: s.Pairs[0], Timestamp: t.Tick.Data[i].Timestamp.Time().UTC(), @@ -256,7 +256,7 @@ func (h *HUOBI) wsHandleAllTradesMsg(s *subscription.Subscription, respRaw []byt } if tradeFeed { for i := range trades { - h.Websocket.DataHandler <- trades[i] + e.Websocket.DataHandler <- trades[i] } } if saveTradeData { @@ -265,7 +265,7 @@ func (h *HUOBI) wsHandleAllTradesMsg(s *subscription.Subscription, respRaw []byt return nil } -func (h *HUOBI) wsHandleTickerMsg(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleTickerMsg(s *subscription.Subscription, respRaw []byte) error { if len(s.Pairs) != 1 { return subscription.ErrNotSinglePair } @@ -273,8 +273,8 @@ func (h *HUOBI) wsHandleTickerMsg(s *subscription.Subscription, respRaw []byte) if err := json.Unmarshal(respRaw, &wsTicker); err != nil { return err } - h.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: h.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Open: wsTicker.Tick.Open, Close: wsTicker.Tick.Close, Volume: wsTicker.Tick.Amount, @@ -288,7 +288,7 @@ func (h *HUOBI) wsHandleTickerMsg(s *subscription.Subscription, respRaw []byte) return nil } -func (h *HUOBI) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byte) error { if len(s.Pairs) != 1 { return subscription.ErrNotSinglePair } @@ -333,20 +333,20 @@ func (h *HUOBI) wsHandleOrderbookMsg(s *subscription.Subscription, respRaw []byt newOrderBook.Bids = bids newOrderBook.Pair = s.Pairs[0] newOrderBook.Asset = asset.Spot - newOrderBook.Exchange = h.Name - newOrderBook.ValidateOrderbook = h.ValidateOrderbook + newOrderBook.Exchange = e.Name + newOrderBook.ValidateOrderbook = e.ValidateOrderbook newOrderBook.LastUpdated = update.Timestamp.Time() - return h.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } -func (h *HUOBI) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte) error { var msg wsOrderUpdateMsg if err := json.Unmarshal(respRaw, &msg); err != nil { return err } o := msg.Data - p, err := h.CurrencyPairs.Match(o.Symbol, s.Asset) + p, err := e.CurrencyPairs.Match(o.Symbol, s.Asset) if err != nil { return err } @@ -356,7 +356,7 @@ func (h *HUOBI) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte Amount: o.Size, ExecutedAmount: o.ExecutedAmount, RemainingAmount: o.RemainingAmount, - Exchange: h.Name, + Exchange: e.Name, Side: o.Side, AssetType: s.Asset, Pair: p, @@ -374,7 +374,7 @@ func (h *HUOBI) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte } if d.Status, err = order.StringToOrderStatus(o.OrderStatus); err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } @@ -383,7 +383,7 @@ func (h *HUOBI) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte d.Side, err = stringToOrderSide(o.OrderType) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } @@ -393,26 +393,26 @@ func (h *HUOBI) wsHandleMyOrdersMsg(s *subscription.Subscription, respRaw []byte d.Type, err = stringToOrderType(o.OrderType) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } } } - h.Websocket.DataHandler <- d + e.Websocket.DataHandler <- d if o.ErrCode != 0 { return fmt.Errorf("error with order %q: %s (%v)", o.ClientOrderID, o.ErrMessage, o.ErrCode) } return nil } -func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte) error { +func (e *Exchange) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte) error { var msg wsTradeUpdateMsg if err := json.Unmarshal(respRaw, &msg); err != nil { return err } t := msg.Data - p, err := h.CurrencyPairs.Match(t.Symbol, s.Asset) + p, err := e.CurrencyPairs.Match(t.Symbol, s.Asset) if err != nil { return err } @@ -420,7 +420,7 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte ClientOrderID: t.ClientOrderID, Price: t.OrderPrice, Amount: t.OrderSize, - Exchange: h.Name, + Exchange: e.Name, Side: t.Side, AssetType: s.Asset, Pair: p, @@ -430,7 +430,7 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte } if d.Status, err = order.StringToOrderStatus(t.OrderStatus); err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } @@ -439,7 +439,7 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte d.Side, err = stringToOrderSide(t.OrderType) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } @@ -449,7 +449,7 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte d.Type, err = stringToOrderType(t.OrderType) if err != nil { return &order.ClassificationError{ - Exchange: h.Name, + Exchange: e.Name, OrderID: d.OrderID, Err: err, } @@ -460,7 +460,7 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte Price: t.TradePrice, Amount: t.TradeVolume, Fee: t.TransactFee, - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatInt(t.TradeID, 10), Type: d.Type, Side: d.Side, @@ -468,48 +468,48 @@ func (h *HUOBI) wsHandleMyTradesMsg(s *subscription.Subscription, respRaw []byte Timestamp: t.TradeTime.Time(), }, } - h.Websocket.DataHandler <- d + e.Websocket.DataHandler <- d return nil } -func (h *HUOBI) wsHandleMyAccountMsg(respRaw []byte) error { +func (e *Exchange) wsHandleMyAccountMsg(respRaw []byte) error { u := &wsAccountUpdateMsg{} if err := json.Unmarshal(respRaw, u); err != nil { return err } - h.Websocket.DataHandler <- u.Data + e.Websocket.DataHandler <- u.Data return nil } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (h *HUOBI) generateSubscriptions() (subscription.List, error) { - return h.Features.Subscriptions.ExpandTemplates(h) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (h *HUOBI) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "isWildcardChannel": isWildcardChannel, - "interval": h.FormatExchangeKlineInterval, + "interval": e.FormatExchangeKlineInterval, }).Parse(subTplText) } // Subscribe sends a websocket message to receive data from the channel -func (h *HUOBI) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - subs, errs := subs.ExpandTemplates(h) - return common.AppendError(errs, h.ParallelChanOp(ctx, subs, func(ctx context.Context, l subscription.List) error { return h.manageSubs(ctx, wsSubOp, l) }, 1)) + subs, errs := subs.ExpandTemplates(e) + return common.AppendError(errs, e.ParallelChanOp(ctx, subs, func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsSubOp, l) }, 1)) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (h *HUOBI) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - subs, errs := subs.ExpandTemplates(h) - return common.AppendError(errs, h.ParallelChanOp(ctx, subs, func(ctx context.Context, l subscription.List) error { return h.manageSubs(ctx, wsUnsubOp, l) }, 1)) + subs, errs := subs.ExpandTemplates(e) + return common.AppendError(errs, e.ParallelChanOp(ctx, subs, func(ctx context.Context, l subscription.List) error { return e.manageSubs(ctx, wsUnsubOp, l) }, 1)) } -func (h *HUOBI) manageSubs(ctx context.Context, op string, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.List) error { if len(subs) != 1 { return subscription.ErrBatchingNotSupported } @@ -517,10 +517,10 @@ func (h *HUOBI) manageSubs(ctx context.Context, op string, subs subscription.Lis var c websocket.Connection var req any if s.Authenticated { - c = h.Websocket.AuthConn + c = e.Websocket.AuthConn req = wsReq{Action: op, Channel: s.QualifiedChannel} } else { - c = h.Websocket.Conn + c = e.Websocket.Conn if op == wsSubOp { // Set the id to the channel so that V1 errors can make it back to us req = wsSubReq{ID: wsSubOp + ":" + s.QualifiedChannel, Sub: s.QualifiedChannel} @@ -530,7 +530,7 @@ func (h *HUOBI) manageSubs(ctx context.Context, op string, subs subscription.Lis } if op == wsSubOp { s.SetKey(s.QualifiedChannel) - if err := h.Websocket.AddSubscriptions(c, s); err != nil { + if err := e.Websocket.AddSubscriptions(c, s); err != nil { return fmt.Errorf("%w: %s; error: %w", websocket.ErrSubscriptionFailure, s, err) } } @@ -540,22 +540,22 @@ func (h *HUOBI) manageSubs(ctx context.Context, op string, subs subscription.Lis } if err != nil { if op == wsSubOp { - _ = h.Websocket.RemoveSubscriptions(c, s) + _ = e.Websocket.RemoveSubscriptions(c, s) } return fmt.Errorf("%s: %w", s, err) } if op == wsSubOp { err = s.SetState(subscription.SubscribedState) - if h.Verbose { - log.Debugf(log.ExchangeSys, "%s Subscribed to %s", h.Name, s) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Subscribed to %s", e.Name, s) } } else { - err = h.Websocket.RemoveSubscriptions(c, s) + err = e.Websocket.RemoveSubscriptions(c, s) } return err } -func (h *HUOBI) wsGenerateSignature(creds *account.Credentials, timestamp string) ([]byte, error) { +func (e *Exchange) wsGenerateSignature(creds *account.Credentials, timestamp string) ([]byte, error) { values := url.Values{} values.Set("accessKey", creds.Key) values.Set("signatureMethod", signatureMethod) @@ -565,24 +565,24 @@ func (h *HUOBI) wsGenerateSignature(creds *account.Credentials, timestamp string return crypto.GetHMAC(crypto.HashSHA256, []byte(payload), []byte(creds.Secret)) } -func (h *HUOBI) wsAuthConnect(ctx context.Context) error { - if err := h.Websocket.AuthConn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { +func (e *Exchange) wsAuthConnect(ctx context.Context) error { + if err := e.Websocket.AuthConn.Dial(ctx, &gws.Dialer{}, http.Header{}); err != nil { return fmt.Errorf("authenticated dial failed: %w", err) } - if err := h.wsLogin(ctx); err != nil { + if err := e.wsLogin(ctx); err != nil { return fmt.Errorf("authentication failed: %w", err) } return nil } -func (h *HUOBI) wsLogin(ctx context.Context) error { - creds, err := h.GetCredentials(ctx) +func (e *Exchange) wsLogin(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } ts := time.Now().UTC().Format(wsDateTimeFormatting) - hmac, err := h.wsGenerateSignature(creds, ts) + hmac, err := e.wsGenerateSignature(creds, ts) if err != nil { return err } @@ -598,7 +598,7 @@ func (h *HUOBI) wsLogin(ctx context.Context) error { Timestamp: ts, }, } - c := h.Websocket.AuthConn + c := e.Websocket.AuthConn if err := c.SendJSONMessage(ctx, request.Unset, req); err != nil { return err } diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index cd45d4893f8..464a817540b 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -34,12 +34,12 @@ import ( ) // SetDefaults sets default values for the exchange -func (h *HUOBI) SetDefaults() { - h.Name = "Huobi" - h.Enabled = true - h.Verbose = true - h.API.CredentialsValidator.RequiresKey = true - h.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Huobi" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true for _, a := range []asset.Item{asset.Spot, asset.CoinMarginedFutures, asset.Futures} { ps := currency.PairStore{ @@ -53,18 +53,18 @@ func (h *HUOBI) SetDefaults() { case asset.CoinMarginedFutures: ps.RequestFormat.Delimiter = currency.DashDelimiter } - if err := h.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", h.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } for _, a := range []asset.Item{asset.Futures, asset.CoinMarginedFutures} { - if err := h.DisableAssetWebsocketSupport(a); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", h.Name, a, err) + if err := e.DisableAssetWebsocketSupport(a); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, a, err) } } - h.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -150,14 +150,14 @@ func (h *HUOBI) SetDefaults() { } var err error - h.Requester, err = request.New(h.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - h.API.Endpoints = h.NewEndpoints() - err = h.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: huobiAPIURL, exchange.RestFutures: huobiFuturesURL, exchange.RestCoinMargined: huobiFuturesURL, @@ -166,58 +166,58 @@ func (h *HUOBI) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - h.Websocket = websocket.NewManager() - h.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - h.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - h.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Bootstrap ensures that future contract expiry codes are loaded if AutoPairUpdates is not enabled -func (h *HUOBI) Bootstrap(ctx context.Context) (continueBootstrap bool, err error) { +func (e *Exchange) Bootstrap(ctx context.Context) (continueBootstrap bool, err error) { continueBootstrap = true - if !h.GetEnabledFeatures().AutoPairUpdates && h.SupportsAsset(asset.Futures) { - _, err = h.FetchTradablePairs(ctx, asset.Futures) + if !e.GetEnabledFeatures().AutoPairUpdates && e.SupportsAsset(asset.Futures) { + _, err = e.FetchTradablePairs(ctx, asset.Futures) } return } // Setup sets user configuration -func (h *HUOBI) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - h.SetEnabled(false) + e.SetEnabled(false) return nil } - err = h.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := h.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = h.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: wsSpotURL + wsPublicPath, RunningURL: wsRunningURL, - Connector: h.WsConnect, - Subscriber: h.Subscribe, - Unsubscriber: h.Unsubscribe, - GenerateSubscriptions: h.generateSubscriptions, - Features: &h.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, }) if err != nil { return err } - err = h.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ RateLimit: request.NewWeightedRateLimitByDuration(20 * time.Millisecond), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -226,7 +226,7 @@ func (h *HUOBI) Setup(exch *config.Exchange) error { return err } - return h.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ RateLimit: request.NewWeightedRateLimitByDuration(20 * time.Millisecond), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -236,15 +236,15 @@ func (h *HUOBI) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (h *HUOBI) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { - if !h.SupportsAsset(a) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } var pairs []currency.Pair switch a { case asset.Spot: - symbols, err := h.GetSymbols(ctx) + symbols, err := e.GetSymbols(ctx) if err != nil { return nil, err } @@ -263,7 +263,7 @@ func (h *HUOBI) FetchTradablePairs(ctx context.Context, a asset.Item) (currency. pairs = append(pairs, pair) } case asset.CoinMarginedFutures: - symbols, err := h.GetSwapMarkets(ctx, currency.EMPTYPAIR) + symbols, err := e.GetSwapMarkets(ctx, currency.EMPTYPAIR) if err != nil { return nil, err } @@ -280,7 +280,7 @@ func (h *HUOBI) FetchTradablePairs(ctx context.Context, a asset.Item) (currency. pairs = append(pairs, pair) } case asset.Futures: - symbols, err := h.FGetContractInfo(ctx, "", "", currency.EMPTYPAIR) + symbols, err := e.FGetContractInfo(ctx, "", "", currency.EMPTYPAIR) if err != nil { return nil, err } @@ -307,42 +307,42 @@ func (h *HUOBI) FetchTradablePairs(ctx context.Context, a asset.Item) (currency. // We cache contract expiries on the exchange locally right now because there's no exchange base holder for them // It's not as dangerous as it seems, because when contracts change, so would tradeable pairs, // so by caching them in FetchTradablePairs we're not adding any extra-layer of out-of-date data - h.futureContractCodesMutex.Lock() - h.futureContractCodes = expiryCodeDates - h.futureContractCodesMutex.Unlock() + e.futureContractCodesMutex.Lock() + e.futureContractCodes = expiryCodeDates + e.futureContractCodesMutex.Unlock() } return pairs, nil } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (h *HUOBI) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := h.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.GetAssetTypes(false) for x := range assets { - pairs, err := h.FetchTradablePairs(ctx, assets[x]) + pairs, err := e.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } - err = h.UpdatePairs(pairs, assets[x], false, forceUpdate) + err = e.UpdatePairs(pairs, assets[x], false, forceUpdate) if err != nil { return err } } - return h.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { var errs error switch a { case asset.Spot: - ticks, err := h.GetTickers(ctx) + ticks, err := e.GetTickers(ctx) if err != nil { return err } for i := range ticks.Data { var cp currency.Pair - cp, _, err = h.MatchSymbolCheckEnabled(ticks.Data[i].Symbol, a, false) + cp, _, err = e.MatchSymbolCheckEnabled(ticks.Data[i].Symbol, a, false) if err != nil { if !errors.Is(err, currency.ErrPairNotFound) { errs = common.AppendError(errs, err) @@ -361,7 +361,7 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { BidSize: ticks.Data[i].BidSize, AskSize: ticks.Data[i].AskSize, Pair: cp, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, LastUpdated: time.Now(), }) @@ -370,13 +370,13 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { } } case asset.CoinMarginedFutures: - ticks, err := h.GetBatchCoinMarginSwapContracts(ctx) + ticks, err := e.GetBatchCoinMarginSwapContracts(ctx) if err != nil { return err } for i := range ticks { var cp currency.Pair - cp, _, err = h.MatchSymbolCheckEnabled(ticks[i].ContractCode, a, true) + cp, _, err = e.MatchSymbolCheckEnabled(ticks[i].ContractCode, a, true) if err != nil { if !errors.Is(err, currency.ErrPairNotFound) { errs = common.AppendError(errs, err) @@ -396,7 +396,7 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { Ask: ticks[i].Ask[0], AskSize: ticks[i].Ask[1], Pair: cp, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, LastUpdated: tt, }) @@ -407,12 +407,12 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { case asset.Futures: ticks := []FuturesBatchTicker{} // TODO: Linear swap contracts are coin-m assets - if coinMTicks, err := h.GetBatchLinearSwapContracts(ctx); err != nil { + if coinMTicks, err := e.GetBatchLinearSwapContracts(ctx); err != nil { errs = common.AppendError(errs, err) } else { ticks = append(ticks, coinMTicks...) } - if futureTicks, err := h.GetBatchFuturesContracts(ctx); err != nil { + if futureTicks, err := e.GetBatchFuturesContracts(ctx); err != nil { errs = common.AppendError(errs, err) } else { ticks = append(ticks, futureTicks...) @@ -423,13 +423,13 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { if ticks[i].Symbol != "" { cp, err = currency.NewPairFromString(ticks[i].Symbol) if err == nil { - cp, err = h.pairFromContractExpiryCode(cp) + cp, err = e.pairFromContractExpiryCode(cp) } if err == nil { - cp, _, err = h.MatchSymbolCheckEnabled(cp.String(), a, true) + cp, _, err = e.MatchSymbolCheckEnabled(cp.String(), a, true) } } else { - cp, _, err = h.MatchSymbolCheckEnabled(ticks[i].ContractCode, a, true) + cp, _, err = e.MatchSymbolCheckEnabled(ticks[i].ContractCode, a, true) } if err != nil { if !errors.Is(err, currency.ErrPairNotFound) { @@ -449,7 +449,7 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { Ask: ticks[i].Ask[0], AskSize: ticks[i].Ask[1], Pair: cp, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, LastUpdated: ticks[i].Timestamp.Time(), }) @@ -464,16 +464,16 @@ func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if !h.SupportsAsset(a) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } switch a { case asset.Spot: - tickerData, err := h.Get24HrMarketSummary(ctx, p) + tickerData, err := e.Get24HrMarketSummary(ctx, p) if err != nil { return nil, err } @@ -485,14 +485,14 @@ func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) Open: tickerData.Tick.Open, Close: tickerData.Tick.Close, Pair: p, - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: asset.Spot, }) if err != nil { return nil, err } case asset.CoinMarginedFutures: - marketData, err := h.GetSwapMarketOverview(ctx, p) + marketData, err := e.GetSwapMarketOverview(ctx, p) if err != nil { return nil, err } @@ -514,14 +514,14 @@ func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) Pair: p, Bid: marketData.Tick.Bid[0], Ask: marketData.Tick.Ask[0], - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } case asset.Futures: - marketData, err := h.FGetMarketOverviewData(ctx, p) + marketData, err := e.FGetMarketOverviewData(ctx, p) if err != nil { return nil, err } @@ -536,18 +536,18 @@ func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) Pair: p, Bid: marketData.Tick.Bid[0], Ask: marketData.Tick.Ask[0], - ExchangeName: h.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { return nil, err } } - return ticker.GetTicker(h.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -555,16 +555,16 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } book := &orderbook.Book{ - Exchange: h.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: h.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } var err error switch assetType { case asset.Spot: var orderbookNew *Orderbook - orderbookNew, err = h.GetDepth(ctx, + orderbookNew, err = e.GetDepth(ctx, &OrderBookDataRequestParams{ Symbol: p, Type: OrderBookDataRequestParamsTypeStep0, @@ -590,7 +590,7 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType case asset.Futures: var orderbookNew *OBData - orderbookNew, err = h.FGetMarketDepth(ctx, p, "step0") + orderbookNew, err = e.FGetMarketDepth(ctx, p, "step0") if err != nil { return book, err } @@ -612,7 +612,7 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType case asset.CoinMarginedFutures: var orderbookNew SwapMarketDepthData - orderbookNew, err = h.GetSwapMarketDepth(ctx, p, "step0") + orderbookNew, err = e.GetSwapMarketDepth(ctx, p, "step0") if err != nil { return book, err } @@ -637,12 +637,12 @@ func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(h.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // GetAccountID returns the account ID for trades -func (h *HUOBI) GetAccountID(ctx context.Context) ([]Account, error) { - acc, err := h.GetAccounts(ctx) +func (e *Exchange) GetAccountID(ctx context.Context) ([]Account, error) { + acc, err := e.GetAccounts(ctx) if err != nil { return nil, err } @@ -656,13 +656,13 @@ func (h *HUOBI) GetAccountID(ctx context.Context) ([]Account, error) { // UpdateAccountInfo retrieves balances for all enabled currencies for the // HUOBI exchange - to-do -func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount - info.Exchange = h.Name + info.Exchange = e.Name switch assetType { case asset.Spot: - accounts, err := h.GetAccountID(ctx) + accounts, err := e.GetAccountID(ctx) if err != nil { return info, err } @@ -671,7 +671,7 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac continue } acc.ID = strconv.FormatInt(accounts[i].ID, 10) - balances, err := h.GetAccountBalance(ctx, acc.ID) + balances, err := e.GetAccountBalance(ctx, acc.ID) if err != nil { return info, err } @@ -710,7 +710,7 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac case asset.CoinMarginedFutures: // fetch swap account info - acctInfo, err := h.GetSwapAccountInfo(ctx, currency.EMPTYPAIR) + acctInfo, err := e.GetSwapAccountInfo(ctx, currency.EMPTYPAIR) if err != nil { return info, err } @@ -731,13 +731,13 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac }) // fetch subaccounts data - subAccsData, err := h.GetSwapAllSubAccAssets(ctx, currency.EMPTYPAIR) + subAccsData, err := e.GetSwapAllSubAccAssets(ctx, currency.EMPTYPAIR) if err != nil { return info, err } var currencyDetails []account.Balance for x := range subAccsData.Data { - a, err := h.SwapSingleSubAccAssets(ctx, + a, err := e.SwapSingleSubAccAssets(ctx, currency.EMPTYPAIR, subAccsData.Data[x].SubUID) if err != nil { @@ -755,7 +755,7 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac acc.Currencies = currencyDetails case asset.Futures: // fetch main account data - mainAcctData, err := h.FGetAccountInfo(ctx, currency.EMPTYCODE) + mainAcctData, err := e.FGetAccountInfo(ctx, currency.EMPTYCODE) if err != nil { return info, err } @@ -776,13 +776,13 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac }) // fetch subaccounts data - subAccsData, err := h.FGetAllSubAccountAssets(ctx, currency.EMPTYCODE) + subAccsData, err := e.FGetAllSubAccountAssets(ctx, currency.EMPTYCODE) if err != nil { return info, err } var currencyDetails []account.Balance for x := range subAccsData.Data { - a, err := h.FGetSingleSubAccountInfo(ctx, + a, err := e.FGetSingleSubAccountInfo(ctx, "", strconv.FormatInt(subAccsData.Data[x].SubUID, 10)) if err != nil { @@ -801,7 +801,7 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac } acc.AssetType = assetType info.Accounts = append(info.Accounts, acc) - creds, err := h.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -813,16 +813,16 @@ func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (h *HUOBI) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (h *HUOBI) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { if a != asset.Spot { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } - withdrawals, err := h.SearchForExistedWithdrawsAndDeposits(ctx, c, "withdraw", "", 0, 500) + withdrawals, err := e.SearchForExistedWithdrawsAndDeposits(ctx, c, "withdraw", "", 0, 500) if err != nil { return nil, err } @@ -845,9 +845,9 @@ func (h *HUOBI) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a as } // GetRecentTrades returns the most recent trades for a currency and asset -func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { var resp []trade.Data - pFmt, err := h.GetPairFormat(a, true) + pFmt, err := e.GetPairFormat(a, true) if err != nil { return nil, err } @@ -856,7 +856,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It switch a { case asset.Spot: var sTrades []TradeHistory - sTrades, err = h.GetTradeHistory(ctx, p, 2000) + sTrades, err = e.GetTradeHistory(ctx, p, 2000) if err != nil { return nil, err } @@ -868,7 +868,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It return nil, err } resp = append(resp, trade.Data{ - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatFloat(sTrades[i].Trades[j].TradeID, 'f', -1, 64), CurrencyPair: p, AssetType: a, @@ -881,7 +881,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } case asset.Futures: var fTrades FBatchTradesForContractData - fTrades, err = h.FRequestPublicBatchTrades(ctx, p, 2000) + fTrades, err = e.FRequestPublicBatchTrades(ctx, p, 2000) if err != nil { return nil, err } @@ -895,7 +895,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } } resp = append(resp, trade.Data{ - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatInt(fTrades.Data[i].Data[j].ID, 10), CurrencyPair: p, AssetType: a, @@ -908,7 +908,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } case asset.CoinMarginedFutures: var cTrades BatchTradesData - cTrades, err = h.GetBatchTrades(ctx, p, 2000) + cTrades, err = e.GetBatchTrades(ctx, p, 2000) if err != nil { return nil, err } @@ -921,7 +921,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } } resp = append(resp, trade.Data{ - Exchange: h.Name, + Exchange: e.Name, TID: strconv.FormatInt(cTrades.Data[i].ID, 10), CurrencyPair: p, AssetType: a, @@ -933,7 +933,7 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } } - err = h.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -943,13 +943,13 @@ func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.It } // GetHistoricTrades returns historic trade data within the timeframe provided -func (h *HUOBI) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(h.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -981,7 +981,7 @@ func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit params.Price = s.Price } params.Type = formattedType - response, err := h.SpotNewOrder(ctx, ¶ms) + response, err := e.SpotNewOrder(ctx, ¶ms) if err != nil { return nil, err } @@ -1028,7 +1028,7 @@ func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit if s.ReduceOnly { offset = "close" } - orderResp, err := h.PlaceSwapOrders(ctx, + orderResp, err := e.PlaceSwapOrders(ctx, s.Pair, s.ClientOrderID, oDirection, @@ -1079,7 +1079,7 @@ func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit if s.ReduceOnly { offset = "close" } - o, err := h.FOrder(ctx, + o, err := e.FOrder(ctx, s.Pair, "", "", @@ -1105,12 +1105,12 @@ func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HUOBI) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (h *HUOBI) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -1122,11 +1122,11 @@ func (h *HUOBI) CancelOrder(ctx context.Context, o *order.Cancel) error { if err != nil { return err } - _, err = h.CancelExistingOrder(ctx, orderIDInt) + _, err = e.CancelExistingOrder(ctx, orderIDInt) case asset.CoinMarginedFutures: - _, err = h.CancelSwapOrder(ctx, o.OrderID, o.ClientID, o.Pair) + _, err = e.CancelSwapOrder(ctx, o.OrderID, o.ClientID, o.Pair) case asset.Futures: - _, err = h.FCancelOrder(ctx, o.Pair.Base, o.ClientID, o.ClientOrderID) + _, err = e.FCancelOrder(ctx, o.Pair.Base, o.ClientID, o.ClientOrderID) default: return fmt.Errorf("%w %v", asset.ErrNotSupported, o.AssetType) } @@ -1134,7 +1134,7 @@ func (h *HUOBI) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (h *HUOBI) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -1151,7 +1151,7 @@ func (h *HUOBI) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order } } - cancelledOrders, err := h.CancelOrderBatch(ctx, ids, cIDs) + cancelledOrders, err := e.CancelOrderBatch(ctx, ids, cIDs) if err != nil { return nil, err } @@ -1166,7 +1166,7 @@ func (h *HUOBI) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order } // CancelAllOrders cancels all orders associated with a currency pair -func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -1174,12 +1174,12 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca cancelAllOrdersResponse.Status = make(map[string]string) switch orderCancellation.AssetType { case asset.Spot: - enabledPairs, err := h.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return cancelAllOrdersResponse, err } for i := range enabledPairs { - resp, err := h.CancelOpenOrdersBatch(ctx, + resp, err := e.CancelOpenOrdersBatch(ctx, orderCancellation.AccountID, enabledPairs[i]) if err != nil { @@ -1196,12 +1196,12 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca } case asset.CoinMarginedFutures: if orderCancellation.Pair.IsEmpty() { - enabledPairs, err := h.GetEnabledPairs(asset.CoinMarginedFutures) + enabledPairs, err := e.GetEnabledPairs(asset.CoinMarginedFutures) if err != nil { return cancelAllOrdersResponse, err } for i := range enabledPairs { - a, err := h.CancelAllSwapOrders(ctx, enabledPairs[i]) + a, err := e.CancelAllSwapOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } @@ -1214,7 +1214,7 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca } } } else { - a, err := h.CancelAllSwapOrders(ctx, orderCancellation.Pair) + a, err := e.CancelAllSwapOrders(ctx, orderCancellation.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -1228,12 +1228,12 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca } case asset.Futures: if orderCancellation.Pair.IsEmpty() { - enabledPairs, err := h.GetEnabledPairs(asset.Futures) + enabledPairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return cancelAllOrdersResponse, err } for i := range enabledPairs { - a, err := h.FCancelAllOrders(ctx, enabledPairs[i], "", "") + a, err := e.FCancelAllOrders(ctx, enabledPairs[i], "", "") if err != nil { return cancelAllOrdersResponse, err } @@ -1246,7 +1246,7 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca } } } else { - a, err := h.FCancelAllOrders(ctx, orderCancellation.Pair, "", "") + a, err := e.FCancelAllOrders(ctx, orderCancellation.Pair, "", "") if err != nil { return cancelAllOrdersResponse, err } @@ -1263,11 +1263,11 @@ func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Ca } // GetOrderInfo returns order information based on order ID -func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := h.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } @@ -1278,25 +1278,25 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. if err != nil { return nil, err } - resp, err := h.GetOrder(ctx, oID) + resp, err := e.GetOrder(ctx, oID) if err != nil { return nil, err } respData := &resp if respData.ID == 0 { - return nil, fmt.Errorf("%s - order not found for orderid %s", h.Name, orderID) + return nil, fmt.Errorf("%s - order not found for orderid %s", e.Name, orderID) } responseID := strconv.FormatInt(respData.ID, 10) if responseID != orderID { - return nil, errors.New(h.Name + " - GetOrderInfo orderID mismatch. Expected: " + + return nil, errors.New(e.Name + " - GetOrderInfo orderID mismatch. Expected: " + orderID + " Received: " + responseID) } typeDetails := strings.Split(respData.Type, "-") orderSide, err := order.StringToOrderSide(typeDetails[0]) if err != nil { - if h.Websocket.IsConnected() { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + if e.Websocket.IsConnected() { + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -1306,9 +1306,9 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. } orderType, err := order.StringToOrderType(typeDetails[1]) if err != nil { - if h.Websocket.IsConnected() { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + if e.Websocket.IsConnected() { + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -1318,9 +1318,9 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. } orderStatus, err := order.StringToOrderStatus(respData.State) if err != nil { - if h.Websocket.IsConnected() { - h.Websocket.DataHandler <- order.ClassificationError{ - Exchange: h.Name, + if e.Websocket.IsConnected() { + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: orderID, Err: err, } @@ -1330,12 +1330,12 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. } var p currency.Pair var a asset.Item - p, a, err = h.GetRequestFormattedPairAndAssetType(respData.Symbol) + p, a, err = e.GetRequestFormattedPairAndAssetType(respData.Symbol) if err != nil { return nil, err } orderDetail = order.Detail{ - Exchange: h.Name, + Exchange: e.Name, OrderID: orderID, AccountID: strconv.FormatInt(respData.AccountID, 10), Pair: p, @@ -1350,7 +1350,7 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. AssetType: a, } case asset.CoinMarginedFutures: - orderInfo, err := h.GetSwapOrderInfo(ctx, pair, orderID, "") + orderInfo, err := e.GetSwapOrderInfo(ctx, pair, orderID, "") if err != nil { return nil, err } @@ -1368,7 +1368,7 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. Price: orderInfo.Data[x].Price, Amount: orderInfo.Data[x].Volume, Fee: orderInfo.Data[x].Fee, - Exchange: h.Name, + Exchange: e.Name, TID: orderInfo.Data[x].OrderIDString, Type: orderVars.OrderType, Side: orderVars.Side, @@ -1376,11 +1376,11 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. }) } case asset.Futures: - fPair, err := h.FormatSymbol(pair, asset.Futures) + fPair, err := e.FormatSymbol(pair, asset.Futures) if err != nil { return nil, err } - orderInfo, err := h.FGetOrderInfo(ctx, fPair, orderID, "") + orderInfo, err := e.FGetOrderInfo(ctx, fPair, orderID, "") if err != nil { return nil, err } @@ -1395,7 +1395,7 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. Price: orderInfo.Data[x].Price, Amount: orderInfo.Data[x].Volume, Fee: orderInfo.Data[x].Fee, - Exchange: h.Name, + Exchange: e.Name, TID: orderInfo.Data[x].OrderIDString, Type: orderVars.OrderType, Side: orderVars.Side, @@ -1409,8 +1409,8 @@ func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency. } // GetDepositAddress returns a deposit address for a specified currency -func (h *HUOBI) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { - resp, err := h.QueryDepositAddress(ctx, cryptocurrency) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { + resp, err := e.QueryDepositAddress(ctx, cryptocurrency) if err != nil { return nil, err } @@ -1433,11 +1433,11 @@ func (h *HUOBI) GetDepositAddress(ctx context.Context, cryptocurrency currency.C // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (h *HUOBI) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := h.Withdraw(ctx, + resp, err := e.Withdraw(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, @@ -1454,30 +1454,30 @@ func (h *HUOBI) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (h *HUOBI) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (h *HUOBI) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (h *HUOBI) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !h.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return h.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1492,12 +1492,12 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques if req.Side == order.Sell { side = req.Side.Lower() } - creds, err := h.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return nil, err } for i := range req.Pairs { - resp, err := h.GetOpenOrders(ctx, + resp, err := e.GetOpenOrders(ctx, req.Pairs[i], creds.ClientID, side, @@ -1513,7 +1513,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques ExecutedAmount: resp[x].FilledAmount, RemainingAmount: resp[x].Amount - resp[x].FilledAmount, Pair: req.Pairs[i], - Exchange: h.Name, + Exchange: e.Name, Date: resp[x].CreatedAt.Time(), AccountID: strconv.FormatInt(resp[x].AccountID, 10), Fee: resp[x].FilledFees, @@ -1526,7 +1526,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques for x := range req.Pairs { var currentPage int64 for done := false; !done; { - openOrders, err := h.GetSwapOpenOrders(ctx, + openOrders, err := e.GetSwapOpenOrders(ctx, req.Pairs[x], currentPage, 50) if err != nil { return orders, err @@ -1551,7 +1551,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques ExecutedAmount: openOrders.Data.Orders[x].TradeVolume, RemainingAmount: openOrders.Data.Orders[x].Volume - openOrders.Data.Orders[x].TradeVolume, Fee: openOrders.Data.Orders[x].Fee, - Exchange: h.Name, + Exchange: e.Name, AssetType: req.AssetType, OrderID: openOrders.Data.Orders[x].OrderIDString, Side: orderVars.Side, @@ -1568,7 +1568,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques for x := range req.Pairs { var currentPage int64 for done := false; !done; { - openOrders, err := h.FGetOpenOrders(ctx, + openOrders, err := e.FGetOpenOrders(ctx, req.Pairs[x].Base, currentPage, 50) if err != nil { return orders, err @@ -1593,7 +1593,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques ExecutedAmount: openOrders.Data.Orders[x].TradeVolume, RemainingAmount: openOrders.Data.Orders[x].Volume - openOrders.Data.Orders[x].TradeVolume, Fee: openOrders.Data.Orders[x].Fee, - Exchange: h.Name, + Exchange: e.Name, AssetType: req.AssetType, OrderID: openOrders.Data.Orders[x].OrderIDString, Side: orderVars.Side, @@ -1607,12 +1607,12 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques } } } - return req.Filter(h.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1625,7 +1625,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques } states := "partial-canceled,filled,canceled" for i := range req.Pairs { - resp, err := h.GetOrders(ctx, + resp, err := e.GetOrders(ctx, req.Pairs[i], "", "", @@ -1647,7 +1647,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques Cost: resp[x].FilledCashAmount, CostAsset: req.Pairs[i].Quote, Pair: req.Pairs[i], - Exchange: h.Name, + Exchange: e.Name, Date: resp[x].CreatedAt.Time(), CloseTime: resp[x].FinishedAt.Time(), AccountID: strconv.FormatInt(resp[x].AccountID, 10), @@ -1662,7 +1662,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques for x := range req.Pairs { var currentPage int64 for done := false; !done; { - orderHistory, err := h.GetSwapOrderHistory(ctx, + orderHistory, err := e.GetSwapOrderHistory(ctx, req.Pairs[x], "all", "all", @@ -1694,7 +1694,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques ExecutedAmount: orderHistory.Data.Orders[x].TradeVolume, RemainingAmount: orderHistory.Data.Orders[x].Volume - orderHistory.Data.Orders[x].TradeVolume, Fee: orderHistory.Data.Orders[x].Fee, - Exchange: h.Name, + Exchange: e.Name, AssetType: req.AssetType, OrderID: orderHistory.Data.Orders[x].OrderIDString, Side: orderVars.Side, @@ -1711,7 +1711,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques for x := range req.Pairs { var currentPage int64 for done := false; !done; { - openOrders, err := h.FGetOrderHistory(ctx, + openOrders, err := e.FGetOrderHistory(ctx, req.Pairs[x], "", "all", @@ -1750,7 +1750,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques ExecutedAmount: openOrders.Data.Orders[x].TradeVolume, RemainingAmount: openOrders.Data.Orders[x].Volume - openOrders.Data.Orders[x].TradeVolume, Fee: openOrders.Data.Orders[x].Fee, - Exchange: h.Name, + Exchange: e.Name, AssetType: req.AssetType, OrderID: openOrders.Data.Orders[x].OrderIDString, Side: orderVars.Side, @@ -1765,7 +1765,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques } } } - return req.Filter(h.Name, orders), nil + return req.Filter(e.Name, orders), nil } func setOrderSideStatusAndType(orderState, requestType string, orderDetail *order.Detail) { @@ -1791,19 +1791,19 @@ func setOrderSideStatusAndType(orderState, requestType string, orderDetail *orde } // AuthenticateWebsocket sends an authentication message to the websocket -func (h *HUOBI) AuthenticateWebsocket(ctx context.Context) error { - return h.wsLogin(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + return e.wsLogin(ctx) } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (h *HUOBI) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := h.UpdateAccountInfo(ctx, assetType) - return h.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (h *HUOBI) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { switch in { case kline.OneMin, kline.FiveMin, kline.FifteenMin, kline.ThirtyMin: return in.Short() + "in" @@ -1824,8 +1824,8 @@ func (h *HUOBI) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := h.GetKlineRequest(pair, a, interval, start, end, true) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, true) if err != nil { return nil, err } @@ -1833,8 +1833,8 @@ func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a as timeSeries := make([]kline.Candle, 0, req.Size()) switch a { case asset.Spot: - candles, err := h.GetSpotKline(ctx, KlinesRequestParams{ - Period: h.FormatExchangeKlineInterval(req.ExchangeInterval), + candles, err := e.GetSpotKline(ctx, KlinesRequestParams{ + Period: e.FormatExchangeKlineInterval(req.ExchangeInterval), Symbol: req.Pair, Size: req.RequestLimit, }) @@ -1859,7 +1859,7 @@ func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a as case asset.Futures: // if size, from, to are all populated, only size is considered size := int64(-1) - candles, err := h.FGetKlineData(ctx, req.Pair, h.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.Start, req.End) + candles, err := e.FGetKlineData(ctx, req.Pair, e.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.Start, req.End) if err != nil { return nil, err } @@ -1880,7 +1880,7 @@ func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a as case asset.CoinMarginedFutures: // if size, from, to are all populated, only size is considered size := int64(-1) - candles, err := h.GetSwapKlineData(ctx, req.Pair, h.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.Start, req.End) + candles, err := e.GetSwapKlineData(ctx, req.Pair, e.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.Start, req.End) if err != nil { return nil, err } @@ -1904,8 +1904,8 @@ func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a as } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (h *HUOBI) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := h.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1919,7 +1919,7 @@ func (h *HUOBI) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pa // if size, from, to are all populated, only size is considered size := int64(-1) var candles FKlineData - candles, err = h.FGetKlineData(ctx, req.Pair, h.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time) + candles, err = e.FGetKlineData(ctx, req.Pair, e.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time) if err != nil { return nil, err } @@ -1944,7 +1944,7 @@ func (h *HUOBI) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pa // if size, from, to are all populated, only size is considered size := int64(-1) var candles SwapKlineData - candles, err = h.GetSwapKlineData(ctx, req.Pair, h.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time) + candles, err = e.GetSwapKlineData(ctx, req.Pair, e.FormatExchangeKlineInterval(req.ExchangeInterval), size, req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time) if err != nil { return nil, err } @@ -2011,8 +2011,8 @@ func compatibleVars(side, orderPriceType string, status int64) (OrderVars, error } // GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency -func (h *HUOBI) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - resp, err := h.GetCurrenciesIncludingChains(ctx, cryptocurrency) +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + resp, err := e.GetCurrenciesIncludingChains(ctx, cryptocurrency) if err != nil { return nil, err } @@ -2033,22 +2033,22 @@ func (h *HUOBI) GetAvailableTransferChains(ctx context.Context, cryptocurrency c } // GetServerTime returns the current exchange server time. -func (h *HUOBI) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - return h.GetCurrentServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + return e.GetCurrentServerTime(ctx) } // GetFuturesContractDetails returns details about futures contracts -func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !h.SupportsAsset(item) { + if !e.SupportsAsset(item) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } switch item { case asset.CoinMarginedFutures: - result, err := h.GetSwapMarkets(ctx, currency.EMPTYPAIR) + result, err := e.GetSwapMarkets(ctx, currency.EMPTYPAIR) if err != nil { return nil, err } @@ -2071,7 +2071,7 @@ func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) } resp = append(resp, futures.Contract{ - Exchange: h.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, Asset: item, @@ -2085,7 +2085,7 @@ func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) } return resp, nil case asset.Futures: - result, err := h.FGetContractInfo(ctx, "", "", currency.EMPTYPAIR) + result, err := e.FGetContractInfo(ctx, "", "", currency.EMPTYPAIR) if err != nil { return nil, err } @@ -2101,17 +2101,17 @@ func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) if err != nil { return nil, err } - var s, e time.Time - s, err = time.Parse("20060102", result.Data[x].CreateDate) + var startTime, endTime time.Time + startTime, err = time.Parse("20060102", result.Data[x].CreateDate) if err != nil { return nil, err } if result.Data[x].DeliveryTime.Time().IsZero() { - e = result.Data[x].DeliveryTime.Time() + endTime = result.Data[x].DeliveryTime.Time() } else { - e = result.Data[x].SettlementTime.Time() + endTime = result.Data[x].SettlementTime.Time() } - contractLength := e.Sub(s) + contractLength := endTime.Sub(startTime) var ct futures.ContractType switch { case contractLength <= kline.OneWeek.Duration()+kline.ThreeDay.Duration(): @@ -2127,12 +2127,12 @@ func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) } resp = append(resp, futures.Contract{ - Exchange: h.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, Asset: item, - StartDate: s, - EndDate: e, + StartDate: startTime, + EndDate: endTime, SettlementType: futures.Linear, IsActive: result.Data[x].ContractStatus == 1, Type: ct, @@ -2146,7 +2146,7 @@ func (h *HUOBI) GetFuturesContractDetails(ctx context.Context, item asset.Item) } // GetLatestFundingRates returns the latest funding rates data -func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -2156,13 +2156,13 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest var rates []FundingRatesData if r.Pair.IsEmpty() { - batchRates, err := h.GetSwapFundingRates(ctx) + batchRates, err := e.GetSwapFundingRates(ctx) if err != nil { return nil, err } rates = batchRates.Data } else { - rateResp, err := h.GetSwapFundingRate(ctx, r.Pair) + rateResp, err := e.GetSwapFundingRate(ctx, r.Pair) if err != nil { return nil, err } @@ -2174,7 +2174,7 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest // formatting to match documentation rates[i].ContractCode = rates[i].Symbol + "-USD" } - cp, isEnabled, err := h.MatchSymbolCheckEnabled(rates[i].ContractCode, r.Asset, true) + cp, isEnabled, err := e.MatchSymbolCheckEnabled(rates[i].ContractCode, r.Asset, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2182,7 +2182,7 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest continue } var isPerp bool - isPerp, err = h.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -2191,9 +2191,9 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest } ft, nft := rates[i].FundingTime.Time(), rates[i].NextFundingTime.Time() var fri time.Duration - if len(h.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { + if len(e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined - for k := range h.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { + for k := range e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { fri = k.Duration() } } @@ -2205,7 +2205,7 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest nft = nft.Add(-fri) } rate := fundingrate.LatestRateResponse{ - Exchange: h.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -2227,17 +2227,17 @@ func (h *HUOBI) GetLatestFundingRates(ctx context.Context, r *fundingrate.Latest } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (h *HUOBI) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { return a == asset.CoinMarginedFutures, nil } // UpdateOrderExecutionLimits updates order execution limits -func (h *HUOBI) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetOpenInterest returns the open interest rate for a given asset pair -func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { if k[i].Asset != asset.Futures && k[i].Asset != asset.CoinMarginedFutures { // avoid API calls or returning errors after a successful retrieval @@ -2251,9 +2251,9 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu // Huobi does not like requests being made with contract expiry in them (eg BTC240109) return nil, fmt.Errorf("%w %v, must use shorthand such as CW (current week)", currency.ErrCurrencyNotSupported, k[0].Pair()) } - data, err := h.FContractOpenInterest(ctx, "", "", k[0].Pair()) + data, err := e.FContractOpenInterest(ctx, "", "", k[0].Pair()) if err != nil { - data2, err2 := h.ContractOpenInterestUSDT(ctx, k[0].Pair(), currency.EMPTYPAIR, "", "") + data2, err2 := e.ContractOpenInterestUSDT(ctx, k[0].Pair(), currency.EMPTYPAIR, "", "") if err2 != nil { return nil, fmt.Errorf("%w %w", err, err2) } @@ -2262,7 +2262,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu for i := range data.Data { var p currency.Pair - p, err = h.MatchSymbolWithAvailablePairs(data.Data[i].ContractCode, k[0].Asset, true) + p, err = e.MatchSymbolWithAvailablePairs(data.Data[i].ContractCode, k[0].Asset, true) if err != nil { if errors.Is(err, currency.ErrPairNotFound) { continue @@ -2272,7 +2272,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu return []futures.OpenInterest{ { Key: key.ExchangePairAsset{ - Exchange: h.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: k[0].Asset, @@ -2282,13 +2282,13 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu }, nil } case asset.CoinMarginedFutures: - data, err := h.SwapOpenInterestInformation(ctx, k[0].Pair()) + data, err := e.SwapOpenInterestInformation(ctx, k[0].Pair()) if err != nil { return nil, err } for i := range data.Data { var p currency.Pair - p, err = h.MatchSymbolWithAvailablePairs(data.Data[i].ContractCode, k[0].Asset, true) + p, err = e.MatchSymbolWithAvailablePairs(data.Data[i].ContractCode, k[0].Asset, true) if err != nil { if errors.Is(err, currency.ErrPairNotFound) { continue @@ -2298,7 +2298,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu return []futures.OpenInterest{ { Key: key.ExchangePairAsset{ - Exchange: h.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: k[0].Asset, @@ -2310,14 +2310,14 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu } } var resp []futures.OpenInterest - for _, a := range h.GetAssetTypes(true) { + for _, a := range e.GetAssetTypes(true) { switch a { case asset.Futures: - data, err := h.FContractOpenInterest(ctx, "", "", currency.EMPTYPAIR) + data, err := e.FContractOpenInterest(ctx, "", "", currency.EMPTYPAIR) if err != nil { return nil, err } - uData, err := h.ContractOpenInterestUSDT(ctx, currency.EMPTYPAIR, currency.EMPTYPAIR, "", "") + uData, err := e.ContractOpenInterestUSDT(ctx, currency.EMPTYPAIR, currency.EMPTYPAIR, "", "") if err != nil { return nil, err } @@ -2327,7 +2327,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu for i := range allData { var p currency.Pair var isEnabled, appendData bool - p, isEnabled, err = h.MatchSymbolCheckEnabled(allData[i].ContractCode, a, true) + p, isEnabled, err = e.MatchSymbolCheckEnabled(allData[i].ContractCode, a, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2345,7 +2345,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: h.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, @@ -2354,12 +2354,12 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu }) } case asset.CoinMarginedFutures: - data, err := h.SwapOpenInterestInformation(ctx, currency.EMPTYPAIR) + data, err := e.SwapOpenInterestInformation(ctx, currency.EMPTYPAIR) if err != nil { return nil, err } for i := range data.Data { - p, isEnabled, err := h.MatchSymbolCheckEnabled(data.Data[i].ContractCode, a, true) + p, isEnabled, err := e.MatchSymbolCheckEnabled(data.Data[i].ContractCode, a, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2378,7 +2378,7 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: h.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: a, @@ -2392,8 +2392,8 @@ func (h *HUOBI) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futu } // GetCurrencyTradeURL returns the UR˜L to the exchange's trade page for the given asset and currency pair -func (h *HUOBI) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := h.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 9c94c1384ce..701fa10727a 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -37,19 +37,19 @@ const ( krakenFuturesVersion = "3" ) -// Kraken is the overarching type across the kraken package -type Kraken struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Kraken +type Exchange struct { exchange.Base wsAuthToken string wsAuthMtx sync.RWMutex } // GetCurrentServerTime returns current server time -func (k *Kraken) GetCurrentServerTime(ctx context.Context) (*TimeResponse, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (*TimeResponse, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenServerTime) var result TimeResponse - if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { return nil, err } @@ -58,8 +58,8 @@ func (k *Kraken) GetCurrentServerTime(ctx context.Context) (*TimeResponse, error // SeedAssets seeds Kraken's asset list and stores it in the // asset translator -func (k *Kraken) SeedAssets(ctx context.Context) error { - assets, err := k.GetAssets(ctx) +func (e *Exchange) SeedAssets(ctx context.Context) error { + assets, err := e.GetAssets(ctx) if err != nil { return err } @@ -67,7 +67,7 @@ func (k *Kraken) SeedAssets(ctx context.Context) error { assetTranslator.Seed(orig, val.Altname) } - assetPairs, err := k.GetAssetPairs(ctx, []string{}, "") + assetPairs, err := e.GetAssetPairs(ctx, []string{}, "") if err != nil { return err } @@ -78,10 +78,10 @@ func (k *Kraken) SeedAssets(ctx context.Context) error { } // GetAssets returns a full asset list -func (k *Kraken) GetAssets(ctx context.Context) (map[string]*Asset, error) { +func (e *Exchange) GetAssets(ctx context.Context) (map[string]*Asset, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenAssets) var result map[string]*Asset - if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { return nil, err } return result, nil @@ -89,7 +89,7 @@ func (k *Kraken) GetAssets(ctx context.Context) (map[string]*Asset, error) { // GetAssetPairs returns a full asset pair list // Parameter 'info' only supports 4 strings: "fees", "leverage", "margin", "info" <- (default) -func (k *Kraken) GetAssetPairs(ctx context.Context, assetPairs []string, info string) (map[string]*AssetPairs, error) { +func (e *Exchange) GetAssetPairs(ctx context.Context, assetPairs []string, info string) (map[string]*AssetPairs, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenAssetPairs) params := url.Values{} var assets string @@ -105,16 +105,16 @@ func (k *Kraken) GetAssetPairs(ctx context.Context, assetPairs []string, info st } params.Set("info", info) } - if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path+params.Encode(), &result); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path+params.Encode(), &result); err != nil { return nil, err } return result, nil } // GetTicker returns ticker information from kraken -func (k *Kraken) GetTicker(ctx context.Context, symbol currency.Pair) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol currency.Pair) (*Ticker, error) { values := url.Values{} - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -122,7 +122,7 @@ func (k *Kraken) GetTicker(ctx context.Context, symbol currency.Pair) (*Ticker, var data map[string]*TickerResponse path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenTicker, values.Encode()) - if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &data); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &data); err != nil { return nil, err } @@ -146,7 +146,7 @@ func (k *Kraken) GetTicker(ctx context.Context, symbol currency.Pair) (*Ticker, // GetTickers supports fetching multiple tickers from Kraken // pairList must be in the format pairs separated by commas // ("LTCUSD,ETCUSD") -func (k *Kraken) GetTickers(ctx context.Context, pairList string) (map[string]Ticker, error) { +func (e *Exchange) GetTickers(ctx context.Context, pairList string) (map[string]Ticker, error) { values := url.Values{} if pairList != "" { values.Set("pair", pairList) @@ -155,7 +155,7 @@ func (k *Kraken) GetTickers(ctx context.Context, pairList string) (map[string]Ti var result map[string]*TickerResponse path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenTicker, values.Encode()) - err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) if err != nil { return nil, err } @@ -180,9 +180,9 @@ func (k *Kraken) GetTickers(ctx context.Context, pairList string) (map[string]Ti } // GetOHLC returns an array of open high low close values of a currency pair -func (k *Kraken) GetOHLC(ctx context.Context, symbol currency.Pair, interval string) ([]OpenHighLowClose, error) { +func (e *Exchange) GetOHLC(ctx context.Context, symbol currency.Pair, interval string) ([]OpenHighLowClose, error) { values := url.Values{} - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (k *Kraken) GetOHLC(ctx context.Context, symbol currency.Pair, interval str path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenOHLC, values.Encode()) result := make(map[string]any) - err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) + err = e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) if err != nil { return nil, err } @@ -251,8 +251,8 @@ func (k *Kraken) GetOHLC(ctx context.Context, symbol currency.Pair, interval str } // GetDepth returns the orderbook for a particular currency -func (k *Kraken) GetDepth(ctx context.Context, symbol currency.Pair) (*Orderbook, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) GetDepth(ctx context.Context, symbol currency.Pair) (*Orderbook, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -266,7 +266,7 @@ func (k *Kraken) GetDepth(ctx context.Context, symbol currency.Pair) (*Orderbook } result := make(map[string]*orderbookStructure) - if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { + if err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result); err != nil { return nil, err } @@ -292,8 +292,8 @@ func (k *Kraken) GetDepth(ctx context.Context, symbol currency.Pair) (*Orderbook } // GetTrades returns current trades on Kraken -func (k *Kraken) GetTrades(ctx context.Context, symbol currency.Pair, since time.Time, count uint64) (*RecentTradesResponse, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) GetTrades(ctx context.Context, symbol currency.Pair, since time.Time, count uint64) (*RecentTradesResponse, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -308,12 +308,12 @@ func (k *Kraken) GetTrades(ctx context.Context, symbol currency.Pair, since time path := common.EncodeURLValues("/"+krakenAPIVersion+"/public/"+krakenTrades, values) var resp *RecentTradesResponse - return resp, k.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetSpread returns the full spread on Kraken -func (k *Kraken) GetSpread(ctx context.Context, symbol currency.Pair, since time.Time) (*SpreadResponse, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) GetSpread(ctx context.Context, symbol currency.Pair, since time.Time) (*SpreadResponse, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -324,13 +324,13 @@ func (k *Kraken) GetSpread(ctx context.Context, symbol currency.Pair, since time } var peanutButter *SpreadResponse path := common.EncodeURLValues("/"+krakenAPIVersion+"/public/"+krakenSpread, values) - return peanutButter, k.SendHTTPRequest(ctx, exchange.RestSpot, path, &peanutButter) + return peanutButter, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &peanutButter) } // GetBalance returns your balance associated with your keys -func (k *Kraken) GetBalance(ctx context.Context) (map[string]Balance, error) { +func (e *Exchange) GetBalance(ctx context.Context) (map[string]Balance, error) { var result map[string]Balance - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenBalance, url.Values{}, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenBalance, url.Values{}, &result); err != nil { return nil, err } @@ -338,14 +338,14 @@ func (k *Kraken) GetBalance(ctx context.Context) (map[string]Balance, error) { } // GetWithdrawInfo gets withdrawal fees -func (k *Kraken) GetWithdrawInfo(ctx context.Context, currency string, amount float64) (*WithdrawInformation, error) { +func (e *Exchange) GetWithdrawInfo(ctx context.Context, currency string, amount float64) (*WithdrawInformation, error) { params := url.Values{} params.Set("asset", currency) params.Set("key", "") params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result WithdrawInformation - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawInfo, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawInfo, params, &result); err != nil { return nil, err } @@ -353,14 +353,14 @@ func (k *Kraken) GetWithdrawInfo(ctx context.Context, currency string, amount fl } // Withdraw withdraws funds -func (k *Kraken) Withdraw(ctx context.Context, asset, key string, amount float64) (string, error) { +func (e *Exchange) Withdraw(ctx context.Context, asset, key string, amount float64) (string, error) { params := url.Values{} params.Set("asset", asset) params.Set("key", key) params.Set("amount", fmt.Sprintf("%f", amount)) var referenceID string - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdraw, params, &referenceID); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdraw, params, &referenceID); err != nil { return referenceID, err } @@ -368,12 +368,12 @@ func (k *Kraken) Withdraw(ctx context.Context, asset, key string, amount float64 } // GetDepositMethods gets withdrawal fees -func (k *Kraken) GetDepositMethods(ctx context.Context, currency string) ([]DepositMethods, error) { +func (e *Exchange) GetDepositMethods(ctx context.Context, currency string) ([]DepositMethods, error) { params := url.Values{} params.Set("asset", currency) var result []DepositMethods - err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositMethods, params, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositMethods, params, &result) if err != nil { return nil, err } @@ -382,7 +382,7 @@ func (k *Kraken) GetDepositMethods(ctx context.Context, currency string) ([]Depo } // GetTradeBalance returns full information about your trades on Kraken -func (k *Kraken) GetTradeBalance(ctx context.Context, args ...TradeBalanceOptions) (*TradeBalanceInfo, error) { +func (e *Exchange) GetTradeBalance(ctx context.Context, args ...TradeBalanceOptions) (*TradeBalanceInfo, error) { params := url.Values{} if args != nil { @@ -396,7 +396,7 @@ func (k *Kraken) GetTradeBalance(ctx context.Context, args ...TradeBalanceOption } var result TradeBalanceInfo - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeBalance, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeBalance, params, &result); err != nil { return nil, err } @@ -404,7 +404,7 @@ func (k *Kraken) GetTradeBalance(ctx context.Context, args ...TradeBalanceOption } // GetOpenOrders returns all current open orders -func (k *Kraken) GetOpenOrders(ctx context.Context, args OrderInfoOptions) (*OpenOrders, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, args OrderInfoOptions) (*OpenOrders, error) { params := url.Values{} if args.Trades { @@ -416,7 +416,7 @@ func (k *Kraken) GetOpenOrders(ctx context.Context, args OrderInfoOptions) (*Ope } var result OpenOrders - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenOrders, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenOrders, params, &result); err != nil { return nil, err } @@ -424,7 +424,7 @@ func (k *Kraken) GetOpenOrders(ctx context.Context, args OrderInfoOptions) (*Ope } // GetClosedOrders returns a list of closed orders -func (k *Kraken) GetClosedOrders(ctx context.Context, args GetClosedOrdersOptions) (*ClosedOrders, error) { +func (e *Exchange) GetClosedOrders(ctx context.Context, args GetClosedOrdersOptions) (*ClosedOrders, error) { params := url.Values{} if args.Trades { @@ -452,7 +452,7 @@ func (k *Kraken) GetClosedOrders(ctx context.Context, args GetClosedOrdersOption } var result ClosedOrders - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenClosedOrders, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenClosedOrders, params, &result); err != nil { return nil, err } @@ -460,7 +460,7 @@ func (k *Kraken) GetClosedOrders(ctx context.Context, args GetClosedOrdersOption } // QueryOrdersInfo returns order information -func (k *Kraken) QueryOrdersInfo(ctx context.Context, args OrderInfoOptions, txid string, txids ...string) (map[string]OrderInfo, error) { +func (e *Exchange) QueryOrdersInfo(ctx context.Context, args OrderInfoOptions, txid string, txids ...string) (map[string]OrderInfo, error) { params := url.Values{ "txid": {txid}, } @@ -478,7 +478,7 @@ func (k *Kraken) QueryOrdersInfo(ctx context.Context, args OrderInfoOptions, txi } var result map[string]OrderInfo - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryOrders, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryOrders, params, &result); err != nil { return result, err } @@ -486,7 +486,7 @@ func (k *Kraken) QueryOrdersInfo(ctx context.Context, args OrderInfoOptions, txi } // GetTradesHistory returns trade history information -func (k *Kraken) GetTradesHistory(ctx context.Context, args ...GetTradesHistoryOptions) (*TradesHistory, error) { +func (e *Exchange) GetTradesHistory(ctx context.Context, args ...GetTradesHistoryOptions) (*TradesHistory, error) { params := url.Values{} if args != nil { @@ -512,7 +512,7 @@ func (k *Kraken) GetTradesHistory(ctx context.Context, args ...GetTradesHistoryO } var result TradesHistory - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeHistory, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeHistory, params, &result); err != nil { return nil, err } @@ -520,7 +520,7 @@ func (k *Kraken) GetTradesHistory(ctx context.Context, args ...GetTradesHistoryO } // QueryTrades returns information on a specific trade -func (k *Kraken) QueryTrades(ctx context.Context, trades bool, txid string, txids ...string) (map[string]TradeInfo, error) { +func (e *Exchange) QueryTrades(ctx context.Context, trades bool, txid string, txids ...string) (map[string]TradeInfo, error) { params := url.Values{ "txid": {txid}, } @@ -534,7 +534,7 @@ func (k *Kraken) QueryTrades(ctx context.Context, trades bool, txid string, txid } var result map[string]TradeInfo - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryTrades, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryTrades, params, &result); err != nil { return nil, err } @@ -542,7 +542,7 @@ func (k *Kraken) QueryTrades(ctx context.Context, trades bool, txid string, txid } // OpenPositions returns current open positions -func (k *Kraken) OpenPositions(ctx context.Context, docalcs bool, txids ...string) (map[string]Position, error) { +func (e *Exchange) OpenPositions(ctx context.Context, docalcs bool, txids ...string) (map[string]Position, error) { params := url.Values{} if txids != nil { @@ -554,7 +554,7 @@ func (k *Kraken) OpenPositions(ctx context.Context, docalcs bool, txids ...strin } var result map[string]Position - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenPositions, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenPositions, params, &result); err != nil { return nil, err } @@ -562,7 +562,7 @@ func (k *Kraken) OpenPositions(ctx context.Context, docalcs bool, txids ...strin } // GetLedgers returns current ledgers -func (k *Kraken) GetLedgers(ctx context.Context, args ...GetLedgersOptions) (*Ledgers, error) { +func (e *Exchange) GetLedgers(ctx context.Context, args ...GetLedgersOptions) (*Ledgers, error) { params := url.Values{} if args != nil { @@ -592,7 +592,7 @@ func (k *Kraken) GetLedgers(ctx context.Context, args ...GetLedgersOptions) (*Le } var result Ledgers - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenLedgers, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenLedgers, params, &result); err != nil { return nil, err } @@ -600,7 +600,7 @@ func (k *Kraken) GetLedgers(ctx context.Context, args ...GetLedgersOptions) (*Le } // QueryLedgers queries an individual ledger by ID -func (k *Kraken) QueryLedgers(ctx context.Context, id string, ids ...string) (map[string]LedgerInfo, error) { +func (e *Exchange) QueryLedgers(ctx context.Context, id string, ids ...string) (map[string]LedgerInfo, error) { params := url.Values{ "id": {id}, } @@ -610,7 +610,7 @@ func (k *Kraken) QueryLedgers(ctx context.Context, id string, ids ...string) (ma } var result map[string]LedgerInfo - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryLedgers, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryLedgers, params, &result); err != nil { return nil, err } @@ -618,11 +618,11 @@ func (k *Kraken) QueryLedgers(ctx context.Context, id string, ids ...string) (ma } // GetTradeVolume returns your trade volume by currency -func (k *Kraken) GetTradeVolume(ctx context.Context, feeinfo bool, symbol ...currency.Pair) (*TradeVolumeResponse, error) { +func (e *Exchange) GetTradeVolume(ctx context.Context, feeinfo bool, symbol ...currency.Pair) (*TradeVolumeResponse, error) { params := url.Values{} formattedPairs := make([]string, len(symbol)) for x := range symbol { - symbolValue, err := k.FormatSymbol(symbol[x], asset.Spot) + symbolValue, err := e.FormatSymbol(symbol[x], asset.Spot) if err != nil { return nil, err } @@ -637,7 +637,7 @@ func (k *Kraken) GetTradeVolume(ctx context.Context, feeinfo bool, symbol ...cur } var result *TradeVolumeResponse - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeVolume, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeVolume, params, &result); err != nil { return nil, err } @@ -645,8 +645,8 @@ func (k *Kraken) GetTradeVolume(ctx context.Context, feeinfo bool, symbol ...cur } // AddOrder adds a new order for Kraken exchange -func (k *Kraken) AddOrder(ctx context.Context, symbol currency.Pair, side, orderType string, volume, price, price2, leverage float64, args *AddOrderOptions) (*AddOrderResponse, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Spot) +func (e *Exchange) AddOrder(ctx context.Context, symbol currency.Pair, side, orderType string, volume, price, price2, leverage float64, args *AddOrderOptions) (*AddOrderResponse, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } @@ -702,7 +702,7 @@ func (k *Kraken) AddOrder(ctx context.Context, symbol currency.Pair, side, order } var result AddOrderResponse - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderPlace, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderPlace, params, &result); err != nil { return nil, err } @@ -710,13 +710,13 @@ func (k *Kraken) AddOrder(ctx context.Context, symbol currency.Pair, side, order } // CancelExistingOrder cancels order by orderID -func (k *Kraken) CancelExistingOrder(ctx context.Context, txid string) (*CancelOrderResponse, error) { +func (e *Exchange) CancelExistingOrder(ctx context.Context, txid string) (*CancelOrderResponse, error) { values := url.Values{ "txid": {txid}, } var result CancelOrderResponse - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderCancel, values, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderCancel, values, &result); err != nil { return nil, err } @@ -724,8 +724,8 @@ func (k *Kraken) CancelExistingOrder(ctx context.Context, txid string) (*CancelO } // SendHTTPRequest sends an unauthenticated HTTP requests -func (k *Kraken) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := k.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -735,12 +735,12 @@ func (k *Kraken) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri Method: http.MethodGet, Path: endpoint + path, Result: &rawMessage, - Verbose: k.Verbose, - HTTPDebugging: k.HTTPDebugging, - HTTPRecording: k.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - err = k.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) if err != nil { @@ -758,7 +758,7 @@ func (k *Kraken) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri } if genResponse.Error.Warnings() != "" { - log.Warnf(log.ExchangeSys, "%v: REST request warning: %v", k.Name, genResponse.Error.Warnings()) + log.Warnf(log.ExchangeSys, "%v: REST request warning: %v", e.Name, genResponse.Error.Warnings()) } return genResponse.Error.Errors() @@ -772,19 +772,19 @@ func (k *Kraken) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (k *Kraken) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method string, params url.Values, result any) error { - creds, err := k.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method string, params url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := k.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } interim := json.RawMessage{} - err = k.SendPayload(ctx, request.Unset, func() (*request.Item, error) { - nonce := k.Requester.GetNonce(nonce.UnixNano).String() + err = e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + nonce := e.Requester.GetNonce(nonce.UnixNano).String() params.Set("nonce", nonce) encoded := params.Encode() @@ -806,9 +806,9 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U Body: strings.NewReader(encoded), Result: &interim, NonceEnabled: true, - Verbose: k.Verbose, - HTTPDebugging: k.HTTPDebugging, - HTTPRecording: k.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -828,18 +828,18 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.U } if genResponse.Error.Warnings() != "" { - log.Warnf(log.ExchangeSys, "%v: AUTH REST request warning: %v", k.Name, genResponse.Error.Warnings()) + log.Warnf(log.ExchangeSys, "%v: AUTH REST request warning: %v", e.Name, genResponse.Error.Warnings()) } return nil } // GetFee returns an estimate of fee based on type of transaction -func (k *Kraken) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feePair, err := k.GetTradeVolume(ctx, true, feeBuilder.Pair) + feePair, err := e.GetTradeVolume(ctx, true, feeBuilder.Pair) if err != nil { return 0, err } @@ -857,7 +857,7 @@ func (k *Kraken) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (f case exchange.CryptocurrencyWithdrawalFee: fee = getWithdrawalFee(feeBuilder.Pair.Base) case exchange.InternationalBankDepositFee: - depositMethods, err := k.GetDepositMethods(ctx, + depositMethods, err := e.GetDepositMethods(ctx, feeBuilder.FiatCurrency.String()) if err != nil { return 0, err @@ -904,7 +904,7 @@ func calculateTradingFee(currency string, feePair map[string]TradeVolumeFee, pur } // GetCryptoDepositAddress returns a deposit address for a cryptocurrency -func (k *Kraken) GetCryptoDepositAddress(ctx context.Context, method, code string, createNew bool) ([]DepositAddress, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, method, code string, createNew bool) ([]DepositAddress, error) { values := url.Values{} values.Set("asset", code) values.Set("method", method) @@ -914,7 +914,7 @@ func (k *Kraken) GetCryptoDepositAddress(ctx context.Context, method, code strin } var result []DepositAddress - err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositAddresses, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositAddresses, values, &result) if err != nil { return nil, err } @@ -926,7 +926,7 @@ func (k *Kraken) GetCryptoDepositAddress(ctx context.Context, method, code strin } // WithdrawStatus gets the status of recent withdrawals -func (k *Kraken) WithdrawStatus(ctx context.Context, c currency.Code, method string) ([]WithdrawStatusResponse, error) { +func (e *Exchange) WithdrawStatus(ctx context.Context, c currency.Code, method string) ([]WithdrawStatusResponse, error) { params := url.Values{} params.Set("asset", c.String()) if method != "" { @@ -934,7 +934,7 @@ func (k *Kraken) WithdrawStatus(ctx context.Context, c currency.Code, method str } var result []WithdrawStatusResponse - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawStatus, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawStatus, params, &result); err != nil { return nil, err } @@ -942,13 +942,13 @@ func (k *Kraken) WithdrawStatus(ctx context.Context, c currency.Code, method str } // WithdrawCancel sends a withdrawal cancellation request -func (k *Kraken) WithdrawCancel(ctx context.Context, c currency.Code, refID string) (bool, error) { +func (e *Exchange) WithdrawCancel(ctx context.Context, c currency.Code, refID string) (bool, error) { params := url.Values{} params.Set("asset", c.String()) params.Set("refid", refID) var result bool - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawCancel, params, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawCancel, params, &result); err != nil { return result, err } @@ -956,9 +956,9 @@ func (k *Kraken) WithdrawCancel(ctx context.Context, c currency.Code, refID stri } // GetWebsocketToken returns a websocket token -func (k *Kraken) GetWebsocketToken(ctx context.Context) (string, error) { +func (e *Exchange) GetWebsocketToken(ctx context.Context) (string, error) { var response WsTokenResponse - if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWebsocketToken, url.Values{}, &response); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWebsocketToken, url.Values{}, &response); err != nil { return "", err } return response.Token, nil diff --git a/exchanges/kraken/kraken_futures.go b/exchanges/kraken/kraken_futures.go index 349fc92563a..6c0e5acfcec 100644 --- a/exchanges/kraken/kraken_futures.go +++ b/exchanges/kraken/kraken_futures.go @@ -25,20 +25,20 @@ import ( var errInvalidBatchOrderType = errors.New("invalid batch order type") // GetFuturesOrderbook gets orderbook data for futures -func (k *Kraken) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair) (*FuturesOrderbookData, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) +func (e *Exchange) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair) (*FuturesOrderbookData, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return nil, err } params := url.Values{} params.Set("symbol", symbolValue) var resp FuturesOrderbookData - return &resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresOrderbook+"?"+params.Encode(), &resp) + return &resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresOrderbook+"?"+params.Encode(), &resp) } // GetFuturesCharts returns candle data for kraken futures -func (k *Kraken) GetFuturesCharts(ctx context.Context, resolution, tickType string, symbol currency.Pair, to, from time.Time) (*FuturesCandles, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) +func (e *Exchange) GetFuturesCharts(ctx context.Context, resolution, tickType string, symbol currency.Pair, to, from time.Time) (*FuturesCandles, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return nil, err } @@ -54,12 +54,12 @@ func (k *Kraken) GetFuturesCharts(ctx context.Context, resolution, tickType stri reqStr += "?" + params.Encode() } var resp FuturesCandles - return &resp, k.SendHTTPRequest(ctx, exchange.RestFuturesSupplementary, reqStr, &resp) + return &resp, e.SendHTTPRequest(ctx, exchange.RestFuturesSupplementary, reqStr, &resp) } // GetFuturesTrades returns public trade data for kraken futures -func (k *Kraken) GetFuturesTrades(ctx context.Context, symbol currency.Pair, to, from time.Time) (*FuturesPublicTrades, error) { - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) +func (e *Exchange) GetFuturesTrades(ctx context.Context, symbol currency.Pair, to, from time.Time) (*FuturesPublicTrades, error) { + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return nil, err } @@ -71,32 +71,32 @@ func (k *Kraken) GetFuturesTrades(ctx context.Context, symbol currency.Pair, to, params.Set("before", strconv.FormatInt(from.Unix(), 10)) } var resp FuturesPublicTrades - return &resp, k.SendHTTPRequest(ctx, exchange.RestFuturesSupplementary, futuresPublicTrades+"/"+symbolValue+"/executions?"+params.Encode(), &resp) + return &resp, e.SendHTTPRequest(ctx, exchange.RestFuturesSupplementary, futuresPublicTrades+"/"+symbolValue+"/executions?"+params.Encode(), &resp) } // GetInstruments gets a list of futures markets and their data -func (k *Kraken) GetInstruments(ctx context.Context) (FuturesInstrumentData, error) { +func (e *Exchange) GetInstruments(ctx context.Context) (FuturesInstrumentData, error) { var resp FuturesInstrumentData - return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresInstruments, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresInstruments, &resp) } // GetFuturesTickers gets a list of futures tickers and their data -func (k *Kraken) GetFuturesTickers(ctx context.Context) (FuturesTickersData, error) { +func (e *Exchange) GetFuturesTickers(ctx context.Context) (FuturesTickersData, error) { var resp FuturesTickersData - return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickers, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickers, &resp) } // GetFuturesTickerBySymbol returns futures ticker data by symbol -func (k *Kraken) GetFuturesTickerBySymbol(ctx context.Context, symbol string) (FuturesTickerData, error) { +func (e *Exchange) GetFuturesTickerBySymbol(ctx context.Context, symbol string) (FuturesTickerData, error) { var resp FuturesTickerData - return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickers+"/"+symbol, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickers+"/"+symbol, &resp) } // GetFuturesTradeHistory gets public trade history data for futures -func (k *Kraken) GetFuturesTradeHistory(ctx context.Context, symbol currency.Pair, lastTime time.Time) (FuturesTradeHistoryData, error) { +func (e *Exchange) GetFuturesTradeHistory(ctx context.Context, symbol currency.Pair, lastTime time.Time) (FuturesTradeHistoryData, error) { var resp FuturesTradeHistoryData params := url.Values{} - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return resp, err } @@ -104,18 +104,18 @@ func (k *Kraken) GetFuturesTradeHistory(ctx context.Context, symbol currency.Pai if !lastTime.IsZero() { params.Set("lastTime", lastTime.Format("2006-01-02T15:04:05.070Z")) } - return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresTradeHistory+"?"+params.Encode(), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresTradeHistory+"?"+params.Encode(), &resp) } // FuturesBatchOrder places a batch order for futures -func (k *Kraken) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) (BatchOrderData, error) { +func (e *Exchange) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) (BatchOrderData, error) { var resp BatchOrderData for x := range data { unformattedPair, err := currency.NewPairFromString(data[x].Symbol) if err != nil { return resp, err } - formattedPair, err := k.FormatExchangeCurrency(unformattedPair, asset.Futures) + formattedPair, err := e.FormatExchangeCurrency(unformattedPair, asset.Futures) if err != nil { return resp, err } @@ -137,11 +137,11 @@ func (k *Kraken) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderDa params := url.Values{} params.Set("json", string(jsonData)) - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresBatchOrder, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresBatchOrder, params, &resp) } // FuturesEditOrder edits a futures order -func (k *Kraken) FuturesEditOrder(ctx context.Context, orderID, clientOrderID string, size, limitPrice, stopPrice float64) (FuturesAccountsData, error) { +func (e *Exchange) FuturesEditOrder(ctx context.Context, orderID, clientOrderID string, size, limitPrice, stopPrice float64) (FuturesAccountsData, error) { var resp FuturesAccountsData params := url.Values{} if orderID != "" { @@ -153,11 +153,11 @@ func (k *Kraken) FuturesEditOrder(ctx context.Context, orderID, clientOrderID st params.Set("size", strconv.FormatFloat(size, 'f', -1, 64)) params.Set("limitPrice", strconv.FormatFloat(limitPrice, 'f', -1, 64)) params.Set("stopPrice", strconv.FormatFloat(stopPrice, 'f', -1, 64)) - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresEditOrder, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresEditOrder, params, &resp) } // FuturesSendOrder sends a futures order -func (k *Kraken) FuturesSendOrder(ctx context.Context, orderType order.Type, symbol currency.Pair, side, triggerSignal, clientOrderID, reduceOnly string, tif order.TimeInForce, size, limitPrice, stopPrice float64) (FuturesSendOrderData, error) { +func (e *Exchange) FuturesSendOrder(ctx context.Context, orderType order.Type, symbol currency.Pair, side, triggerSignal, clientOrderID, reduceOnly string, tif order.TimeInForce, size, limitPrice, stopPrice float64) (FuturesSendOrderData, error) { var resp FuturesSendOrderData oType, ok := validOrderTypes[orderType] if !ok { @@ -174,7 +174,7 @@ func (k *Kraken) FuturesSendOrder(ctx context.Context, orderType order.Type, sym params := url.Values{} params.Set("orderType", oType) - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return resp, err } @@ -203,11 +203,11 @@ func (k *Kraken) FuturesSendOrder(ctx context.Context, orderType order.Type, sym if stopPrice != 0 { params.Set("stopPrice", strconv.FormatFloat(stopPrice, 'f', -1, 64)) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresSendOrder, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresSendOrder, params, &resp) } // FuturesCancelOrder cancels an order -func (k *Kraken) FuturesCancelOrder(ctx context.Context, orderID, clientOrderID string) (FuturesCancelOrderData, error) { +func (e *Exchange) FuturesCancelOrder(ctx context.Context, orderID, clientOrderID string) (FuturesCancelOrderData, error) { var resp FuturesCancelOrderData params := url.Values{} if orderID != "" { @@ -216,110 +216,110 @@ func (k *Kraken) FuturesCancelOrder(ctx context.Context, orderID, clientOrderID if clientOrderID != "" { params.Set("cliOrdId", clientOrderID) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrder, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrder, params, &resp) } // FuturesGetFills gets order fills for futures -func (k *Kraken) FuturesGetFills(ctx context.Context, lastFillTime time.Time) (FuturesFillsData, error) { +func (e *Exchange) FuturesGetFills(ctx context.Context, lastFillTime time.Time) (FuturesFillsData, error) { var resp FuturesFillsData params := url.Values{} if !lastFillTime.IsZero() { params.Set("lastFillTime", lastFillTime.UTC().Format("2006-01-02T15:04:05.999Z")) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOrderFills, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOrderFills, params, &resp) } // FuturesTransfer transfers funds between accounts -func (k *Kraken) FuturesTransfer(ctx context.Context, fromAccount, toAccount, unit string, amount float64) (FuturesTransferData, error) { +func (e *Exchange) FuturesTransfer(ctx context.Context, fromAccount, toAccount, unit string, amount float64) (FuturesTransferData, error) { var resp FuturesTransferData req := make(map[string]any) req["fromAccount"] = fromAccount req["toAccount"] = toAccount req["unit"] = unit req["amount"] = amount - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresTransfer, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresTransfer, nil, &resp) } // FuturesGetOpenPositions gets futures platform's notifications -func (k *Kraken) FuturesGetOpenPositions(ctx context.Context) (FuturesOpenPositions, error) { +func (e *Exchange) FuturesGetOpenPositions(ctx context.Context) (FuturesOpenPositions, error) { var resp FuturesOpenPositions - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenPositions, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenPositions, nil, &resp) } // FuturesNotifications gets futures notifications -func (k *Kraken) FuturesNotifications(ctx context.Context) (FuturesNotificationData, error) { +func (e *Exchange) FuturesNotifications(ctx context.Context) (FuturesNotificationData, error) { var resp FuturesNotificationData - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresNotifications, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresNotifications, nil, &resp) } // FuturesCancelAllOrders cancels all futures orders for a given symbol or all symbols -func (k *Kraken) FuturesCancelAllOrders(ctx context.Context, symbol currency.Pair) (CancelAllOrdersData, error) { +func (e *Exchange) FuturesCancelAllOrders(ctx context.Context, symbol currency.Pair) (CancelAllOrdersData, error) { var resp CancelAllOrdersData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelAllOrders, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelAllOrders, params, &resp) } // FuturesCancelAllOrdersAfter cancels all futures orders for all symbols after a period of time (timeout measured in seconds) -func (k *Kraken) FuturesCancelAllOrdersAfter(ctx context.Context, timeout int64) (CancelOrdersAfterData, error) { +func (e *Exchange) FuturesCancelAllOrdersAfter(ctx context.Context, timeout int64) (CancelOrdersAfterData, error) { var resp CancelOrdersAfterData params := url.Values{} params.Set("timeout", strconv.FormatInt(timeout, 10)) - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrdersAfter, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrdersAfter, params, &resp) } // FuturesOpenOrders gets all futures open orders -func (k *Kraken) FuturesOpenOrders(ctx context.Context) (FuturesOpenOrdersData, error) { +func (e *Exchange) FuturesOpenOrders(ctx context.Context) (FuturesOpenOrdersData, error) { var resp FuturesOpenOrdersData - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenOrders, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenOrders, nil, &resp) } // FuturesRecentOrders gets recent futures orders for a symbol or all symbols -func (k *Kraken) FuturesRecentOrders(ctx context.Context, symbol currency.Pair) (FuturesRecentOrdersData, error) { +func (e *Exchange) FuturesRecentOrders(ctx context.Context, symbol currency.Pair) (FuturesRecentOrdersData, error) { var resp FuturesRecentOrdersData params := url.Values{} if !symbol.IsEmpty() { - symbolValue, err := k.FormatSymbol(symbol, asset.Futures) + symbolValue, err := e.FormatSymbol(symbol, asset.Futures) if err != nil { return resp, err } params.Set("symbol", symbolValue) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresRecentOrders, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresRecentOrders, nil, &resp) } // FuturesWithdrawToSpotWallet withdraws currencies from futures wallet to spot wallet -func (k *Kraken) FuturesWithdrawToSpotWallet(ctx context.Context, currency string, amount float64) (GenericResponse, error) { +func (e *Exchange) FuturesWithdrawToSpotWallet(ctx context.Context, currency string, amount float64) (GenericResponse, error) { var resp GenericResponse params := url.Values{} params.Set("currency", currency) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresWithdraw, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresWithdraw, params, &resp) } // FuturesGetTransfers withdraws currencies from futures wallet to spot wallet -func (k *Kraken) FuturesGetTransfers(ctx context.Context, lastTransferTime time.Time) (GenericResponse, error) { +func (e *Exchange) FuturesGetTransfers(ctx context.Context, lastTransferTime time.Time) (GenericResponse, error) { var resp GenericResponse params := url.Values{} if !lastTransferTime.IsZero() { params.Set("lastTransferTime", lastTransferTime.UTC().Format(time.RFC3339)) } - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresTransfers, params, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresTransfers, params, &resp) } // GetFuturesAccountData gets account data for futures -func (k *Kraken) GetFuturesAccountData(ctx context.Context) (FuturesAccountsData, error) { +func (e *Exchange) GetFuturesAccountData(ctx context.Context) (FuturesAccountsData, error) { var resp FuturesAccountsData - return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresAccountData, nil, &resp) + return resp, e.SendFuturesAuthRequest(ctx, http.MethodGet, futuresAccountData, nil, &resp) } -func (k *Kraken) signFuturesRequest(secret, endpoint, nonce, data string) (string, error) { +func (e *Exchange) signFuturesRequest(secret, endpoint, nonce, data string) (string, error) { shasum := sha256.Sum256([]byte(data + nonce + endpoint)) hmac, err := crypto.GetHMAC(crypto.HashSHA512, shasum[:], []byte(secret)) if err != nil { @@ -329,8 +329,8 @@ func (k *Kraken) signFuturesRequest(secret, endpoint, nonce, data string) (strin } // SendFuturesAuthRequest will send an auth req -func (k *Kraken) SendFuturesAuthRequest(ctx context.Context, method, path string, data url.Values, result any) error { - creds, err := k.GetCredentials(ctx) +func (e *Exchange) SendFuturesAuthRequest(ctx context.Context, method, path string, data url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -348,7 +348,7 @@ func (k *Kraken) SendFuturesAuthRequest(ctx context.Context, method, path string newRequest := func() (*request.Item, error) { nonce := strconv.FormatInt(time.Now().UnixNano(), 10) var sig string - sig, err = k.signFuturesRequest(creds.Secret, path, nonce, dataToSign) + sig, err = e.signFuturesRequest(creds.Secret, path, nonce, dataToSign) if err != nil { return nil, err } @@ -359,7 +359,7 @@ func (k *Kraken) SendFuturesAuthRequest(ctx context.Context, method, path string } var futuresURL string - futuresURL, err = k.API.Endpoints.GetURL(exchange.RestFutures) + futuresURL, err = e.API.Endpoints.GetURL(exchange.RestFutures) if err != nil { return nil, err } @@ -369,13 +369,13 @@ func (k *Kraken) SendFuturesAuthRequest(ctx context.Context, method, path string Path: futuresURL + common.EncodeURLValues(path, data), Headers: headers, Result: &interim, - Verbose: k.Verbose, - HTTPDebugging: k.HTTPDebugging, - HTTPRecording: k.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - err = k.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) + err = e.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest) if err == nil { err = getFuturesErr(interim) diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 3824bc721f6..3d383beba26 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -35,7 +35,7 @@ import ( ) var ( - k *Kraken + e *Exchange spotTestPair = currency.NewPair(currency.XBT, currency.USD) futuresTestPair = currency.NewPairWithDelimiter("PF", "XBTUSD", "_") ) @@ -48,31 +48,31 @@ const ( ) func TestMain(m *testing.M) { - k = new(Kraken) - if err := testexch.Setup(k); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Kraken Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - k.API.AuthenticatedSupport = true - k.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) } func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) + testexch.UpdatePairsOnce(t, e) } func TestGetCurrentServerTime(t *testing.T) { t.Parallel() - _, err := k.GetCurrentServerTime(t.Context()) + _, err := e.GetCurrentServerTime(t.Context()) assert.NoError(t, err, "GetCurrentServerTime should not error") } func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := k.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err, "GetServerTime must not error") assert.WithinRange(t, st, time.Now().Add(-24*time.Hour), time.Now().Add(24*time.Hour), "ServerTime should be within a day of now") } @@ -81,13 +81,13 @@ func TestWrapperGetServerTime(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := k.UpdateOrderExecutionLimits(t.Context(), asset.Spot) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Spot) require.NoError(t, err, "UpdateOrderExecutionLimits must not error") for _, p := range []currency.Pair{ currency.NewPair(currency.ETH, currency.USDT), currency.NewPair(currency.XBT, currency.USDT), } { - limits, err := k.GetOrderExecutionLimits(asset.Spot, p) + limits, err := e.GetOrderExecutionLimits(asset.Spot, p) require.NoErrorf(t, err, "%s GetOrderExecutionLimits must not error", p) assert.Positivef(t, limits.PriceStepIncrementSize, "%s PriceStepIncrementSize should be positive", p) assert.Positivef(t, limits.MinimumBaseAmount, "%s MinimumBaseAmount should be positive", p) @@ -96,59 +96,59 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := k.FetchTradablePairs(t.Context(), asset.Futures) + _, err := e.FetchTradablePairs(t.Context(), asset.Futures) assert.NoError(t, err, "FetchTradablePairs should not error") } func TestUpdateTicker(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) - _, err := k.UpdateTicker(t.Context(), spotTestPair, asset.Spot) + testexch.UpdatePairsOnce(t, e) + _, err := e.UpdateTicker(t.Context(), spotTestPair, asset.Spot) assert.NoError(t, err, "UpdateTicker spot asset should not error") - _, err = k.UpdateTicker(t.Context(), futuresTestPair, asset.Futures) + _, err = e.UpdateTicker(t.Context(), futuresTestPair, asset.Futures) assert.NoError(t, err, "UpdateTicker futures asset should not error") } func TestUpdateTickers(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - testexch.UpdatePairsOnce(t, k) + testexch.UpdatePairsOnce(t, e) - err := k.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) require.NoError(t, err, "UpdateTickers must not error") - ap, err := k.GetAvailablePairs(asset.Spot) + ap, err := e.GetAvailablePairs(asset.Spot) require.NoError(t, err, "GetAvailablePairs must not error") for i := range ap { - _, err = ticker.GetTicker(k.Name, ap[i], asset.Spot) + _, err = ticker.GetTicker(e.Name, ap[i], asset.Spot) assert.NoErrorf(t, err, "GetTicker should not error for %s", ap[i]) } - ap, err = k.GetAvailablePairs(asset.Futures) + ap, err = e.GetAvailablePairs(asset.Futures) require.NoError(t, err, "GetAvailablePairs must not error") - err = k.UpdateTickers(t.Context(), asset.Futures) + err = e.UpdateTickers(t.Context(), asset.Futures) require.NoError(t, err, "UpdateTickers must not error") for i := range ap { - _, err = ticker.GetTicker(k.Name, ap[i], asset.Futures) + _, err = ticker.GetTicker(e.Name, ap[i], asset.Futures) assert.NoErrorf(t, err, "GetTicker should not error for %s", ap[i]) } - err = k.UpdateTickers(t.Context(), asset.Index) + err = e.UpdateTickers(t.Context(), asset.Index) assert.ErrorIs(t, err, asset.ErrNotSupported, "UpdateTickers should error correctly for asset.Index") } func TestUpdateOrderbook(t *testing.T) { t.Parallel() - _, err := k.UpdateOrderbook(t.Context(), spotTestPair, asset.Spot) + _, err := e.UpdateOrderbook(t.Context(), spotTestPair, asset.Spot) assert.NoError(t, err, "UpdateOrderbook spot asset should not error") - _, err = k.UpdateOrderbook(t.Context(), futuresTestPair, asset.Futures) + _, err = e.UpdateOrderbook(t.Context(), futuresTestPair, asset.Futures) assert.NoError(t, err, "UpdateOrderbook futures asset should not error") } @@ -160,163 +160,163 @@ func TestFuturesBatchOrder(t *testing.T) { tempData.OrderID = "test123" tempData.Symbol = futuresTestPair.Lower().String() data = append(data, tempData) - _, err := k.FuturesBatchOrder(t.Context(), data) + _, err := e.FuturesBatchOrder(t.Context(), data) assert.ErrorIs(t, err, errInvalidBatchOrderType, "FuturesBatchOrder should error correctly") - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) data[0].PlaceOrderType = "cancel" - _, err = k.FuturesBatchOrder(t.Context(), data) + _, err = e.FuturesBatchOrder(t.Context(), data) assert.NoError(t, err, "FuturesBatchOrder should not error") } func TestFuturesEditOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesEditOrder(t.Context(), "test123", "", 5.2, 1, 0) + _, err := e.FuturesEditOrder(t.Context(), "test123", "", 5.2, 1, 0) assert.NoError(t, err, "FuturesEditOrder should not error") } func TestFuturesSendOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesSendOrder(t.Context(), order.Limit, futuresTestPair, "buy", "", "", "", order.ImmediateOrCancel, 1, 1, 0.9) + _, err := e.FuturesSendOrder(t.Context(), order.Limit, futuresTestPair, "buy", "", "", "", order.ImmediateOrCancel, 1, 1, 0.9) assert.NoError(t, err, "FuturesSendOrder should not error") } func TestFuturesCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesCancelOrder(t.Context(), "test123", "") + _, err := e.FuturesCancelOrder(t.Context(), "test123", "") assert.NoError(t, err, "FuturesCancelOrder should not error") } func TestFuturesGetFills(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesGetFills(t.Context(), time.Now().Add(-time.Hour*24)) + _, err := e.FuturesGetFills(t.Context(), time.Now().Add(-time.Hour*24)) assert.NoError(t, err, "FuturesGetFills should not error") } func TestFuturesTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesTransfer(t.Context(), "cash", "futures", "btc", 2) + _, err := e.FuturesTransfer(t.Context(), "cash", "futures", "btc", 2) assert.NoError(t, err, "FuturesTransfer should not error") } func TestFuturesGetOpenPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesGetOpenPositions(t.Context()) + _, err := e.FuturesGetOpenPositions(t.Context()) assert.NoError(t, err, "FuturesGetOpenPositions should not error") } func TestFuturesNotifications(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesNotifications(t.Context()) + _, err := e.FuturesNotifications(t.Context()) assert.NoError(t, err, "FuturesNotifications should not error") } func TestFuturesCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesCancelAllOrders(t.Context(), futuresTestPair) + _, err := e.FuturesCancelAllOrders(t.Context(), futuresTestPair) assert.NoError(t, err, "FuturesCancelAllOrders should not error") } func TestGetFuturesAccountData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.GetFuturesAccountData(t.Context()) + _, err := e.GetFuturesAccountData(t.Context()) assert.NoError(t, err, "GetFuturesAccountData should not error") } func TestFuturesCancelAllOrdersAfter(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesCancelAllOrdersAfter(t.Context(), 50) + _, err := e.FuturesCancelAllOrdersAfter(t.Context(), 50) assert.NoError(t, err, "FuturesCancelAllOrdersAfter should not error") } func TestFuturesOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesOpenOrders(t.Context()) + _, err := e.FuturesOpenOrders(t.Context()) assert.NoError(t, err, "FuturesOpenOrders should not error") } func TestFuturesRecentOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.FuturesRecentOrders(t.Context(), futuresTestPair) + _, err := e.FuturesRecentOrders(t.Context(), futuresTestPair) assert.NoError(t, err, "FuturesRecentOrders should not error") } func TestFuturesWithdrawToSpotWallet(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesWithdrawToSpotWallet(t.Context(), "xbt", 5) + _, err := e.FuturesWithdrawToSpotWallet(t.Context(), "xbt", 5) assert.NoError(t, err, "FuturesWithdrawToSpotWallet should not error") } func TestFuturesGetTransfers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := k.FuturesGetTransfers(t.Context(), time.Now().Add(-time.Hour*24)) + _, err := e.FuturesGetTransfers(t.Context(), time.Now().Add(-time.Hour*24)) assert.NoError(t, err, "FuturesGetTransfers should not error") } func TestGetFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := k.GetFuturesOrderbook(t.Context(), futuresTestPair) + _, err := e.GetFuturesOrderbook(t.Context(), futuresTestPair) assert.NoError(t, err, "GetFuturesOrderbook should not error") } func TestGetFuturesMarkets(t *testing.T) { t.Parallel() - _, err := k.GetInstruments(t.Context()) + _, err := e.GetInstruments(t.Context()) assert.NoError(t, err, "GetInstruments should not error") } func TestGetFuturesTickers(t *testing.T) { t.Parallel() - _, err := k.GetFuturesTickers(t.Context()) + _, err := e.GetFuturesTickers(t.Context()) assert.NoError(t, err, "GetFuturesTickers should not error") } func TestGetFuturesTradeHistory(t *testing.T) { t.Parallel() - _, err := k.GetFuturesTradeHistory(t.Context(), futuresTestPair, time.Now().Add(-time.Hour*24)) + _, err := e.GetFuturesTradeHistory(t.Context(), futuresTestPair, time.Now().Add(-time.Hour*24)) assert.NoError(t, err, "GetFuturesTradeHistory should not error") } // TestGetAssets API endpoint test func TestGetAssets(t *testing.T) { t.Parallel() - _, err := k.GetAssets(t.Context()) + _, err := e.GetAssets(t.Context()) assert.NoError(t, err, "GetAssets should not error") } func TestSeedAssetTranslator(t *testing.T) { t.Parallel() - err := k.SeedAssets(t.Context()) + err := e.SeedAssets(t.Context()) require.NoError(t, err, "SeedAssets must not error") for from, to := range map[string]string{"XBTUSD": "XXBTZUSD", "USD": "ZUSD", "XBT": "XXBT"} { @@ -348,7 +348,7 @@ func TestLookupCurrency(t *testing.T) { func TestGetAssetPairs(t *testing.T) { t.Parallel() for _, v := range []string{"fees", "leverage", "margin", ""} { - _, err := k.GetAssetPairs(t.Context(), []string{}, v) + _, err := e.GetAssetPairs(t.Context(), []string{}, v) require.NoErrorf(t, err, "GetAssetPairs %s must not error", v) } } @@ -356,35 +356,35 @@ func TestGetAssetPairs(t *testing.T) { // TestGetTicker API endpoint test func TestGetTicker(t *testing.T) { t.Parallel() - _, err := k.GetTicker(t.Context(), spotTestPair) + _, err := e.GetTicker(t.Context(), spotTestPair) assert.NoError(t, err, "GetTicker should not error") } // TestGetTickers API endpoint test func TestGetTickers(t *testing.T) { t.Parallel() - _, err := k.GetTickers(t.Context(), "LTCUSD,ETCUSD") + _, err := e.GetTickers(t.Context(), "LTCUSD,ETCUSD") assert.NoError(t, err, "GetTickers should not error") } // TestGetOHLC API endpoint test func TestGetOHLC(t *testing.T) { t.Parallel() - _, err := k.GetOHLC(t.Context(), currency.NewPairWithDelimiter("XXBT", "ZUSD", ""), "1440") + _, err := e.GetOHLC(t.Context(), currency.NewPairWithDelimiter("XXBT", "ZUSD", ""), "1440") assert.NoError(t, err, "GetOHLC should not error") } // TestGetDepth API endpoint test func TestGetDepth(t *testing.T) { t.Parallel() - _, err := k.GetDepth(t.Context(), spotTestPair) + _, err := e.GetDepth(t.Context(), spotTestPair) assert.NoError(t, err, "GetDepth should not error") } func TestGetTrades(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) - r, err := k.GetTrades(t.Context(), spotTestPair, time.Now().Add(-time.Hour*4), 1000) + testexch.UpdatePairsOnce(t, e) + r, err := e.GetTrades(t.Context(), spotTestPair, time.Now().Add(-time.Hour*4), 1000) require.NoError(t, err, "GetTrades must not error") require.NotNil(t, r, "GetTrades must return a valid response") } @@ -392,7 +392,7 @@ func TestGetTrades(t *testing.T) { func TestGetSpread(t *testing.T) { t.Parallel() p := currency.NewPair(currency.BCH, currency.EUR) // XBTUSD not in spread data - r, err := k.GetSpread(t.Context(), p, time.Now().Add(-time.Hour*4)) + r, err := e.GetSpread(t.Context(), p, time.Now().Add(-time.Hour*4)) require.NoError(t, err, "GetSpread must not error") require.NotNil(t, r, "GetSpread must return a valid response") require.NotZero(t, r.Last.Time(), "GetSpread must return a valid last updated time") @@ -404,76 +404,76 @@ func TestGetSpread(t *testing.T) { // TestGetBalance API endpoint test func TestGetBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.GetBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetBalance(t.Context()) assert.NoError(t, err, "GetBalance should not error") } func TestGetDepositMethods(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.GetDepositMethods(t.Context(), "USDT") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDepositMethods(t.Context(), "USDT") assert.NoError(t, err, "GetDepositMethods should not error") } // TestGetTradeBalance API endpoint test func TestGetTradeBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := TradeBalanceOptions{Asset: "ZEUR"} - _, err := k.GetTradeBalance(t.Context(), args) + _, err := e.GetTradeBalance(t.Context(), args) assert.NoError(t, err) } // TestGetOpenOrders API endpoint test func TestGetOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := OrderInfoOptions{Trades: true} - _, err := k.GetOpenOrders(t.Context(), args) + _, err := e.GetOpenOrders(t.Context(), args) assert.NoError(t, err) } // TestGetClosedOrders API endpoint test func TestGetClosedOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := GetClosedOrdersOptions{Trades: true, Start: "OE4KV4-4FVQ5-V7XGPU"} - _, err := k.GetClosedOrders(t.Context(), args) + _, err := e.GetClosedOrders(t.Context(), args) assert.NoError(t, err) } // TestQueryOrdersInfo API endpoint test func TestQueryOrdersInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := OrderInfoOptions{Trades: true} - _, err := k.QueryOrdersInfo(t.Context(), args, "OR6ZFV-AA6TT-CKFFIW", "OAMUAJ-HLVKG-D3QJ5F") + _, err := e.QueryOrdersInfo(t.Context(), args, "OR6ZFV-AA6TT-CKFFIW", "OAMUAJ-HLVKG-D3QJ5F") assert.NoError(t, err) } // TestGetTradesHistory API endpoint test func TestGetTradesHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := GetTradesHistoryOptions{Trades: true, Start: "TMZEDR-VBJN2-NGY6DX", End: "TVRXG2-R62VE-RWP3UW"} - _, err := k.GetTradesHistory(t.Context(), args) + _, err := e.GetTradesHistory(t.Context(), args) assert.NoError(t, err) } // TestQueryTrades API endpoint test func TestQueryTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.QueryTrades(t.Context(), true, "TMZEDR-VBJN2-NGY6DX", "TFLWIB-KTT7L-4TWR3L", "TDVRAH-2H6OS-SLSXRX") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.QueryTrades(t.Context(), true, "TMZEDR-VBJN2-NGY6DX", "TFLWIB-KTT7L-4TWR3L", "TDVRAH-2H6OS-SLSXRX") assert.NoError(t, err) } // TestOpenPositions API endpoint test func TestOpenPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.OpenPositions(t.Context(), false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.OpenPositions(t.Context(), false) assert.NoError(t, err) } @@ -481,38 +481,38 @@ func TestOpenPositions(t *testing.T) { // TODO: Needs a positive test func TestGetLedgers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) args := GetLedgersOptions{Start: "LRUHXI-IWECY-K4JYGO", End: "L5NIY7-JZQJD-3J4M2V", Ofs: 15} - _, err := k.GetLedgers(t.Context(), args) + _, err := e.GetLedgers(t.Context(), args) assert.ErrorContains(t, err, "EQuery:Unknown asset pair", "GetLedger should error on imaginary ledgers") } // TestQueryLedgers API endpoint test func TestQueryLedgers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.QueryLedgers(t.Context(), "LVTSFS-NHZVM-EXNZ5M") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.QueryLedgers(t.Context(), "LVTSFS-NHZVM-EXNZ5M") assert.NoError(t, err) } // TestGetTradeVolume API endpoint test func TestGetTradeVolume(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.GetTradeVolume(t.Context(), true, spotTestPair) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetTradeVolume(t.Context(), true, spotTestPair) assert.NoError(t, err, "GetTradeVolume should not error") } // TestOrders Tests AddOrder and CancelExistingOrder func TestOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) args := AddOrderOptions{OrderFlags: "fcib"} cp, err := currency.NewPairFromString("XXBTZUSD") assert.NoError(t, err, "NewPairFromString should not error") - resp, err := k.AddOrder(t.Context(), + resp, err := e.AddOrder(t.Context(), cp, order.Buy.Lower(), order.Limit.Lower(), 0.0001, 9000, 9000, 0, &args) @@ -520,7 +520,7 @@ func TestOrders(t *testing.T) { if assert.NoError(t, err, "AddOrder should not error") { if assert.Len(t, resp.TransactionIDs, 1, "One TransactionId should be returned") { id := resp.TransactionIDs[0] - _, err = k.CancelExistingOrder(t.Context(), id) + _, err = e.CancelExistingOrder(t.Context(), id) assert.NoErrorf(t, err, "CancelExistingOrder should not error, Please ensure order %s is cancelled manually", id) } } @@ -529,8 +529,8 @@ func TestOrders(t *testing.T) { // TestCancelExistingOrder API endpoint test func TestCancelExistingOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) - _, err := k.CancelExistingOrder(t.Context(), "OAVY7T-MV5VK-KHDF5X") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelExistingOrder(t.Context(), "OAVY7T-MV5VK-KHDF5X") if assert.Error(t, err, "Cancel with imaginary order-id should error") { assert.ErrorContains(t, err, "EOrder:Unknown order", "Cancel with imaginary order-id should error Unknown Order") } @@ -551,10 +551,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - f, err := k.GetFeeByType(t.Context(), feeBuilder) + f, err := e.GetFeeByType(t.Context(), feeBuilder) require.NoError(t, err, "GetFeeByType must not error") assert.Positive(t, f, "GetFeeByType should return a positive value") - if !sharedtestvalues.AreAPICredentialsSet(k) { + if !sharedtestvalues.AreAPICredentialsSet(e) { assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "GetFeeByType should set FeeType correctly") } else { assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType, "GetFeeByType should set FeeType correctly") @@ -566,53 +566,53 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(k) { - _, err := k.GetFee(t.Context(), feeBuilder) + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyTradeFee Basic GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyTradeFee High quantity GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyTradeFee IsMaker GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyTradeFee Negative purchase price GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "InternationalBankDepositFee Basic GetFee should not error") } feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee feeBuilder.Pair.Base = currency.XXBT - _, err := k.GetFee(t.Context(), feeBuilder) + _, err := e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyDepositFee Basic GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyWithdrawalFee Basic GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "CryptocurrencyWithdrawalFee Invalid currency GetFee should not error") feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - _, err = k.GetFee(t.Context(), feeBuilder) + _, err = e.GetFee(t.Context(), feeBuilder) assert.NoError(t, err, "InternationalBankWithdrawalFee Basic GetFee should not error") } @@ -620,14 +620,14 @@ func TestGetFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() exp := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.AutoWithdrawFiatWithSetupText + " & " + exchange.WithdrawFiatWith2FAText - withdrawPermissions := k.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() assert.Equal(t, exp, withdrawPermissions, "FormatWithdrawPermissions should return correct value") } // TestGetActiveOrders wrapper test func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, @@ -636,14 +636,14 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := k.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err, "GetActiveOrders should not error") } // TestGetOrderHistory wrapper test func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest := order.MultiOrderRequest{ Type: order.AnyType, @@ -651,15 +651,15 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := k.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) } // TestGetOrderInfo exercises GetOrderInfo func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) - _, err := k.GetOrderInfo(t.Context(), "OZPTPJ-HVYHF-EDIGXS", currency.EMPTYPAIR, asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrderInfo(t.Context(), "OZPTPJ-HVYHF-EDIGXS", currency.EMPTYPAIR, asset.Spot) assert.ErrorContains(t, err, "order OZPTPJ-HVYHF-EDIGXS not found in response", "Should error that order was not found in response") } @@ -669,10 +669,10 @@ func TestGetOrderInfo(t *testing.T) { // TestSubmitOrder wrapper test func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: k.Name, + Exchange: e.Name, Pair: spotTestPair, Side: order.Buy, Type: order.Limit, @@ -681,8 +681,8 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := k.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(k) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) { assert.NoError(t, err, "SubmitOrder should not error") assert.Equal(t, order.New, response.Status, "SubmitOrder should return a New order status") } else { @@ -694,21 +694,21 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - err := k.CancelOrder(t.Context(), &order.Cancel{ + err := e.CancelOrder(t.Context(), &order.Cancel{ AssetType: asset.Options, OrderID: "1337", }) assert.ErrorIs(t, err, asset.ErrNotSupported, "CancelOrder should error on Options asset") - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "OGEX6P-B5Q74-IGZ72R", AssetType: asset.Spot, } - err = k.CancelOrder(t.Context(), orderCancellation) - if sharedtestvalues.AreAPICredentialsSet(k) { + err = e.CancelOrder(t.Context(), orderCancellation) + if sharedtestvalues.AreAPICredentialsSet(e) { assert.NoError(t, err, "CancelOrder should not error") } else { assert.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled, "CancelOrder should error correctly") @@ -717,7 +717,7 @@ func TestCancelExchangeOrder(t *testing.T) { func TestCancelBatchExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) var ordersCancellation []order.Cancel ordersCancellation = append(ordersCancellation, order.Cancel{ @@ -726,8 +726,8 @@ func TestCancelBatchExchangeOrder(t *testing.T) { AssetType: asset.Spot, }) - _, err := k.CancelBatchOrders(t.Context(), ordersCancellation) - if sharedtestvalues.AreAPICredentialsSet(k) { + _, err := e.CancelBatchOrders(t.Context(), ordersCancellation) + if sharedtestvalues.AreAPICredentialsSet(e) { assert.NoError(t, err, "CancelBatchOrder should not error") } else { assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "CancelBatchOrders should error correctly") @@ -737,11 +737,11 @@ func TestCancelBatchExchangeOrder(t *testing.T) { // TestCancelAllExchangeOrders wrapper test func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - resp, err := k.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot}) + resp, err := e.CancelAllOrders(t.Context(), &order.Cancel{AssetType: asset.Spot}) - if sharedtestvalues.AreAPICredentialsSet(k) { + if sharedtestvalues.AreAPICredentialsSet(e) { assert.NoError(t, err, "CancelAllOrders should not error") } else { assert.ErrorIs(t, err, exchange.ErrAuthenticationSupportNotEnabled, "CancelBatchOrders should error correctly") @@ -755,9 +755,9 @@ func TestUpdateAccountInfo(t *testing.T) { t.Parallel() for _, a := range []asset.Item{asset.Spot, asset.Futures} { - _, err := k.UpdateAccountInfo(t.Context(), a) + _, err := e.UpdateAccountInfo(t.Context(), a) - if sharedtestvalues.AreAPICredentialsSet(k) { + if sharedtestvalues.AreAPICredentialsSet(e) { assert.NoErrorf(t, err, "UpdateAccountInfo should not error for asset %s", a) // Note Well: Spot and Futures have separate api keys } else { assert.ErrorIsf(t, err, exchange.ErrAuthenticationSupportNotEnabled, "UpdateAccountInfo should error correctly for asset %s", a) @@ -769,17 +769,17 @@ func TestUpdateAccountInfo(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := k.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "ModifyOrder should error correctly") } // TestWithdraw wrapper test func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: k.Name, + Exchange: e.Name, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, }, @@ -789,12 +789,12 @@ func TestWithdraw(t *testing.T) { TradePassword: "Key", } - _, err := k.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(k) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } @@ -802,7 +802,7 @@ func TestWithdraw(t *testing.T) { // TestWithdrawFiat wrapper test func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: -1, @@ -811,11 +811,11 @@ func TestWithdrawFiat(t *testing.T) { TradePassword: "someBank", } - _, err := k.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil { + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(k) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } @@ -823,7 +823,7 @@ func TestWithdrawFiat(t *testing.T) { // TestWithdrawInternationalBank wrapper test func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, k, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{ Amount: -1, @@ -832,28 +832,28 @@ func TestWithdrawInternationalBank(t *testing.T) { TradePassword: "someBank", } - _, err := k.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) - if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(k) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestGetCryptoDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := k.GetCryptoDepositAddress(t.Context(), "Bitcoin", "XBT", false) + _, err := e.GetCryptoDepositAddress(t.Context(), "Bitcoin", "XBT", false) if err != nil { t.Error(err) } if !canManipulateRealOrders { t.Skip("canManipulateRealOrders not set, skipping test") } - _, err = k.GetCryptoDepositAddress(t.Context(), "Bitcoin", "XBT", true) + _, err = e.GetCryptoDepositAddress(t.Context(), "Bitcoin", "XBT", true) if err != nil { t.Error(err) } @@ -862,13 +862,13 @@ func TestGetCryptoDepositAddress(t *testing.T) { // TestGetDepositAddress wrapper test func TestGetDepositAddress(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(k) { - _, err := k.GetDepositAddress(t.Context(), currency.USDT, "", "") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := k.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress() error can not be nil") } @@ -878,13 +878,13 @@ func TestGetDepositAddress(t *testing.T) { // TestWithdrawStatus wrapper test func TestWithdrawStatus(t *testing.T) { t.Parallel() - if sharedtestvalues.AreAPICredentialsSet(k) { - _, err := k.WithdrawStatus(t.Context(), currency.BTC, "") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.WithdrawStatus(t.Context(), currency.BTC, "") if err != nil { t.Error("WithdrawStatus() error", err) } } else { - _, err := k.WithdrawStatus(t.Context(), currency.BTC, "") + _, err := e.WithdrawStatus(t.Context(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error can not be nil") } @@ -894,10 +894,10 @@ func TestWithdrawStatus(t *testing.T) { // TestWithdrawCancel wrapper test func TestWithdrawCancel(t *testing.T) { t.Parallel() - _, err := k.WithdrawCancel(t.Context(), currency.BTC, "") - if sharedtestvalues.AreAPICredentialsSet(k) && err == nil { + _, err := e.WithdrawCancel(t.Context(), currency.BTC, "") + if sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("WithdrawCancel() error cannot be nil") - } else if !sharedtestvalues.AreAPICredentialsSet(k) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Errorf("WithdrawCancel() error - expecting an error when no keys are set but received nil") } } @@ -909,12 +909,12 @@ func TestWithdrawCancel(t *testing.T) { // single pass, single fail, mixed fail, multiple pass, all fail // No objection to this becoming a fixture test, so long as it integrates through Un/Subscribe roundtrip func TestWsSubscribe(t *testing.T) { - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.SetupWs(t, e) for _, enabled := range []bool{false, true} { - require.NoError(t, k.SetPairs(currency.Pairs{ + require.NoError(t, e.SetPairs(currency.Pairs{ spotTestPair, currency.NewPairWithDelimiter("ETH", "USD", "/"), currency.NewPairWithDelimiter("LTC", "ETH", "/"), @@ -926,24 +926,24 @@ func TestWsSubscribe(t *testing.T) { }, asset.Spot, enabled), "SetPairs must not error") } - err := k.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{spotTestPair}}}) + err := e.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{spotTestPair}}}) require.NoError(t, err, "Simple subscription must not error") - subs := k.Websocket.GetSubscriptions() + subs := e.Websocket.GetSubscriptions() require.Len(t, subs, 1, "Should add 1 Subscription") assert.Equal(t, subscription.SubscribedState, subs[0].State(), "Subscription should be subscribed state") - err = k.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{spotTestPair}}}) + err = e.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{spotTestPair}}}) assert.ErrorIs(t, err, subscription.ErrDuplicate, "Resubscribing to the same channel should error with SubscribedAlready") - subs = k.Websocket.GetSubscriptions() + subs = e.Websocket.GetSubscriptions() require.Len(t, subs, 1, "Should not add a subscription on error") assert.Equal(t, subscription.SubscribedState, subs[0].State(), "Existing subscription state should not change") - err = k.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "HOBBIT", "/")}}}) + err = e.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "HOBBIT", "/")}}}) assert.ErrorContains(t, err, "Currency pair not supported; Channel: ticker Pairs: DWARF/HOBBIT", "Subscribing to an invalid pair should error correctly") - require.Len(t, k.Websocket.GetSubscriptions(), 1, "Should not add a subscription on error") + require.Len(t, e.Websocket.GetSubscriptions(), 1, "Should not add a subscription on error") // Mix success and failure - err = k.Subscribe(subscription.List{ + err = e.Subscribe(subscription.List{ {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("ETH", "USD", "/")}}, {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "HOBBIT", "/")}}, {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "ELF", "/")}}, @@ -951,53 +951,53 @@ func TestWsSubscribe(t *testing.T) { assert.ErrorContains(t, err, "Currency pair not supported; Channel: ticker Pairs:", "Subscribing to an invalid pair should error correctly") assert.ErrorContains(t, err, "DWARF/HOBBIT", "Subscribing to an invalid pair should error correctly") assert.ErrorContains(t, err, "DWARF/ELF", "Subscribing to an invalid pair should error correctly") - require.Len(t, k.Websocket.GetSubscriptions(), 2, "Should have 2 subscriptions after mixed success/failures") + require.Len(t, e.Websocket.GetSubscriptions(), 2, "Should have 2 subscriptions after mixed success/failures") // Just failures - err = k.Subscribe(subscription.List{ + err = e.Subscribe(subscription.List{ {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "HOBBIT", "/")}}, {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "GOBLIN", "/")}}, }) assert.ErrorContains(t, err, "Currency pair not supported; Channel: ticker Pairs:", "Subscribing to an invalid pair should error correctly") assert.ErrorContains(t, err, "DWARF/HOBBIT", "Subscribing to an invalid pair should error correctly") assert.ErrorContains(t, err, "DWARF/GOBLIN", "Subscribing to an invalid pair should error correctly") - require.Len(t, k.Websocket.GetSubscriptions(), 2, "Should have 2 subscriptions after mixed success/failures") + require.Len(t, e.Websocket.GetSubscriptions(), 2, "Should have 2 subscriptions after mixed success/failures") // Just success - err = k.Subscribe(subscription.List{ + err = e.Subscribe(subscription.List{ {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("ETH", "XBT", "/")}}, {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("LTC", "ETH", "/")}}, }) assert.NoError(t, err, "Multiple successful subscriptions should not error") - subs = k.Websocket.GetSubscriptions() + subs = e.Websocket.GetSubscriptions() assert.Len(t, subs, 4, "Should have correct number of subscriptions") - err = k.Unsubscribe(subs[:1]) + err = e.Unsubscribe(subs[:1]) assert.NoError(t, err, "Simple Unsubscribe should succeed") - assert.Len(t, k.Websocket.GetSubscriptions(), 3, "Should have removed 1 channel") + assert.Len(t, e.Websocket.GetSubscriptions(), 3, "Should have removed 1 channel") - err = k.Unsubscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "WIZARD", "/")}, Key: 1337}}) + err = e.Unsubscribe(subscription.List{{Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "WIZARD", "/")}, Key: 1337}}) assert.ErrorIs(t, err, subscription.ErrNotFound, "Simple failing Unsubscribe should error NotFound") assert.ErrorContains(t, err, "DWARF/WIZARD", "Unsubscribing from an invalid pair should error correctly") - assert.Len(t, k.Websocket.GetSubscriptions(), 3, "Should not have removed any channels") + assert.Len(t, e.Websocket.GetSubscriptions(), 3, "Should not have removed any channels") - err = k.Unsubscribe(subscription.List{ + err = e.Unsubscribe(subscription.List{ subs[1], {Asset: asset.Spot, Channel: subscription.TickerChannel, Pairs: currency.Pairs{currency.NewPairWithDelimiter("DWARF", "EAGLE", "/")}, Key: 1338}, }) assert.ErrorIs(t, err, subscription.ErrNotFound, "Mixed failing Unsubscribe should error NotFound") assert.ErrorContains(t, err, "Channel: ticker Pairs: DWARF/EAGLE", "Unsubscribing from an invalid pair should error correctly") - subs = k.Websocket.GetSubscriptions() + subs = e.Websocket.GetSubscriptions() assert.Len(t, subs, 2, "Should have removed only 1 more channel") - err = k.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.NoError(t, err, "Unsubscribe multiple passing subscriptions should not error") - assert.Empty(t, k.Websocket.GetSubscriptions(), "Should have successfully removed all channels") + assert.Empty(t, e.Websocket.GetSubscriptions(), "Should have successfully removed all channels") for _, c := range []string{"ohlc", "ohlc-5"} { - err = k.Subscribe(subscription.List{{ + err = e.Subscribe(subscription.List{{ Asset: asset.Spot, Channel: c, Pairs: currency.Pairs{spotTestPair}, @@ -1009,18 +1009,18 @@ func TestWsSubscribe(t *testing.T) { // TestWsResubscribe tests websocket resubscription func TestWsResubscribe(t *testing.T) { - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "TestInstance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "TestInstance must not error") + testexch.SetupWs(t, e) - err := k.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.OrderbookChannel, Levels: 1000}}) + err := e.Subscribe(subscription.List{{Asset: asset.Spot, Channel: subscription.OrderbookChannel, Levels: 1000}}) require.NoError(t, err, "Subscribe must not error") - subs := k.Websocket.GetSubscriptions() + subs := e.Websocket.GetSubscriptions() require.Len(t, subs, 1, "Should add 1 Subscription") require.Equal(t, subscription.SubscribedState, subs[0].State(), "Subscription must be in a subscribed state") require.Eventually(t, func() bool { - b, e2 := k.Websocket.Orderbook.GetOrderbook(spotTestPair, asset.Spot) + b, e2 := e.Websocket.Orderbook.GetOrderbook(spotTestPair, asset.Spot) if e2 == nil { return !b.LastUpdated.IsZero() } @@ -1031,7 +1031,7 @@ func TestWsResubscribe(t *testing.T) { err = subs[0].SetState(subscription.UnsubscribingState) require.NoError(t, err) - err = k.Websocket.ResubscribeToChannel(k.Websocket.Conn, subs[0]) + err = e.Websocket.ResubscribeToChannel(e.Websocket.Conn, subs[0]) require.NoError(t, err, "Resubscribe must not error") require.Equal(t, subscription.SubscribedState, subs[0].State(), "subscription must be subscribed again") } @@ -1040,11 +1040,11 @@ func TestWsResubscribe(t *testing.T) { func TestWsOrderbookSub(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.SetupWs(t, e) - err := k.Subscribe(subscription.List{{ + err := e.Subscribe(subscription.List{{ Asset: asset.Spot, Channel: subscription.OrderbookChannel, Pairs: currency.Pairs{spotTestPair}, @@ -1052,14 +1052,14 @@ func TestWsOrderbookSub(t *testing.T) { }}) require.NoError(t, err, "Simple subscription must not error") - subs := k.Websocket.GetSubscriptions() + subs := e.Websocket.GetSubscriptions() require.Equal(t, 1, len(subs), "Must have 1 subscription channel") - err = k.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.NoError(t, err, "Unsubscribe should not error") - assert.Empty(t, k.Websocket.GetSubscriptions(), "Should have successfully removed all channels") + assert.Empty(t, e.Websocket.GetSubscriptions(), "Should have successfully removed all channels") - err = k.Subscribe(subscription.List{{ + err = e.Subscribe(subscription.List{{ Asset: asset.Spot, Channel: subscription.OrderbookChannel, Pairs: currency.Pairs{spotTestPair}, @@ -1072,11 +1072,11 @@ func TestWsOrderbookSub(t *testing.T) { func TestWsCandlesSub(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.SetupWs(t, e) - err := k.Subscribe(subscription.List{{ + err := e.Subscribe(subscription.List{{ Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: currency.Pairs{spotTestPair}, @@ -1084,14 +1084,14 @@ func TestWsCandlesSub(t *testing.T) { }}) require.NoError(t, err, "Simple subscription must not error") - subs := k.Websocket.GetSubscriptions() + subs := e.Websocket.GetSubscriptions() require.Equal(t, 1, len(subs), "Should add 1 Subscription") - err = k.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.NoError(t, err, "Unsubscribe should not error") - assert.Empty(t, k.Websocket.GetSubscriptions(), "Should have successfully removed all channels") + assert.Empty(t, e.Websocket.GetSubscriptions(), "Should have successfully removed all channels") - err = k.Subscribe(subscription.List{{ + err = e.Subscribe(subscription.List{{ Asset: asset.Spot, Channel: subscription.CandlesChannel, Pairs: currency.Pairs{spotTestPair}, @@ -1104,30 +1104,30 @@ func TestWsCandlesSub(t *testing.T) { func TestWsOwnTradesSub(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.SetupWs(t, e) - err := k.Subscribe(subscription.List{{Channel: subscription.MyTradesChannel, Authenticated: true}}) + err := e.Subscribe(subscription.List{{Channel: subscription.MyTradesChannel, Authenticated: true}}) assert.NoError(t, err, "Subsrcibing to ownTrades should not error") - subs := k.Websocket.GetSubscriptions() + subs := e.Websocket.GetSubscriptions() assert.Len(t, subs, 1, "Should add 1 Subscription") - err = k.Unsubscribe(subs) + err = e.Unsubscribe(subs) assert.NoError(t, err, "Unsubscribing an auth channel should not error") - assert.Empty(t, k.Websocket.GetSubscriptions(), "Should have successfully removed channel") + assert.Empty(t, e.Websocket.GetSubscriptions(), "Should have successfully removed channel") } // TestGenerateSubscriptions tests the subscriptions generated from configuration func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - pairs, err := k.GetEnabledPairs(asset.Spot) + pairs, err := e.GetEnabledPairs(asset.Spot) require.NoError(t, err, "GetEnabledPairs must not error") - require.False(t, k.Websocket.CanUseAuthenticatedEndpoints(), "Websocket must not be authenticated by default") + require.False(t, e.Websocket.CanUseAuthenticatedEndpoints(), "Websocket must not be authenticated by default") exp := subscription.List{ {Channel: subscription.TickerChannel}, {Channel: subscription.AllTradesChannel}, @@ -1139,29 +1139,29 @@ func TestGenerateSubscriptions(t *testing.T) { s.Asset = asset.Spot s.Pairs = pairs } - subs, err := k.generateSubscriptions() + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") testsubs.EqualLists(t, exp, subs) - k.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) exp = append(exp, subscription.List{ {Channel: subscription.MyOrdersChannel, QualifiedChannel: krakenWsOpenOrders}, {Channel: subscription.MyTradesChannel, QualifiedChannel: krakenWsOwnTrades}, }...) - subs, err = k.generateSubscriptions() + subs, err = e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") testsubs.EqualLists(t, exp, subs) } func TestGetWSToken(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, k) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") - testexch.SetupWs(t, k) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") + testexch.SetupWs(t, e) - resp, err := k.GetWebsocketToken(t.Context()) + resp, err := e.GetWebsocketToken(t.Context()) require.NoError(t, err, "GetWebsocketToken must not error") assert.NotEmpty(t, resp, "Token should not be empty") } @@ -1170,7 +1170,7 @@ func TestGetWSToken(t *testing.T) { func TestWsAddOrder(t *testing.T) { t.Parallel() - k := testexch.MockWsInstance[Kraken](t, curryWsMockUpgrader(t, mockWsServer)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + k := testexch.MockWsInstance[Exchange](t, curryWsMockUpgrader(t, mockWsServer)) require.True(t, k.IsWebsocketAuthenticationSupported(), "WS must be authenticated") id, err := k.wsAddOrder(t.Context(), &WsAddOrderRequest{ OrderType: order.Limit.Lower(), @@ -1186,7 +1186,7 @@ func TestWsAddOrder(t *testing.T) { func TestWsCancelOrders(t *testing.T) { t.Parallel() - k := testexch.MockWsInstance[Kraken](t, curryWsMockUpgrader(t, mockWsServer)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + k := testexch.MockWsInstance[Exchange](t, curryWsMockUpgrader(t, mockWsServer)) require.True(t, k.IsWebsocketAuthenticationSupported(), "WS must be authenticated") err := k.wsCancelOrders(t.Context(), []string{"RABBIT", "BATFISH", "SQUIRREL", "CATFISH", "MOUSE"}) @@ -1200,18 +1200,18 @@ func TestWsCancelOrders(t *testing.T) { } func TestWsCancelAllOrders(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, k, canManipulateRealOrders) - testexch.SetupWs(t, k) - _, err := k.wsCancelAllOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + _, err := e.wsCancelAllOrders(t.Context()) require.NoError(t, err, "wsCancelAllOrders must not error") } func TestWsHandleData(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") for _, l := range []int{10, 100} { - err := k.Websocket.AddSuccessfulSubscriptions(k.Websocket.Conn, &subscription.Subscription{ + err := e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, &subscription.Subscription{ Channel: subscription.OrderbookChannel, Pairs: currency.Pairs{spotTestPair}, Asset: asset.Spot, @@ -1219,37 +1219,37 @@ func TestWsHandleData(t *testing.T) { }) require.NoError(t, err, "AddSuccessfulSubscriptions must not error") } - testexch.FixtureToDataHandler(t, "testdata/wsHandleData.json", k.wsHandleData) + testexch.FixtureToDataHandler(t, "testdata/wsHandleData.json", e.wsHandleData) } func TestWSProcessTrades(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Test instance Setup must not error") - err := k.Websocket.AddSubscriptions(k.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{spotTestPair}, Channel: subscription.AllTradesChannel, Key: 18788}) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{Asset: asset.Spot, Pairs: currency.Pairs{spotTestPair}, Channel: subscription.AllTradesChannel, Key: 18788}) require.NoError(t, err, "AddSubscriptions must not error") - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", k.wsHandleData) - close(k.Websocket.DataHandler) + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) invalid := []any{"trades", []any{[]any{"95873.80000", "0.00051182", "1708731380.3791859"}}} rawBytes, err := json.Marshal(invalid) require.NoError(t, err, "Marshal must not error marshalling invalid trade data") pair := currency.NewPair(currency.XBT, currency.USD) - err = k.wsProcessTrades(json.RawMessage(rawBytes), pair) + err = e.wsProcessTrades(json.RawMessage(rawBytes), pair) require.ErrorContains(t, err, "error unmarshalling trade data") expJSON := []string{ `{"AssetType":"spot","CurrencyPair":"XBT/USD","Side":"BUY","Price":95873.80000,"Amount":0.00051182,"Timestamp":"2025-02-23T23:29:40.379186Z"}`, `{"AssetType":"spot","CurrencyPair":"XBT/USD","Side":"SELL","Price":95940.90000,"Amount":0.00011069,"Timestamp":"2025-02-24T02:01:12.853682Z"}`, } - require.Len(t, k.Websocket.DataHandler, len(expJSON), "Must see correct number of trades") - for resp := range k.Websocket.DataHandler { + require.Len(t, e.Websocket.DataHandler, len(expJSON), "Must see correct number of trades") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case trade.Data: - i := 1 - len(k.Websocket.DataHandler) - exp := trade.Data{Exchange: k.Name, CurrencyPair: spotTestPair} + i := 1 - len(e.Websocket.DataHandler) + exp := trade.Data{Exchange: e.Name, CurrencyPair: spotTestPair} require.NoErrorf(t, json.Unmarshal([]byte(expJSON[i]), &exp), "Must not error unmarshalling json %d: %s", i, expJSON[i]) require.Equalf(t, exp, v, "Trade [%d] must be correct", i) case error: @@ -1262,16 +1262,16 @@ func TestWSProcessTrades(t *testing.T) { func TestWsOpenOrders(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Test instance Setup must not error") - testexch.UpdatePairsOnce(t, k) - testexch.FixtureToDataHandler(t, "testdata/wsOpenTrades.json", k.wsHandleData) - close(k.Websocket.DataHandler) - assert.Len(t, k.Websocket.DataHandler, 7, "Should see 7 orders") - for resp := range k.Websocket.DataHandler { + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + testexch.UpdatePairsOnce(t, e) + testexch.FixtureToDataHandler(t, "testdata/wsOpenTrades.json", e.wsHandleData) + close(e.Websocket.DataHandler) + assert.Len(t, e.Websocket.DataHandler, 7, "Should see 7 orders") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case *order.Detail: - switch len(k.Websocket.DataHandler) { + switch len(e.Websocket.DataHandler) { case 6: assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID") assert.Equal(t, order.Limit, v.Type, "order type") @@ -1328,18 +1328,18 @@ func TestWsOpenOrders(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) + testexch.UpdatePairsOnce(t, e) - _, err := k.GetHistoricCandles(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now()) + _, err := e.GetHistoricCandles(t.Context(), spotTestPair, asset.Spot, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now()) assert.NoError(t, err, "GetHistoricCandles should not error") - _, err = k.GetHistoricCandles(t.Context(), futuresTestPair, asset.Futures, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now()) + _, err = e.GetHistoricCandles(t.Context(), futuresTestPair, asset.Futures, kline.OneHour, time.Now().Add(-time.Hour*12), time.Now()) assert.ErrorIs(t, err, asset.ErrNotSupported, "GetHistoricCandles should error with asset.ErrNotSupported") } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - _, err := k.GetHistoricCandlesExtended(t.Context(), futuresTestPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Minute*3), time.Now()) + _, err := e.GetHistoricCandlesExtended(t.Context(), futuresTestPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Minute*3), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "GetHistoricCandlesExtended should error correctly") } @@ -1352,24 +1352,24 @@ func TestFormatExchangeKlineInterval(t *testing.T) { {kline.OneMin, "1"}, {kline.OneDay, "1440"}, } { - assert.Equalf(t, tt.exp, k.FormatExchangeKlineInterval(tt.interval), "FormatExchangeKlineInterval should return correct output for %s", tt.interval.Short()) + assert.Equalf(t, tt.exp, e.FormatExchangeKlineInterval(tt.interval), "FormatExchangeKlineInterval should return correct output for %s", tt.interval.Short()) } } func TestGetRecentTrades(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) + testexch.UpdatePairsOnce(t, e) - _, err := k.GetRecentTrades(t.Context(), spotTestPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), spotTestPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades should not error") - _, err = k.GetRecentTrades(t.Context(), futuresTestPair, asset.Futures) + _, err = e.GetRecentTrades(t.Context(), futuresTestPair, asset.Futures) assert.NoError(t, err, "GetRecentTrades should not error") } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := k.GetHistoricTrades(t.Context(), spotTestPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), spotTestPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported, "GetHistoricTrades should error") } @@ -1423,21 +1423,21 @@ func TestChecksumCalculation(t *testing.T) { func TestGetCharts(t *testing.T) { t.Parallel() - resp, err := k.GetFuturesCharts(t.Context(), "1d", "spot", futuresTestPair, time.Time{}, time.Time{}) + resp, err := e.GetFuturesCharts(t.Context(), "1d", "spot", futuresTestPair, time.Time{}, time.Time{}) require.NoError(t, err) require.NotEmpty(t, resp.Candles) end := resp.Candles[0].Time.Time() - _, err = k.GetFuturesCharts(t.Context(), "1d", "spot", futuresTestPair, end.Add(-time.Hour*24*7), end) + _, err = e.GetFuturesCharts(t.Context(), "1d", "spot", futuresTestPair, end.Add(-time.Hour*24*7), end) require.NoError(t, err) } func TestGetFuturesTrades(t *testing.T) { t.Parallel() - _, err := k.GetFuturesTrades(t.Context(), futuresTestPair, time.Time{}, time.Time{}) + _, err := e.GetFuturesTrades(t.Context(), futuresTestPair, time.Time{}, time.Time{}) assert.NoError(t, err, "GetFuturesTrades should not error") - _, err = k.GetFuturesTrades(t.Context(), futuresTestPair, time.Now().Add(-time.Hour), time.Now()) + _, err = e.GetFuturesTrades(t.Context(), futuresTestPair, time.Now().Add(-time.Hour), time.Now()) assert.NoError(t, err, "GetFuturesTrades should not error") } @@ -1471,15 +1471,15 @@ var websocketGSTEUROrderbookUpdates = []string{ func TestWsOrderbookMax10Depth(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Setup Instance must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup Instance must not error") pairs := currency.Pairs{ currency.NewPairWithDelimiter("XDG", "USD", "/"), currency.NewPairWithDelimiter("LUNA", "EUR", "/"), currency.NewPairWithDelimiter("GST", "EUR", "/"), } for _, p := range pairs { - err := k.Websocket.AddSuccessfulSubscriptions(k.Websocket.Conn, &subscription.Subscription{ + err := e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, &subscription.Subscription{ Channel: subscription.OrderbookChannel, Pairs: currency.Pairs{p}, Asset: asset.Spot, @@ -1489,12 +1489,12 @@ func TestWsOrderbookMax10Depth(t *testing.T) { } for x := range websocketXDGUSDOrderbookUpdates { - err := k.wsHandleData(t.Context(), []byte(websocketXDGUSDOrderbookUpdates[x])) + err := e.wsHandleData(t.Context(), []byte(websocketXDGUSDOrderbookUpdates[x])) require.NoError(t, err, "wsHandleData must not error") } for x := range websocketLUNAEUROrderbookUpdates { - err := k.wsHandleData(t.Context(), []byte(websocketLUNAEUROrderbookUpdates[x])) + err := e.wsHandleData(t.Context(), []byte(websocketLUNAEUROrderbookUpdates[x])) // TODO: Known issue with LUNA pairs and big number float precision // storage and checksum calc. Might need to store raw strings as fields // in the orderbook.Level struct. @@ -1506,40 +1506,40 @@ func TestWsOrderbookMax10Depth(t *testing.T) { // This has less than 10 bids and still needs a checksum calc. for x := range websocketGSTEUROrderbookUpdates { - err := k.wsHandleData(t.Context(), []byte(websocketGSTEUROrderbookUpdates[x])) + err := e.wsHandleData(t.Context(), []byte(websocketGSTEUROrderbookUpdates[x])) require.NoError(t, err, "wsHandleData must not error") } } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := k.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) assert.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = k.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = k.GetFuturesContractDetails(t.Context(), asset.Futures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.Futures) assert.NoError(t, err, "GetFuturesContractDetails should not error") } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := k.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err := e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.USDTMarginedFutures, Pair: currency.NewBTCUSD(), IncludePredictedRate: true, }) assert.ErrorIs(t, err, asset.ErrNotSupported, "GetLatestFundingRates should error") - _, err = k.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, }) assert.NoError(t, err, "GetLatestFundingRates should not error") - err = k.CurrencyPairs.EnablePair(asset.Futures, futuresTestPair) + err = e.CurrencyPairs.EnablePair(asset.Futures, futuresTestPair) assert.Truef(t, err == nil || errors.Is(err, currency.ErrPairAlreadyEnabled), "EnablePair should not error: %s", err) - _, err = k.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ + _, err = e.GetLatestFundingRates(t.Context(), &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: futuresTestPair, IncludePredictedRate: true, @@ -1549,25 +1549,25 @@ func TestGetLatestFundingRates(t *testing.T) { func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := k.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) + is, err := e.IsPerpetualFutureCurrency(asset.Binary, currency.NewBTCUSDT()) assert.NoError(t, err) assert.False(t, is, "IsPerpetualFutureCurrency should return false for a binary asset") - is, err = k.IsPerpetualFutureCurrency(asset.Futures, currency.NewBTCUSDT()) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, currency.NewBTCUSDT()) assert.NoError(t, err) assert.False(t, is, "IsPerpetualFutureCurrency should return false for a non-perpetual future") - is, err = k.IsPerpetualFutureCurrency(asset.Futures, futuresTestPair) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, futuresTestPair) assert.NoError(t, err) assert.True(t, is, "IsPerpetualFutureCurrency should return true for a perpetual future") } func TestGetOpenInterest(t *testing.T) { t.Parallel() - k := new(Kraken) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(k), "Test instance Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") - _, err := k.GetOpenInterest(t.Context(), key.PairAsset{ + _, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.ETH.Item, Quote: currency.USDT.Item, Asset: asset.USDTMarginedFutures, @@ -1576,9 +1576,9 @@ func TestGetOpenInterest(t *testing.T) { cp1 := currency.NewPair(currency.PF, currency.NewCode("XBTUSD")) cp2 := currency.NewPair(currency.PF, currency.NewCode("ETHUSD")) - sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, k, asset.Futures, cp1, cp2) + sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, e, asset.Futures, cp1, cp2) - resp, err := k.GetOpenInterest(t.Context(), key.PairAsset{ + resp, err := e.GetOpenInterest(t.Context(), key.PairAsset{ Base: cp1.Base.Item, Quote: cp1.Quote.Item, Asset: asset.Futures, @@ -1586,7 +1586,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = k.GetOpenInterest(t.Context(), + resp, err = e.GetOpenInterest(t.Context(), key.PairAsset{ Base: cp1.Base.Item, Quote: cp1.Quote.Item, @@ -1600,7 +1600,7 @@ func TestGetOpenInterest(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = k.GetOpenInterest(t.Context()) + resp, err = e.GetOpenInterest(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, resp) } @@ -1620,14 +1620,14 @@ func curryWsMockUpgrader(tb testing.TB, h mockws.WsMockFunc) http.HandlerFunc { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, k) - for _, a := range k.GetAssetTypes(false) { - pairs, err := k.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) if len(pairs) == 0 { continue } require.NoErrorf(t, err, "cannot get pairs for %s", a) - resp, err := k.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) if a != asset.Spot && a != asset.Futures { assert.ErrorIs(t, err, asset.ErrNotSupported) continue @@ -1745,8 +1745,8 @@ func TestEnforceStandardChannelNames(t *testing.T) { func TestWebsocketAuthToken(t *testing.T) { t.Parallel() - k := new(Kraken) - k.setWebsocketAuthToken("meep") + e := new(Exchange) + e.setWebsocketAuthToken("meep") const n = 69 var wg sync.WaitGroup wg.Add(2 * n) @@ -1756,24 +1756,24 @@ func TestWebsocketAuthToken(t *testing.T) { go func() { defer wg.Done() <-start - k.setWebsocketAuthToken("69420") + e.setWebsocketAuthToken("69420") }() } for range n { go func() { defer wg.Done() <-start - k.websocketAuthToken() + e.websocketAuthToken() }() } close(start) wg.Wait() - assert.Equal(t, "69420", k.websocketAuthToken(), "websocketAuthToken should return correctly after concurrent reads and writes") + assert.Equal(t, "69420", e.websocketAuthToken(), "websocketAuthToken should return correctly after concurrent reads and writes") } func TestSetWebsocketAuthToken(t *testing.T) { t.Parallel() - k := new(Kraken) - k.setWebsocketAuthToken("69420") - assert.Equal(t, "69420", k.websocketAuthToken()) + e := new(Exchange) + e.setWebsocketAuthToken("69420") + assert.Equal(t, "69420", e.websocketAuthToken()) } diff --git a/exchanges/kraken/kraken_websocket.go b/exchanges/kraken/kraken_websocket.go index e559990a308..1f23fc2b69b 100644 --- a/exchanges/kraken/kraken_websocket.go +++ b/exchanges/kraken/kraken_websocket.go @@ -93,49 +93,49 @@ var defaultSubscriptions = subscription.List{ } // WsConnect initiates a websocket connection -func (k *Kraken) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !k.Websocket.IsEnabled() || !k.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := k.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } comms := make(chan websocket.Response) - k.Websocket.Wg.Add(2) - go k.wsReadData(ctx, comms) - go k.wsFunnelConnectionData(k.Websocket.Conn, comms) - - if k.IsWebsocketAuthenticationSupported() { - if authToken, err := k.GetWebsocketToken(ctx); err != nil { - k.Websocket.SetCanUseAuthenticatedEndpoints(false) - log.Errorf(log.ExchangeSys, "%s - authentication failed: %v\n", k.Name, err) + e.Websocket.Wg.Add(2) + go e.wsReadData(ctx, comms) + go e.wsFunnelConnectionData(e.Websocket.Conn, comms) + + if e.IsWebsocketAuthenticationSupported() { + if authToken, err := e.GetWebsocketToken(ctx); err != nil { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%s - authentication failed: %v\n", e.Name, err) } else { - if err := k.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil { - k.Websocket.SetCanUseAuthenticatedEndpoints(false) - log.Errorf(log.ExchangeSys, "%s - failed to connect to authenticated endpoint: %v\n", k.Name, err) + if err := e.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}); err != nil { + e.Websocket.SetCanUseAuthenticatedEndpoints(false) + log.Errorf(log.ExchangeSys, "%s - failed to connect to authenticated endpoint: %v\n", e.Name, err) } else { - k.setWebsocketAuthToken(authToken) - k.Websocket.SetCanUseAuthenticatedEndpoints(true) - k.Websocket.Wg.Add(1) - go k.wsFunnelConnectionData(k.Websocket.AuthConn, comms) - k.startWsPingHandler(k.Websocket.AuthConn) + e.setWebsocketAuthToken(authToken) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.Wg.Add(1) + go e.wsFunnelConnectionData(e.Websocket.AuthConn, comms) + e.startWsPingHandler(e.Websocket.AuthConn) } } } - k.startWsPingHandler(k.Websocket.Conn) + e.startWsPingHandler(e.Websocket.Conn) return nil } // wsFunnelConnectionData funnels both auth and public ws data into one manageable place -func (k *Kraken) wsFunnelConnectionData(ws websocket.Connection, comms chan websocket.Response) { - defer k.Websocket.Wg.Done() +func (e *Exchange) wsFunnelConnectionData(ws websocket.Connection, comms chan websocket.Response) { + defer e.Websocket.Wg.Done() for { resp := ws.ReadMessage() if resp.Raw == nil { @@ -146,35 +146,35 @@ func (k *Kraken) wsFunnelConnectionData(ws websocket.Connection, comms chan webs } // wsReadData receives and passes on websocket messages for processing -func (k *Kraken) wsReadData(ctx context.Context, comms chan websocket.Response) { - defer k.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context, comms chan websocket.Response) { + defer e.Websocket.Wg.Done() for { select { - case <-k.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: select { case resp := <-comms: - err := k.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { select { - case k.Websocket.DataHandler <- err: + case e.Websocket.DataHandler <- err: default: - log.Errorf(log.WebsocketMgr, "%s websocket handle data error: %v", k.Name, err) + log.Errorf(log.WebsocketMgr, "%s websocket handle data error: %v", e.Name, err) } } default: } return case resp := <-comms: - err := k.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - k.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } } -func (k *Kraken) wsHandleData(_ context.Context, respRaw []byte) error { +func (e *Exchange) wsHandleData(_ context.Context, respRaw []byte) error { if strings.HasPrefix(string(respRaw), "[") { var msg []json.RawMessage if err := json.Unmarshal(respRaw, &msg); err != nil { @@ -200,7 +200,7 @@ func (k *Kraken) wsHandleData(_ context.Context, respRaw []byte) error { pair = p } - return k.wsReadDataResponse(chanName, pair, msg) + return e.wsReadDataResponse(chanName, pair, msg) } event, err := jsonparser.GetString(respRaw, "event") @@ -209,11 +209,11 @@ func (k *Kraken) wsHandleData(_ context.Context, respRaw []byte) error { } if event == krakenWsSubscriptionStatus { // Must happen before IncomingWithData to avoid race - k.wsProcessSubStatus(respRaw) + e.wsProcessSubStatus(respRaw) } reqID, err := jsonparser.GetInt(respRaw, "reqid") - if err == nil && reqID != 0 && k.Websocket.Match.IncomingWithData(reqID, respRaw) { + if err == nil && reqID != 0 && e.Websocket.Match.IncomingWithData(reqID, respRaw) { return nil } @@ -228,9 +228,9 @@ func (k *Kraken) wsHandleData(_ context.Context, respRaw []byte) error { // All of these should have found a listener already return fmt.Errorf("%w: %s %v", websocket.ErrSignatureNotMatched, event, reqID) case krakenWsSystemStatus: - return k.wsProcessSystemStatus(respRaw) + return e.wsProcessSystemStatus(respRaw) default: - k.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ Message: fmt.Sprintf("%s: %s", websocket.UnhandledMessage, respRaw), } } @@ -239,7 +239,7 @@ func (k *Kraken) wsHandleData(_ context.Context, respRaw []byte) error { } // startWsPingHandler sets up a websocket ping handler to maintain a connection -func (k *Kraken) startWsPingHandler(conn websocket.Connection) { +func (e *Exchange) startWsPingHandler(conn websocket.Connection) { conn.SetupPingHandler(request.Unset, websocket.PingHandler{ Message: []byte(`{"event":"ping"}`), Delay: krakenWsPingDelay, @@ -248,46 +248,46 @@ func (k *Kraken) startWsPingHandler(conn websocket.Connection) { } // wsReadDataResponse classifies the WS response and sends to appropriate handler -func (k *Kraken) wsReadDataResponse(c string, pair currency.Pair, response []json.RawMessage) error { +func (e *Exchange) wsReadDataResponse(c string, pair currency.Pair, response []json.RawMessage) error { switch c { case krakenWsTicker: - return k.wsProcessTickers(response[1], pair) + return e.wsProcessTickers(response[1], pair) case krakenWsSpread: - return k.wsProcessSpread(response[1], pair) + return e.wsProcessSpread(response[1], pair) case krakenWsTrade: - return k.wsProcessTrades(response[1], pair) + return e.wsProcessTrades(response[1], pair) case krakenWsOwnTrades: - return k.wsProcessOwnTrades(response[0]) + return e.wsProcessOwnTrades(response[0]) case krakenWsOpenOrders: - return k.wsProcessOpenOrders(response[0]) + return e.wsProcessOpenOrders(response[0]) } channelType := strings.TrimRight(c, "-0123456789") switch channelType { case krakenWsOHLC: - return k.wsProcessCandle(c, response[1], pair) + return e.wsProcessCandle(c, response[1], pair) case krakenWsOrderbook: - return k.wsProcessOrderBook(c, response, pair) + return e.wsProcessOrderBook(c, response, pair) default: return fmt.Errorf("received unidentified data for subscription %s: %+v", c, response) } } -func (k *Kraken) wsProcessSystemStatus(respRaw []byte) error { +func (e *Exchange) wsProcessSystemStatus(respRaw []byte) error { var systemStatus wsSystemStatus if err := json.Unmarshal(respRaw, &systemStatus); err != nil { return fmt.Errorf("%s parsing system status: %s", err, respRaw) } if systemStatus.Status != "online" { - k.Websocket.DataHandler <- fmt.Errorf("system status not online: %v", systemStatus.Status) + e.Websocket.DataHandler <- fmt.Errorf("system status not online: %v", systemStatus.Status) } if systemStatus.Version > krakenWSSupportedVersion { - log.Warnf(log.ExchangeSys, "%v New version of Websocket API released. Was %v Now %v", k.Name, krakenWSSupportedVersion, systemStatus.Version) + log.Warnf(log.ExchangeSys, "%v New version of Websocket API released. Was %v Now %v", e.Name, krakenWSSupportedVersion, systemStatus.Version) } return nil } -func (k *Kraken) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { +func (e *Exchange) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { var result []map[string]*WsOwnTrade if err := json.Unmarshal(ownOrdersRaw, &result); err != nil { return err @@ -300,16 +300,16 @@ func (k *Kraken) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { for key, val := range result[0] { oSide, err := order.StringToOrderSide(val.Type) if err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } } oType, err := order.StringToOrderType(val.OrderType) if err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } @@ -318,14 +318,14 @@ func (k *Kraken) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { Price: val.Price, Amount: val.Vol, Fee: val.Fee, - Exchange: k.Name, + Exchange: e.Name, TID: key, Type: oType, Side: oSide, Timestamp: val.Time.Time(), } - k.Websocket.DataHandler <- &order.Detail{ - Exchange: k.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: val.OrderTransactionID, Trades: []order.TradeHistory{trade}, } @@ -335,7 +335,7 @@ func (k *Kraken) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { } // wsProcessOpenOrders processes open orders from the websocket response -func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { +func (e *Exchange) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { var result []map[string]*WsOpenOrder if err := json.Unmarshal(ownOrdersResp, &result); err != nil { return err @@ -344,7 +344,7 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { for r := range result { for key, val := range result[r] { d := &order.Detail{ - Exchange: k.Name, + Exchange: e.Name, OrderID: key, AverageExecutedPrice: val.AveragePrice, Amount: val.Volume, @@ -357,8 +357,8 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { if val.Status != "" { if s, err := order.StringToOrderStatus(val.Status); err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } @@ -372,8 +372,8 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { d.Side = order.Sell } else { if oSide, err := order.StringToOrderSide(val.Description.Type); err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } @@ -383,8 +383,8 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { } if oType, err := order.StringToOrderType(val.Description.OrderType); err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } @@ -393,16 +393,16 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { } if p, err := currency.NewPairFromString(val.Description.Pair); err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } } else { d.Pair = p - if d.AssetType, err = k.GetPairAssetType(p); err != nil { - k.Websocket.DataHandler <- order.ClassificationError{ - Exchange: k.Name, + if d.AssetType, err = e.GetPairAssetType(p); err != nil { + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: key, Err: err, } @@ -419,21 +419,21 @@ func (k *Kraken) wsProcessOpenOrders(ownOrdersResp json.RawMessage) error { // Note: Volume and ExecutedVolume are only populated when status is open d.RemainingAmount = val.Volume - val.ExecutedVolume } - k.Websocket.DataHandler <- d + e.Websocket.DataHandler <- d } } return nil } // wsProcessTickers converts ticker data and sends it to the datahandler -func (k *Kraken) wsProcessTickers(dataRaw json.RawMessage, pair currency.Pair) error { +func (e *Exchange) wsProcessTickers(dataRaw json.RawMessage, pair currency.Pair) error { var t wsTicker if err := json.Unmarshal(dataRaw, &t); err != nil { return fmt.Errorf("error unmarshalling ticker data: %w", err) } - k.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: k.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Ask: t.Ask[0].Float64(), Bid: t.Bid[0].Float64(), Close: t.Last[0].Float64(), @@ -448,14 +448,14 @@ func (k *Kraken) wsProcessTickers(dataRaw json.RawMessage, pair currency.Pair) e } // wsProcessSpread converts spread/orderbook data and sends it to the datahandler -func (k *Kraken) wsProcessSpread(rawData json.RawMessage, pair currency.Pair) error { +func (e *Exchange) wsProcessSpread(rawData json.RawMessage, pair currency.Pair) error { var data wsSpread if err := json.Unmarshal(rawData, &data); err != nil { return fmt.Errorf("error unmarshalling spread data: %w", err) } - if k.Verbose { + if e.Verbose { log.Debugf(log.ExchangeSys, "%s Spread data for %q received. Best bid: '%v' Best ask: '%v' Time: %q, Bid volume: '%v', Ask volume: '%v'", - k.Name, + e.Name, pair, data.Bid.Float64(), data.Ask.Float64(), @@ -467,9 +467,9 @@ func (k *Kraken) wsProcessSpread(rawData json.RawMessage, pair currency.Pair) er } // wsProcessTrades converts trade data and sends it to the datahandler -func (k *Kraken) wsProcessTrades(respRaw json.RawMessage, pair currency.Pair) error { - saveTradeData := k.IsSaveTradeDataEnabled() - tradeFeed := k.IsTradeFeedEnabled() +func (e *Exchange) wsProcessTrades(respRaw json.RawMessage, pair currency.Pair) error { + saveTradeData := e.IsSaveTradeDataEnabled() + tradeFeed := e.IsTradeFeedEnabled() if !saveTradeData && !tradeFeed { return nil } @@ -488,7 +488,7 @@ func (k *Kraken) wsProcessTrades(respRaw json.RawMessage, pair currency.Pair) er trades[i] = trade.Data{ AssetType: asset.Spot, CurrencyPair: pair, - Exchange: k.Name, + Exchange: e.Name, Price: t[i].Price.Float64(), Amount: t[i].Volume.Float64(), Timestamp: t[i].Time.Time().UTC(), @@ -497,7 +497,7 @@ func (k *Kraken) wsProcessTrades(respRaw json.RawMessage, pair currency.Pair) er } if tradeFeed { for i := range trades { - k.Websocket.DataHandler <- trades[i] + e.Websocket.DataHandler <- trades[i] } } if saveTradeData { @@ -515,7 +515,7 @@ func hasKey(raw json.RawMessage, key string) bool { } // wsProcessOrderBook handles both partial and full orderbook updates -func (k *Kraken) wsProcessOrderBook(c string, response []json.RawMessage, pair currency.Pair) error { +func (e *Exchange) wsProcessOrderBook(c string, response []json.RawMessage, pair currency.Pair) error { key := &subscription.Subscription{ Channel: c, Asset: asset.Spot, @@ -524,7 +524,7 @@ func (k *Kraken) wsProcessOrderBook(c string, response []json.RawMessage, pair c if err := fqChannelNameSub(key); err != nil { return err } - s := k.Websocket.GetSubscription(key) + s := e.Websocket.GetSubscription(key) if s == nil { return fmt.Errorf("%w: %s %s %s", subscription.ErrNotFound, asset.Spot, c, pair) } @@ -547,12 +547,12 @@ func (k *Kraken) wsProcessOrderBook(c string, response []json.RawMessage, pair c copy(update.Bids, update2.Bids) update.Checksum = update2.Checksum } - err := k.wsProcessOrderBookUpdate(pair, &update) + err := e.wsProcessOrderBookUpdate(pair, &update) if errors.Is(err, errInvalidChecksum) { - log.Debugf(log.Global, "%s Resubscribing to invalid %s orderbook", k.Name, pair) + log.Debugf(log.Global, "%s Resubscribing to invalid %s orderbook", e.Name, pair) go func() { - if e2 := k.Websocket.ResubscribeToChannel(k.Websocket.Conn, s); e2 != nil && !errors.Is(e2, subscription.ErrInStateAlready) { - log.Errorf(log.ExchangeSys, "%s resubscription failure for %v: %v", k.Name, pair, e2) + if e2 := e.Websocket.ResubscribeToChannel(e.Websocket.Conn, s); e2 != nil && !errors.Is(e2, subscription.ErrInStateAlready) { + log.Errorf(log.ExchangeSys, "%s resubscription failure for %v: %v", e.Name, pair, e2) } }() } @@ -563,15 +563,15 @@ func (k *Kraken) wsProcessOrderBook(c string, response []json.RawMessage, pair c if err := json.Unmarshal(response[1], &snapshot); err != nil { return fmt.Errorf("error unmarshalling orderbook snapshot: %w", err) } - return k.wsProcessOrderBookPartial(pair, &snapshot, key.Levels) + return e.wsProcessOrderBookPartial(pair, &snapshot, key.Levels) } // wsProcessOrderBookPartial creates a new orderbook entry for a given currency pair -func (k *Kraken) wsProcessOrderBookPartial(pair currency.Pair, obSnapshot *wsSnapshot, levels int) error { +func (e *Exchange) wsProcessOrderBookPartial(pair currency.Pair, obSnapshot *wsSnapshot, levels int) error { base := orderbook.Book{ Pair: pair, Asset: asset.Spot, - ValidateOrderbook: k.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(obSnapshot.Bids)), Asks: make(orderbook.Levels, len(obSnapshot.Asks)), MaxDepth: levels, @@ -605,12 +605,12 @@ func (k *Kraken) wsProcessOrderBookPartial(pair currency.Pair, obSnapshot *wsSna } } base.LastUpdated = highestLastUpdate - base.Exchange = k.Name - return k.Websocket.Orderbook.LoadSnapshot(&base) + base.Exchange = e.Name + return e.Websocket.Orderbook.LoadSnapshot(&base) } // wsProcessOrderBookUpdate updates an orderbook entry for a given currency pair -func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, wsUpdt *wsUpdate) error { +func (e *Exchange) wsProcessOrderBookUpdate(pair currency.Pair, wsUpdt *wsUpdate) error { obUpdate := orderbook.Update{ Asset: asset.Spot, Pair: pair, @@ -650,12 +650,12 @@ func (k *Kraken) wsProcessOrderBookUpdate(pair currency.Pair, wsUpdt *wsUpdate) } obUpdate.UpdateTime = highestLastUpdate - err := k.Websocket.Orderbook.Update(&obUpdate) + err := e.Websocket.Orderbook.Update(&obUpdate) if err != nil { return err } - book, err := k.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) + book, err := e.Websocket.Orderbook.GetOrderbook(pair, asset.Spot) if err != nil { return fmt.Errorf("cannot calculate websocket checksum: book not found for %s %s %w", pair, asset.Spot, err) } @@ -696,7 +696,7 @@ func trim(s string) string { } // wsProcessCandle converts candle data and sends it to the data handler -func (k *Kraken) wsProcessCandle(c string, resp json.RawMessage, pair currency.Pair) error { +func (e *Exchange) wsProcessCandle(c string, resp json.RawMessage, pair currency.Pair) error { var data wsCandle if err := json.Unmarshal(resp, &data); err != nil { return fmt.Errorf("error unmarshalling candle data: %w", err) @@ -709,11 +709,11 @@ func (k *Kraken) wsProcessCandle(c string, resp json.RawMessage, pair currency.P } interval := parts[1] - k.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ AssetType: asset.Spot, Pair: pair, Timestamp: time.Now(), - Exchange: k.Name, + Exchange: e.Name, StartTime: data.LastUpdateTime.Time(), CloseTime: data.LastUpdateTime.Time(), OpenPrice: data.Open.Float64(), @@ -727,24 +727,24 @@ func (k *Kraken) wsProcessCandle(c string, resp json.RawMessage, pair currency.P } // GetSubscriptionTemplate returns a subscription channel template -func (k *Kraken) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{"channelName": channelName}).Parse(subTplText) } -func (k *Kraken) generateSubscriptions() (subscription.List, error) { - return k.Features.Subscriptions.ExpandTemplates(k) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // Subscribe adds a channel subscription to the websocket -func (k *Kraken) Subscribe(in subscription.List) error { +func (e *Exchange) Subscribe(in subscription.List) error { ctx := context.TODO() - in, errs := in.ExpandTemplates(k) + in, errs := in.ExpandTemplates(e) // Collect valid new subs and add to websocket in Subscribing state subs := subscription.List{} for _, s := range in { if s.State() != subscription.ResubscribingState { - if err := k.Websocket.AddSubscriptions(k.Websocket.Conn, s); err != nil { + if err := e.Websocket.AddSubscriptions(e.Websocket.Conn, s); err != nil { errs = common.AppendError(errs, fmt.Errorf("%w; Channel: %s Pairs: %s", err, s.Channel, s.Pairs.Join())) continue } @@ -756,13 +756,13 @@ func (k *Kraken) Subscribe(in subscription.List) error { groupedSubs := subs.GroupPairs() errs = common.AppendError(errs, - k.ParallelChanOp(ctx, groupedSubs, func(ctx context.Context, s subscription.List) error { return k.manageSubs(ctx, krakenWsSubscribe, s) }, 1), + e.ParallelChanOp(ctx, groupedSubs, func(ctx context.Context, s subscription.List) error { return e.manageSubs(ctx, krakenWsSubscribe, s) }, 1), ) for _, s := range subs { if s.State() != subscription.SubscribedState { _ = s.SetState(subscription.InactiveState) - if err := k.Websocket.RemoveSubscriptions(k.Websocket.Conn, s); err != nil { + if err := e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s); err != nil { errs = common.AppendError(errs, fmt.Errorf("error removing failed subscription: %w; Channel: %s Pairs: %s", err, s.Channel, s.Pairs.Join())) } } @@ -772,13 +772,13 @@ func (k *Kraken) Subscribe(in subscription.List) error { } // Unsubscribe removes a channel subscriptions from the websocket -func (k *Kraken) Unsubscribe(keys subscription.List) error { +func (e *Exchange) Unsubscribe(keys subscription.List) error { ctx := context.TODO() var errs error // Make sure we have the concrete subscriptions, since we will change the state subs := make(subscription.List, 0, len(keys)) for _, key := range keys { - if s := k.Websocket.GetSubscription(key); s == nil { + if s := e.Websocket.GetSubscription(key); s == nil { errs = common.AppendError(errs, fmt.Errorf("%w; Channel: %s Pairs: %s", subscription.ErrNotFound, key.Channel, key.Pairs.Join())) } else { if s.State() != subscription.ResubscribingState { @@ -794,12 +794,12 @@ func (k *Kraken) Unsubscribe(keys subscription.List) error { subs = subs.GroupPairs() return common.AppendError(errs, - k.ParallelChanOp(ctx, subs, func(ctx context.Context, s subscription.List) error { return k.manageSubs(ctx, krakenWsUnsubscribe, s) }, 1), + e.ParallelChanOp(ctx, subs, func(ctx context.Context, s subscription.List) error { return e.manageSubs(ctx, krakenWsUnsubscribe, s) }, 1), ) } // manageSubs handles both websocket channel subscribe and unsubscribe -func (k *Kraken) manageSubs(ctx context.Context, op string, subs subscription.List) error { +func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.List) error { if len(subs) != 1 { return subscription.ErrBatchingNotSupported } @@ -813,7 +813,7 @@ func (k *Kraken) manageSubs(ctx context.Context, op string, subs subscription.Li reqFmt := currency.PairFormat{Uppercase: true, Delimiter: "/"} r := &WebsocketSubRequest{ Event: op, - RequestID: k.Websocket.Conn.GenerateMessageID(false), + RequestID: e.Websocket.Conn.GenerateMessageID(false), Subscription: WebsocketSubscriptionData{ Name: s.QualifiedChannel, Depth: s.Levels, @@ -826,10 +826,10 @@ func (k *Kraken) manageSubs(ctx context.Context, op string, subs subscription.Li r.Subscription.Interval = int(time.Duration(s.Interval).Minutes()) } - conn := k.Websocket.Conn + conn := e.Websocket.Conn if s.Authenticated { - r.Subscription.Token = k.websocketAuthToken() - conn = k.Websocket.AuthConn + r.Subscription.Token = e.websocketAuthToken() + conn = e.Websocket.AuthConn } resps, err := conn.SendMessageReturnResponses(ctx, request.Unset, r.RequestID, r, len(s.Pairs)) @@ -840,13 +840,13 @@ func (k *Kraken) manageSubs(ctx context.Context, op string, subs subscription.Li return fmt.Errorf("%w; Channel: %s Pair: %s", err, s.Channel, s.Pairs) } - return k.handleSubResps(s, resps, op) + return e.handleSubResps(s, resps, op) } // handleSubResps takes a collection of subscription responses from Kraken // We submit a subscription for N+ pairs, and we get N+ individual responses // Returns an error collection of unique errors and its pairs -func (k *Kraken) handleSubResps(s *subscription.Subscription, resps [][]byte, op string) error { +func (e *Exchange) handleSubResps(s *subscription.Subscription, resps [][]byte, op string) error { reqFmt := currency.PairFormat{Uppercase: true, Delimiter: "/"} errMap := map[string]error{} @@ -865,7 +865,7 @@ func (k *Kraken) handleSubResps(s *subscription.Subscription, resps [][]byte, op if err != nil { return fmt.Errorf("%w parsing WS pair; Channel: %s Pair: %s", err, s.Channel, pName) } - if err := k.getSubRespErr(resp, op); err != nil { + if err := e.getSubRespErr(resp, op); err != nil { // Remove the pair name from the error so we can group errors errStr := strings.TrimSpace(strings.TrimSuffix(err.Error(), pName)) if _, ok := errMap[errStr]; !ok { @@ -874,7 +874,7 @@ func (k *Kraken) handleSubResps(s *subscription.Subscription, resps [][]byte, op pairErrs[pair] = errMap[errStr] } else { delete(pairErrs, pair) - if k.Verbose && op == krakenWsSubscribe { + if e.Verbose && op == krakenWsSubscribe { subPairs = subPairs.Add(pair) } } @@ -891,16 +891,16 @@ func (k *Kraken) handleSubResps(s *subscription.Subscription, resps [][]byte, op errs = common.AppendError(errs, fmt.Errorf("%w; Channel: %s Pairs: %s", err, s.Channel, pairs.Join())) } - if k.Verbose && len(subPairs) > 0 { - log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s Pairs: %s", k.Name, s.Channel, subPairs.Join()) + if e.Verbose && len(subPairs) > 0 { + log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s Pairs: %s", e.Name, s.Channel, subPairs.Join()) } return errs } // getSubRespErr calls getRespErr and if there's no error from that ensures the status matches the sub operation -func (k *Kraken) getSubRespErr(resp []byte, op string) error { - if err := k.getRespErr(resp); err != nil { +func (e *Exchange) getSubRespErr(resp []byte, op string) error { + if err := e.getRespErr(resp); err != nil { return err } exp := op + "d" // subscribed or unsubscribed @@ -917,7 +917,7 @@ func (k *Kraken) getSubRespErr(resp []byte, op string) error { // If found it returns the errorMessage // It might log parsing errors about the nature of the error // If the error message is not defined it will return a wrapped errUnknownError -func (k *Kraken) getRespErr(resp []byte) error { +func (e *Exchange) getRespErr(resp []byte) error { event, err := jsonparser.GetUnsafeString(resp, "event") switch { case err != nil: @@ -931,7 +931,7 @@ func (k *Kraken) getRespErr(resp []byte) error { var msg string if msg, err = jsonparser.GetString(resp, "errorMessage"); err != nil { - log.Errorf(log.ExchangeSys, "%s error parsing WS errorMessage: %s from message: %s", k.Name, err, resp) + log.Errorf(log.ExchangeSys, "%s error parsing WS errorMessage: %s from message: %s", e.Name, err, resp) return fmt.Errorf("%w: error message did not contain errorMessage: %s", common.ErrUnknownError, resp) } return errors.New(msg) @@ -940,7 +940,7 @@ func (k *Kraken) getRespErr(resp []byte) error { // wsProcessSubStatus handles creating or removing Subscriptions as soon as we receive a message // It's job is to ensure that subscription state is kept correct sequentially between WS messages // If this responsibility was moved to Subscribe then we would have a race due to the channel connecting IncomingWithData -func (k *Kraken) wsProcessSubStatus(resp []byte) { +func (e *Exchange) wsProcessSubStatus(resp []byte) { pName, err := jsonparser.GetUnsafeString(resp, "pair") if err != nil { return @@ -953,7 +953,7 @@ func (k *Kraken) wsProcessSubStatus(resp []byte) { if err != nil { return } - if err = k.getRespErr(resp); err != nil { + if err = e.getRespErr(resp); err != nil { return } status, err := jsonparser.GetUnsafeString(resp, "status") @@ -969,23 +969,23 @@ func (k *Kraken) wsProcessSubStatus(resp []byte) { if err = fqChannelNameSub(key); err != nil { return } - s := k.Websocket.GetSubscription(&subscription.IgnoringAssetKey{Subscription: key}) + s := e.Websocket.GetSubscription(&subscription.IgnoringAssetKey{Subscription: key}) if s == nil { - log.Errorf(log.ExchangeSys, "%s %s Channel: %s Pairs: %s", k.Name, subscription.ErrNotFound, key.Channel, key.Pairs.Join()) + log.Errorf(log.ExchangeSys, "%s %s Channel: %s Pairs: %s", e.Name, subscription.ErrNotFound, key.Channel, key.Pairs.Join()) return } if status == krakenWsSubscribed { err = s.SetState(subscription.SubscribedState) } else if s.State() != subscription.ResubscribingState { // Do not remove a resubscribing sub which just unsubbed - err = k.Websocket.RemoveSubscriptions(k.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) if e2 := s.SetState(subscription.UnsubscribedState); e2 != nil { err = common.AppendError(err, e2) } } if err != nil { - log.Errorf(log.ExchangeSys, "%s %s Channel: %s Pairs: %s", k.Name, err, s.Channel, s.Pairs.Join()) + log.Errorf(log.ExchangeSys, "%s %s Channel: %s Pairs: %s", e.Name, err, s.Channel, s.Pairs.Join()) } } @@ -1036,14 +1036,14 @@ func fqChannelNameSub(s *subscription.Subscription) error { } // wsAddOrder creates an order, returned order ID if success -func (k *Kraken) wsAddOrder(ctx context.Context, req *WsAddOrderRequest) (string, error) { +func (e *Exchange) wsAddOrder(ctx context.Context, req *WsAddOrderRequest) (string, error) { if req == nil { return "", common.ErrNilPointer } - req.RequestID = k.Websocket.AuthConn.GenerateMessageID(false) + req.RequestID = e.Websocket.AuthConn.GenerateMessageID(false) req.Event = krakenWsAddOrder - req.Token = k.websocketAuthToken() - jsonResp, err := k.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req) + req.Token = e.websocketAuthToken() + jsonResp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, req.RequestID, req) if err != nil { return "", err } @@ -1055,8 +1055,8 @@ func (k *Kraken) wsAddOrder(ctx context.Context, req *WsAddOrderRequest) (string if resp.Status == "error" { return "", errors.New("AddOrder error: " + resp.ErrorMessage) } - k.Websocket.DataHandler <- &order.Detail{ - Exchange: k.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: resp.TransactionID, Status: order.New, } @@ -1065,12 +1065,12 @@ func (k *Kraken) wsAddOrder(ctx context.Context, req *WsAddOrderRequest) (string // wsCancelOrders cancels open orders concurrently // It does not use the multiple txId facility of the cancelOrder API because the errors are not specific -func (k *Kraken) wsCancelOrders(ctx context.Context, orderIDs []string) error { +func (e *Exchange) wsCancelOrders(ctx context.Context, orderIDs []string) error { errs := common.CollectErrors(len(orderIDs)) for _, id := range orderIDs { go func() { defer errs.Wg.Done() - errs.C <- k.wsCancelOrder(ctx, id) + errs.C <- e.wsCancelOrder(ctx, id) }() } @@ -1078,16 +1078,16 @@ func (k *Kraken) wsCancelOrders(ctx context.Context, orderIDs []string) error { } // wsCancelOrder cancels an open order -func (k *Kraken) wsCancelOrder(ctx context.Context, orderID string) error { - id := k.Websocket.AuthConn.GenerateMessageID(false) +func (e *Exchange) wsCancelOrder(ctx context.Context, orderID string) error { + id := e.Websocket.AuthConn.GenerateMessageID(false) req := WsCancelOrderRequest{ Event: krakenWsCancelOrder, - Token: k.websocketAuthToken(), + Token: e.websocketAuthToken(), TransactionIDs: []string{orderID}, RequestID: id, } - resp, err := k.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, id, req) + resp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, id, req) if err != nil { return fmt.Errorf("%w %s: %w", errCancellingOrder, orderID, err) } @@ -1109,15 +1109,15 @@ func (k *Kraken) wsCancelOrder(ctx context.Context, orderID string) error { // wsCancelAllOrders cancels all opened orders // Returns number (count param) of affected orders or 0 if no open orders found -func (k *Kraken) wsCancelAllOrders(ctx context.Context) (*WsCancelOrderResponse, error) { - id := k.Websocket.AuthConn.GenerateMessageID(false) +func (e *Exchange) wsCancelAllOrders(ctx context.Context) (*WsCancelOrderResponse, error) { + id := e.Websocket.AuthConn.GenerateMessageID(false) req := WsCancelOrderRequest{ Event: krakenWsCancelAll, - Token: k.websocketAuthToken(), + Token: e.websocketAuthToken(), RequestID: id, } - jsonResp, err := k.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, id, req) + jsonResp, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, request.Unset, id, req) if err != nil { return &WsCancelOrderResponse{}, err } @@ -1153,14 +1153,14 @@ const subTplText = ` ` // websocketAuthToken retrieves the current websocket session's auth token -func (k *Kraken) websocketAuthToken() string { - k.wsAuthMtx.RLock() - defer k.wsAuthMtx.RUnlock() - return k.wsAuthToken +func (e *Exchange) websocketAuthToken() string { + e.wsAuthMtx.RLock() + defer e.wsAuthMtx.RUnlock() + return e.wsAuthToken } -func (k *Kraken) setWebsocketAuthToken(token string) { - k.wsAuthMtx.Lock() - k.wsAuthToken = token - k.wsAuthMtx.Unlock() +func (e *Exchange) setWebsocketAuthToken(token string) { + e.wsAuthMtx.Lock() + e.wsAuthToken = token + e.wsAuthMtx.Unlock() } diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index c4b4653b513..8f114234634 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -34,13 +34,13 @@ import ( ) // SetDefaults sets current default settings -func (k *Kraken) SetDefaults() { - k.Name = "Kraken" - k.Enabled = true - k.Verbose = true - k.API.CredentialsValidator.RequiresKey = true - k.API.CredentialsValidator.RequiresSecret = true - k.API.CredentialsValidator.RequiresBase64DecodeSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Kraken" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresBase64DecodeSecret = true for _, a := range []asset.Item{asset.Spot, asset.Futures} { ps := currency.PairStore{ @@ -51,16 +51,16 @@ func (k *Kraken) SetDefaults() { if a == asset.Futures { ps.RequestFormat.Delimiter = currency.UnderscoreDelimiter } - if err := k.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", k.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } - if err := k.DisableAssetWebsocketSupport(asset.Futures); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", k.Name, asset.Futures, err) + if err := e.DisableAssetWebsocketSupport(asset.Futures); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset type websocket support: %s", e.Name, asset.Futures, err) } - k.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -151,14 +151,14 @@ func (k *Kraken) SetDefaults() { } var err error - k.Requester, err = request.New(k.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(request.NewBasicRateLimit(krakenRateInterval, krakenRequestRate, 1))) if err != nil { log.Errorln(log.ExchangeSys, err) } - k.API.Endpoints = k.NewEndpoints() - err = k.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: krakenAPIURL, exchange.RestFutures: krakenFuturesURL, exchange.WebsocketSpot: krakenWSURL, @@ -168,47 +168,47 @@ func (k *Kraken) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - k.Websocket = websocket.NewManager() - k.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - k.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - k.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets current exchange configuration -func (k *Kraken) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - k.SetEnabled(false) + e.SetEnabled(false) return nil } - err = k.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := k.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = k.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: krakenWSURL, RunningURL: wsRunningURL, - Connector: k.WsConnect, - Subscriber: k.Subscribe, - Unsubscriber: k.Unsubscribe, - GenerateSubscriptions: k.generateSubscriptions, - Features: &k.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{SortBuffer: true}, }) if err != nil { return err } - err = k.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + err = e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ RateLimit: request.NewWeightedRateLimitByDuration(50 * time.Millisecond), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -217,11 +217,11 @@ func (k *Kraken) Setup(exch *config.Exchange) error { return err } - wsRunningAuthURL, err := k.API.Endpoints.GetURL(exchange.WebsocketSpotSupplementary) + wsRunningAuthURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpotSupplementary) if err != nil { return err } - return k.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ RateLimit: request.NewWeightedRateLimitByDuration(50 * time.Millisecond), ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, @@ -231,10 +231,10 @@ func (k *Kraken) Setup(exch *config.Exchange) error { } // Bootstrap provides initialisation for an exchange -func (k *Kraken) Bootstrap(ctx context.Context) (continueBootstrap bool, err error) { +func (e *Exchange) Bootstrap(ctx context.Context) (continueBootstrap bool, err error) { continueBootstrap = true - if err = k.SeedAssets(ctx); err != nil { + if err = e.SeedAssets(ctx); err != nil { err = fmt.Errorf("failed to Seed Assets: %w", err) } @@ -242,20 +242,20 @@ func (k *Kraken) Bootstrap(ctx context.Context) (continueBootstrap bool, err err } // UpdateOrderExecutionLimits sets exchange execution order limits for an asset type -func (k *Kraken) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { if a != asset.Spot { return common.ErrNotYetImplemented } if !assetTranslator.Seeded() { - if err := k.SeedAssets(ctx); err != nil { + if err := e.SeedAssets(ctx); err != nil { return err } } - pairInfo, err := k.fetchSpotPairInfo(ctx) + pairInfo, err := e.fetchSpotPairInfo(ctx) if err != nil { - return fmt.Errorf("%s failed to load %s pair execution limits. Err: %s", k.Name, a, err) + return fmt.Errorf("%s failed to load %s pair execution limits. Err: %s", e.Name, a, err) } limits := make([]order.MinMaxLevel, 0, len(pairInfo)) @@ -269,17 +269,17 @@ func (k *Kraken) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) e }) } - if err := k.LoadLimits(limits); err != nil { - return fmt.Errorf("%s Error loading %s exchange limits: %w", k.Name, a, err) + if err := e.LoadLimits(limits); err != nil { + return fmt.Errorf("%s Error loading %s exchange limits: %w", e.Name, a, err) } return nil } -func (k *Kraken) fetchSpotPairInfo(ctx context.Context) (map[currency.Pair]*AssetPairs, error) { +func (e *Exchange) fetchSpotPairInfo(ctx context.Context) (map[currency.Pair]*AssetPairs, error) { pairs := make(map[currency.Pair]*AssetPairs) - pairInfo, err := k.GetAssetPairs(ctx, nil, "") + pairInfo, err := e.GetAssetPairs(ctx, nil, "") if err != nil { return pairs, err } @@ -292,7 +292,7 @@ func (k *Kraken) fetchSpotPairInfo(ctx context.Context) (map[currency.Pair]*Asse if base == "" { log.Warnf(log.ExchangeSys, "%s unable to lookup altname for base currency %s", - k.Name, + e.Name, info.Base) continue } @@ -300,7 +300,7 @@ func (k *Kraken) fetchSpotPairInfo(ctx context.Context) (map[currency.Pair]*Asse if quote == "" { log.Warnf(log.ExchangeSys, "%s unable to lookup altname for quote currency %s", - k.Name, + e.Name, info.Quote) continue } @@ -315,16 +315,16 @@ func (k *Kraken) fetchSpotPairInfo(ctx context.Context) (map[currency.Pair]*Asse } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (k *Kraken) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { pairs := currency.Pairs{} switch a { case asset.Spot: if !assetTranslator.Seeded() { - if err := k.SeedAssets(ctx); err != nil { + if err := e.SeedAssets(ctx); err != nil { return nil, err } } - pairInfo, err := k.fetchSpotPairInfo(ctx) + pairInfo, err := e.fetchSpotPairInfo(ctx) if err != nil { return pairs, err } @@ -333,7 +333,7 @@ func (k *Kraken) FetchTradablePairs(ctx context.Context, a asset.Item) (currency pairs = append(pairs, pair) } case asset.Futures: - symbols, err := k.GetInstruments(ctx) + symbols, err := e.GetInstruments(ctx) if err != nil { return nil, err } @@ -353,32 +353,32 @@ func (k *Kraken) FetchTradablePairs(ctx context.Context, a asset.Item) (currency } // UpdateTradablePairs updates the exchanges available pairs and stores them in the exchanges config -func (k *Kraken) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := k.GetAssetTypes(false) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.GetAssetTypes(false) for x := range assets { - pairs, err := k.FetchTradablePairs(ctx, assets[x]) + pairs, err := e.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } - err = k.UpdatePairs(pairs, assets[x], false, forceUpdate) + err = e.UpdatePairs(pairs, assets[x], false, forceUpdate) if err != nil { return err } } - return k.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { switch a { case asset.Spot: - tickers, err := k.GetTickers(ctx, "") + tickers, err := e.GetTickers(ctx, "") if err != nil { return err } for c, t := range tickers { var cp currency.Pair - cp, err = k.MatchSymbolWithAvailablePairs(c, a, false) + cp, err = e.MatchSymbolWithAvailablePairs(c, a, false) if err != nil { if !errors.Is(err, currency.ErrPairNotFound) { return err @@ -387,7 +387,7 @@ func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { if altName == "" { continue } - cp, err = k.MatchSymbolWithAvailablePairs(altName, a, false) + cp, err = e.MatchSymbolWithAvailablePairs(altName, a, false) if err != nil { continue } @@ -403,7 +403,7 @@ func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { Volume: t.Volume, Open: t.Open, Pair: cp, - ExchangeName: k.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -411,7 +411,7 @@ func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { } } case asset.Futures: - t, err := k.GetFuturesTickers(ctx) + t, err := e.GetFuturesTickers(ctx) if err != nil { return err } @@ -428,7 +428,7 @@ func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { MarkPrice: t.Tickers[x].MarkPrice, IndexPrice: t.Tickers[x].IndexPrice, Pair: t.Tickers[x].Symbol, - ExchangeName: k.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -442,30 +442,30 @@ func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (k *Kraken) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := k.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(k.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := k.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: k.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: k.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } switch assetType { case asset.Spot: - orderbookNew, err := k.GetDepth(ctx, p) + orderbookNew, err := e.GetDepth(ctx, p) if err != nil { return book, err } @@ -484,7 +484,7 @@ func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType } } case asset.Futures: - futuresOB, err := k.GetFuturesOrderbook(ctx, p) + futuresOB, err := e.GetFuturesOrderbook(ctx, p) if err != nil { return book, err } @@ -509,23 +509,23 @@ func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err := book.Process(); err != nil { return book, err } - return orderbook.Get(k.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Kraken exchange - to-do -func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var balances []account.Balance - info.Exchange = k.Name + info.Exchange = e.Name if !assetTranslator.Seeded() { - if err := k.SeedAssets(ctx); err != nil { + if err := e.SeedAssets(ctx); err != nil { return info, err } } switch assetType { case asset.Spot: - bal, err := k.GetBalance(ctx) + bal, err := e.GetBalance(ctx) if err != nil { return info, err } @@ -533,7 +533,7 @@ func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a translatedCurrency := assetTranslator.LookupAltName(key) if translatedCurrency == "" { log.Warnf(log.ExchangeSys, "%s unable to translate currency: %s\n", - k.Name, + e.Name, key) continue } @@ -549,7 +549,7 @@ func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a AssetType: assetType, }) case asset.Futures: - bal, err := k.GetFuturesAccountData(ctx) + bal, err := e.GetFuturesAccountData(ctx) if err != nil { return info, err } @@ -567,7 +567,7 @@ func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a }) } } - creds, err := k.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -579,13 +579,13 @@ func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (a // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (k *Kraken) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (k *Kraken) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - withdrawals, err := k.WithdrawStatus(ctx, c, "") +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + withdrawals, err := e.WithdrawStatus(ctx, c, "") if err != nil { return nil, err } @@ -607,16 +607,16 @@ func (k *Kraken) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ a } // GetRecentTrades returns the most recent trades for a currency and asset -func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = k.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var resp []trade.Data switch assetType { case asset.Spot: - tradeData, err := k.GetTrades(ctx, p, time.Time{}, 1000) + tradeData, err := e.GetTrades(ctx, p, time.Time{}, 1000) if err != nil { return nil, err } @@ -631,7 +631,7 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } resp = append(resp, trade.Data{ TID: strconv.FormatInt(trades[i].TradeID.Int64(), 10), - Exchange: k.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -642,7 +642,7 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } case asset.Futures: var tradeData *FuturesPublicTrades - tradeData, err = k.GetFuturesTrades(ctx, p, time.Time{}, time.Time{}) + tradeData, err = e.GetFuturesTrades(ctx, p, time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -653,7 +653,7 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } resp = append(resp, trade.Data{ TID: tradeData.Elements[i].UID, - Exchange: k.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: side, @@ -666,7 +666,7 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - err = k.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -676,13 +676,13 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } // GetHistoricTrades returns historic trade data within the timeframe provided -func (k *Kraken) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - err := s.Validate(k.GetTradingRequirements()) +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + err := s.Validate(e.GetTradingRequirements()) if err != nil { return nil, err } @@ -698,8 +698,8 @@ func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi case s.TimeInForce.Is(order.ImmediateOrCancel): timeInForce = "IOC" } - if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - orderID, err = k.wsAddOrder(ctx, &WsAddOrderRequest{ + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + orderID, err = e.wsAddOrder(ctx, &WsAddOrderRequest{ OrderType: s.Type.Lower(), OrderSide: s.Side.Lower(), Pair: s.Pair.Format(currency.PairFormat{Uppercase: true, Delimiter: "/"}).String(), // required pair format: ISO 4217-A3 @@ -712,7 +712,7 @@ func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi } } else { var response *AddOrderResponse - response, err = k.AddOrder(ctx, + response, err = e.AddOrder(ctx, s.Pair, s.Side.String(), s.Type.String(), @@ -735,7 +735,7 @@ func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi } case asset.Futures: var fOrder FuturesSendOrderData - fOrder, err = k.FuturesSendOrder(ctx, + fOrder, err = e.FuturesSendOrder(ctx, s.Type, s.Pair, s.Side.Lower(), @@ -768,24 +768,24 @@ func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submi } // ModifyOrder will allow of changing orderbook placement and limit to market conversion -func (k *Kraken) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (k *Kraken) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } switch o.AssetType { case asset.Spot: - if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - return k.wsCancelOrders(ctx, []string{o.OrderID}) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + return e.wsCancelOrders(ctx, []string{o.OrderID}) } - _, err := k.CancelExistingOrder(ctx, o.OrderID) + _, err := e.CancelExistingOrder(ctx, o.OrderID) return err case asset.Futures: - _, err := k.FuturesCancelOrder(ctx, o.OrderID, "") + _, err := e.FuturesCancelOrder(ctx, o.OrderID, "") if err != nil { return err } @@ -797,8 +797,8 @@ func (k *Kraken) CancelOrder(ctx context.Context, o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (k *Kraken) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { - if !k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { + if !e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { return nil, common.ErrFunctionNotSupported } @@ -810,12 +810,12 @@ func (k *Kraken) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*orde ordersList[i] = o[i].OrderID } - err := k.wsCancelOrders(ctx, ordersList) + err := e.wsCancelOrders(ctx, ordersList) return nil, err } // CancelAllOrders cancels all orders associated with a currency pair -func (k *Kraken) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { if err := req.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -824,8 +824,8 @@ func (k *Kraken) CancelAllOrders(ctx context.Context, req *order.Cancel) (order. } switch req.AssetType { case asset.Spot: - if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - resp, err := k.wsCancelAllOrders(ctx) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + resp, err := e.wsCancelAllOrders(ctx) if err != nil { return cancelAllOrdersResponse, err } @@ -835,23 +835,23 @@ func (k *Kraken) CancelAllOrders(ctx context.Context, req *order.Cancel) (order. } var emptyOrderOptions OrderInfoOptions - openOrders, err := k.GetOpenOrders(ctx, emptyOrderOptions) + openOrders, err := e.GetOpenOrders(ctx, emptyOrderOptions) if err != nil { return cancelAllOrdersResponse, err } for orderID := range openOrders.Open { var err error - if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - err = k.wsCancelOrders(ctx, []string{orderID}) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + err = e.wsCancelOrders(ctx, []string{orderID}) } else { - _, err = k.CancelExistingOrder(ctx, orderID) + _, err = e.CancelExistingOrder(ctx, orderID) } if err != nil { cancelAllOrdersResponse.Status[orderID] = err.Error() } } case asset.Futures: - cancelData, err := k.FuturesCancelAllOrders(ctx, req.Pair) + cancelData, err := e.FuturesCancelAllOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -863,15 +863,15 @@ func (k *Kraken) CancelAllOrders(ctx context.Context, req *order.Cancel) (order. } // GetOrderInfo returns information on a current open order -func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, assetType asset.Item) (*order.Detail, error) { - if err := k.CurrencyPairs.IsAssetEnabled(assetType); err != nil { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, assetType asset.Item) (*order.Detail, error) { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } var orderDetail order.Detail switch assetType { case asset.Spot: - resp, err := k.QueryOrdersInfo(ctx, + resp, err := e.QueryOrdersInfo(ctx, OrderInfoOptions{ Trades: true, }, orderID) @@ -888,12 +888,12 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa assetType = asset.UseDefault() } - avail, err := k.GetAvailablePairs(assetType) + avail, err := e.GetAvailablePairs(assetType) if err != nil { return nil, err } - format, err := k.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -910,7 +910,7 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa } status, err := order.StringToOrderStatus(orderInfo.Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", k.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } oType, err := order.StringToOrderType(orderInfo.Description.OrderType) if err != nil { @@ -930,7 +930,7 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa } orderDetail = order.Detail{ - Exchange: k.Name, + Exchange: e.Name, OrderID: orderID, Pair: p, Side: side, @@ -948,7 +948,7 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa AssetType: asset.Spot, } case asset.Futures: - orderInfo, err := k.FuturesGetFills(ctx, time.Time{}) + orderInfo, err := e.FuturesGetFills(ctx, time.Time{}) if err != nil { return nil, err } @@ -976,7 +976,7 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa Type: fillOrderType, Date: orderInfo.Fills[y].FillTime, Pair: pair, - Exchange: k.Name, + Exchange: e.Name, AssetType: asset.Futures, } } @@ -987,9 +987,9 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa } // GetDepositAddress returns a deposit address for a specified currency -func (k *Kraken) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { if chain == "" { - methods, err := k.GetDepositMethods(ctx, cryptocurrency.String()) + methods, err := e.GetDepositMethods(ctx, cryptocurrency.String()) if err != nil { return nil, err } @@ -999,10 +999,10 @@ func (k *Kraken) GetDepositAddress(ctx context.Context, cryptocurrency currency. chain = methods[0].Method } - depositAddr, err := k.GetCryptoDepositAddress(ctx, chain, cryptocurrency.String(), false) + depositAddr, err := e.GetCryptoDepositAddress(ctx, chain, cryptocurrency.String(), false) if err != nil { if strings.Contains(err.Error(), "no addresses returned") { - depositAddr, err = k.GetCryptoDepositAddress(ctx, chain, cryptocurrency.String(), true) + depositAddr, err = e.GetCryptoDepositAddress(ctx, chain, cryptocurrency.String(), true) if err != nil { return nil, err } @@ -1018,11 +1018,11 @@ func (k *Kraken) GetDepositAddress(ctx context.Context, cryptocurrency currency. // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal // Populate exchange.WithdrawRequest.TradePassword with withdrawal key name, as set up on your account -func (k *Kraken) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(ctx, + v, err := e.Withdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) @@ -1036,11 +1036,11 @@ func (k *Kraken) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReques // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (k *Kraken) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(ctx, + v, err := e.Withdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) @@ -1054,11 +1054,11 @@ func (k *Kraken) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdra // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (k *Kraken) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(ctx, + v, err := e.Withdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) @@ -1071,19 +1071,19 @@ func (k *Kraken) WithdrawFiatFundsToInternationalBank(ctx context.Context, withd } // GetFeeByType returns an estimate of fee based on type of transaction -func (k *Kraken) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !k.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return k.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1091,7 +1091,7 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque var orders []order.Detail switch req.AssetType { case asset.Spot: - resp, err := k.GetOpenOrders(ctx, OrderInfoOptions{}) + resp, err := e.GetOpenOrders(ctx, OrderInfoOptions{}) if err != nil { return nil, err } @@ -1101,12 +1101,12 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque assetType = asset.UseDefault() } - avail, err := k.GetAvailablePairs(assetType) + avail, err := e.GetAvailablePairs(assetType) if err != nil { return nil, err } - format, err := k.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -1125,14 +1125,14 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque var orderType order.Type orderType, err = order.StringToOrderType(resp.Open[i].Description.OrderType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", k.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders = append(orders, order.Detail{ OrderID: i, Amount: resp.Open[i].Volume, RemainingAmount: resp.Open[i].Volume - resp.Open[i].VolumeExecuted, ExecutedAmount: resp.Open[i].VolumeExecuted, - Exchange: k.Name, + Exchange: e.Name, Date: resp.Open[i].OpenTime.Time(), Price: resp.Open[i].Description.Price, Side: side, @@ -1148,17 +1148,17 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque if len(req.Pairs) > 0 { pairs = req.Pairs } else { - pairs, err = k.GetEnabledPairs(asset.Futures) + pairs, err = e.GetEnabledPairs(asset.Futures) if err != nil { return orders, err } } - activeOrders, err := k.FuturesOpenOrders(ctx) + activeOrders, err := e.FuturesOpenOrders(ctx) if err != nil { return orders, err } for i := range pairs { - fPair, err := k.FormatExchangeCurrency(pairs[i], asset.Futures) + fPair, err := e.FormatExchangeCurrency(pairs[i], asset.Futures) if err != nil { return orders, err } @@ -1182,7 +1182,7 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque Type: oType, Date: activeOrders.OpenOrders[a].ReceivedTime, Pair: fPair, - Exchange: k.Name, + Exchange: e.Name, AssetType: asset.Futures, Status: order.Open, }) @@ -1191,12 +1191,12 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, req.AssetType) } - return req.Filter(k.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { err := getOrdersRequest.Validate() if err != nil { return nil, err @@ -1217,17 +1217,17 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu assetType = asset.UseDefault() } - avail, err := k.GetAvailablePairs(assetType) + avail, err := e.GetAvailablePairs(assetType) if err != nil { return nil, err } - format, err := k.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } - resp, err := k.GetClosedOrders(ctx, req) + resp, err := e.GetClosedOrders(ctx, req) if err != nil { return nil, err } @@ -1243,16 +1243,16 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu var side order.Side side, err = order.StringToOrderSide(resp.Closed[i].Description.Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", k.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } status, err := order.StringToOrderStatus(resp.Closed[i].Status) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", k.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } var orderType order.Type orderType, err = order.StringToOrderType(resp.Closed[i].Description.OrderType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", k.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } detail := order.Detail{ OrderID: i, @@ -1261,7 +1261,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu RemainingAmount: resp.Closed[i].Volume - resp.Closed[i].VolumeExecuted, Cost: resp.Closed[i].Cost, CostAsset: p.Quote, - Exchange: k.Name, + Exchange: e.Name, Date: resp.Closed[i].OpenTime.Time(), CloseTime: resp.Closed[i].CloseTime.Time(), Price: resp.Closed[i].Description.Price, @@ -1280,13 +1280,13 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu if len(getOrdersRequest.Pairs) > 0 { pairs = getOrdersRequest.Pairs } else { - pairs, err = k.GetEnabledPairs(asset.Futures) + pairs, err = e.GetEnabledPairs(asset.Futures) if err != nil { return orders, err } } for p := range pairs { - orderHistory, err = k.FuturesRecentOrders(ctx, pairs[p]) + orderHistory, err = e.FuturesRecentOrders(ctx, pairs[p]) if err != nil { return orders, err } @@ -1313,7 +1313,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu Type: oType, Date: orderHistory.OrderEvents[o].Event.ExecutionEvent.Execution.TakerOrder.Timestamp, Side: oDirection, - Exchange: k.Name, + Exchange: e.Name, Pair: pairs[p], }) case orderHistory.OrderEvents[o].Event.OrderRejected.RecentOrder.UID != "": @@ -1337,7 +1337,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu Type: oType, Date: orderHistory.OrderEvents[o].Event.OrderRejected.RecentOrder.Timestamp, Side: oDirection, - Exchange: k.Name, + Exchange: e.Name, Pair: pairs[p], Status: order.Rejected, }) @@ -1362,7 +1362,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu Type: oType, Date: orderHistory.OrderEvents[o].Event.OrderCancelled.RecentOrder.Timestamp, Side: oDirection, - Exchange: k.Name, + Exchange: e.Name, Pair: pairs[p], Status: order.Cancelled, }) @@ -1387,7 +1387,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu Type: oType, Date: orderHistory.OrderEvents[o].Event.OrderPlaced.RecentOrder.Timestamp, Side: oDirection, - Exchange: k.Name, + Exchange: e.Name, Pair: pairs[p], }) default: @@ -1396,34 +1396,34 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu } } } - return getOrdersRequest.Filter(k.Name, orders), nil + return getOrdersRequest.Filter(e.Name, orders), nil } // AuthenticateWebsocket sends an authentication message to the websocket -func (k *Kraken) AuthenticateWebsocket(ctx context.Context) error { - resp, err := k.GetWebsocketToken(ctx) +func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error { + resp, err := e.GetWebsocketToken(ctx) if err != nil { return err } - k.setWebsocketAuthToken(resp) + e.setWebsocketAuthToken(resp) return nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (k *Kraken) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := k.UpdateAccountInfo(ctx, assetType) - return k.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (k *Kraken) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { return strconv.FormatFloat(in.Duration().Minutes(), 'f', -1, 64) } // FormatExchangeKlineIntervalFutures returns Interval to exchange formatted string -func (k *Kraken) FormatExchangeKlineIntervalFutures(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineIntervalFutures(in kline.Interval) string { switch in { case kline.OneDay: return "1d" @@ -1433,17 +1433,17 @@ func (k *Kraken) FormatExchangeKlineIntervalFutures(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (k *Kraken) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := k.GetKlineRequest(pair, a, interval, start, end, true) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, true) if err != nil { return nil, err } timeSeries := make([]kline.Candle, 0, req.Size()) switch a { case asset.Spot: - candles, err := k.GetOHLC(ctx, + candles, err := e.GetOHLC(ctx, req.RequestFormatted, - k.FormatExchangeKlineInterval(req.ExchangeInterval)) + e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } @@ -1470,7 +1470,7 @@ func (k *Kraken) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (k *Kraken) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } @@ -1514,10 +1514,9 @@ func compatibleFillOrderType(fillType string) (order.Type, error) { return resp, nil } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (k *Kraken) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - methods, err := k.GetDepositMethods(ctx, cryptocurrency.String()) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + methods, err := e.GetDepositMethods(ctx, cryptocurrency.String()) if err != nil { return nil, err } @@ -1530,8 +1529,8 @@ func (k *Kraken) GetAvailableTransferChains(ctx context.Context, cryptocurrency } // GetServerTime returns the current exchange server time. -func (k *Kraken) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - st, err := k.GetCurrentServerTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + st, err := e.GetCurrentServerTime(ctx) if err != nil { return time.Time{}, err } @@ -1539,14 +1538,14 @@ func (k *Kraken) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, er } // GetFuturesContractDetails returns details about futures contracts -func (k *Kraken) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !k.SupportsAsset(item) { + if !e.SupportsAsset(item) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } - result, err := k.GetInstruments(ctx) + result, err := e.GetInstruments(ctx) if err != nil { return nil, err } @@ -1573,27 +1572,27 @@ func (k *Kraken) GetFuturesContractDetails(ctx context.Context, item asset.Item) } usdIndex := strings.LastIndex(strings.ToLower(underlyingStr), "usd") if usdIndex <= 0 { - log.Warnf(log.ExchangeSys, "%v unable to find USD index in %v to process contract", k.Name, underlyingStr) + log.Warnf(log.ExchangeSys, "%v unable to find USD index in %v to process contract", e.Name, underlyingStr) continue } underlying, err = currency.NewPairFromStrings(underlyingStr[0:usdIndex], underlyingStr[usdIndex:]) if err != nil { return nil, err } - var s, e time.Time + var startTime, endTime time.Time if !result.Instruments[i].OpeningDate.IsZero() { - s = result.Instruments[i].OpeningDate + startTime = result.Instruments[i].OpeningDate } var ct futures.ContractType if result.Instruments[i].LastTradingTime.IsZero() || item == asset.PerpetualSwap { ct = futures.Perpetual } else { - e = result.Instruments[i].LastTradingTime + endTime = result.Instruments[i].LastTradingTime switch { // three day is used for generosity for contract date ranges - case e.Sub(s) <= kline.OneMonth.Duration()+kline.ThreeDay.Duration(): + case endTime.Sub(startTime) <= kline.OneMonth.Duration()+kline.ThreeDay.Duration(): ct = futures.Monthly - case e.Sub(s) <= kline.ThreeMonth.Duration()+kline.ThreeDay.Duration(): + case endTime.Sub(startTime) <= kline.ThreeMonth.Duration()+kline.ThreeDay.Duration(): ct = futures.Quarterly default: ct = futures.SemiAnnually @@ -1604,12 +1603,12 @@ func (k *Kraken) GetFuturesContractDetails(ctx context.Context, item asset.Item) contractSettlementType = futures.Inverse } resp[i] = futures.Contract{ - Exchange: k.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, Asset: item, - StartDate: s, - EndDate: e, + StartDate: startTime, + EndDate: endTime, SettlementType: contractSettlementType, IsActive: result.Instruments[i].Tradable, Type: ct, @@ -1619,7 +1618,7 @@ func (k *Kraken) GetFuturesContractDetails(ctx context.Context, item asset.Item) } // GetLatestFundingRates returns the latest funding rates data -func (k *Kraken) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -1627,14 +1626,14 @@ func (k *Kraken) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, r.Asset) } if !r.Pair.IsEmpty() { - if ok, err := k.CurrencyPairs.IsPairAvailable(r.Pair, r.Asset); err != nil { + if ok, err := e.CurrencyPairs.IsPairAvailable(r.Pair, r.Asset); err != nil { return nil, err } else if !ok { return nil, currency.ErrPairNotContainedInAvailablePairs } } - t, err := k.GetFuturesTickers(ctx) + t, err := e.GetFuturesTickers(ctx) if err != nil { return nil, err } @@ -1644,7 +1643,7 @@ func (k *Kraken) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates continue } var isPerp bool - isPerp, err = k.IsPerpetualFutureCurrency(r.Asset, t.Tickers[i].Symbol) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, t.Tickers[i].Symbol) if err != nil { return nil, err } @@ -1652,7 +1651,7 @@ func (k *Kraken) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates continue } rate := fundingrate.LatestRateResponse{ - Exchange: k.Name, + Exchange: e.Name, Asset: r.Asset, Pair: t.Tickers[i].Symbol, LatestRate: fundingrate.Rate{ @@ -1671,19 +1670,19 @@ func (k *Kraken) GetLatestFundingRates(ctx context.Context, r *fundingrate.Lates } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (k *Kraken) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { return cp.Base.Equal(currency.PF) && a == asset.Futures, nil } // GetOpenInterest returns the open interest rate for a given asset pair -func (k *Kraken) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range keys { if keys[i].Asset != asset.Futures { // avoid API calls or returning errors after a successful retrieval return nil, fmt.Errorf("%w %v %v", asset.ErrNotSupported, keys[i].Asset, keys[i].Pair()) } } - futuresTickersData, err := k.GetFuturesTickers(ctx) + futuresTickersData, err := e.GetFuturesTickers(ctx) if err != nil { return nil, err } @@ -1691,7 +1690,7 @@ func (k *Kraken) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([] for i := range futuresTickersData.Tickers { var p currency.Pair var isEnabled bool - p, isEnabled, err = k.MatchSymbolCheckEnabled(futuresTickersData.Tickers[i].Symbol.String(), asset.Futures, true) + p, isEnabled, err = e.MatchSymbolCheckEnabled(futuresTickersData.Tickers[i].Symbol.String(), asset.Futures, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -1710,7 +1709,7 @@ func (k *Kraken) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([] } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: k.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: asset.Futures, @@ -1722,8 +1721,8 @@ func (k *Kraken) GetOpenInterest(ctx context.Context, keys ...key.PairAsset) ([] } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (k *Kraken) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := k.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/kucoin/kucoin.go b/exchanges/kucoin/kucoin.go index 2ac8f027cd3..431b3ef3736 100644 --- a/exchanges/kucoin/kucoin.go +++ b/exchanges/kucoin/kucoin.go @@ -28,8 +28,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/types" ) -// Kucoin is the overarching type across this package -type Kucoin struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Kucoin +type Exchange struct { exchange.Base obm *orderbookManager } @@ -48,24 +48,24 @@ const ( // GetSymbols gets pairs details on the exchange // For market details see endpoint: https://www.kucoin.com/docs/rest/spot-trading/market-data/get-market-list -func (ku *Kucoin) GetSymbols(ctx context.Context, market string) ([]SymbolInfo, error) { +func (e *Exchange) GetSymbols(ctx context.Context, market string) ([]SymbolInfo, error) { params := url.Values{} if market != "" { params.Set(order.Market.Lower(), market) } var resp []SymbolInfo - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, symbolsEPL, common.EncodeURLValues("/v2/symbols", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, symbolsEPL, common.EncodeURLValues("/v2/symbols", params), &resp) } // GetTicker gets pair ticker information -func (ku *Kucoin) GetTicker(ctx context.Context, symbol string) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (*Ticker, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var resp *Ticker - err := ku.SendHTTPRequest(ctx, exchange.RestSpot, tickersEPL, common.EncodeURLValues("/v1/market/orderbook/level1", params), &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, tickersEPL, common.EncodeURLValues("/v1/market/orderbook/level1", params), &resp) if err != nil { return nil, err } @@ -76,26 +76,26 @@ func (ku *Kucoin) GetTicker(ctx context.Context, symbol string) (*Ticker, error) } // GetTickers gets all trading pair ticker information including 24h volume -func (ku *Kucoin) GetTickers(ctx context.Context) (*TickersResponse, error) { +func (e *Exchange) GetTickers(ctx context.Context) (*TickersResponse, error) { var resp *TickersResponse - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, allTickersEPL, "/v1/market/allTickers", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, allTickersEPL, "/v1/market/allTickers", &resp) } // Get24hrStats get the statistics of the specified pair in the last 24 hours -func (ku *Kucoin) Get24hrStats(ctx context.Context, symbol string) (*Stats24hrs, error) { +func (e *Exchange) Get24hrStats(ctx context.Context, symbol string) (*Stats24hrs, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var resp *Stats24hrs - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, statistics24HrEPL, common.EncodeURLValues("/v1/market/stats", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, statistics24HrEPL, common.EncodeURLValues("/v1/market/stats", params), &resp) } // GetMarketList get the transaction currency for the entire trading market -func (ku *Kucoin) GetMarketList(ctx context.Context) ([]string, error) { +func (e *Exchange) GetMarketList(ctx context.Context) ([]string, error) { var resp []string - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, marketListEPL, "/v1/markets", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, marketListEPL, "/v1/markets", &resp) } // processOB constructs an orderbook.Level instances from slice of numbers. @@ -126,14 +126,14 @@ func constructOrderbook(o *orderbookResponse) (*Orderbook, error) { } // GetPartOrderbook20 gets orderbook for a specified pair with depth 20 -func (ku *Kucoin) GetPartOrderbook20(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetPartOrderbook20(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o *orderbookResponse - err := ku.SendHTTPRequest(ctx, exchange.RestSpot, partOrderbook20EPL, common.EncodeURLValues("/v1/market/orderbook/level2_20", params), &o) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, partOrderbook20EPL, common.EncodeURLValues("/v1/market/orderbook/level2_20", params), &o) if err != nil { return nil, err } @@ -141,14 +141,14 @@ func (ku *Kucoin) GetPartOrderbook20(ctx context.Context, symbol string) (*Order } // GetPartOrderbook100 gets orderbook for a specified pair with depth 100 -func (ku *Kucoin) GetPartOrderbook100(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetPartOrderbook100(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o *orderbookResponse - err := ku.SendHTTPRequest(ctx, exchange.RestSpot, partOrderbook100EPL, common.EncodeURLValues("/v1/market/orderbook/level2_100", params), &o) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, partOrderbook100EPL, common.EncodeURLValues("/v1/market/orderbook/level2_100", params), &o) if err != nil { return nil, err } @@ -156,14 +156,14 @@ func (ku *Kucoin) GetPartOrderbook100(ctx context.Context, symbol string) (*Orde } // GetOrderbook gets full orderbook for a specified pair -func (ku *Kucoin) GetOrderbook(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o *orderbookResponse - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, fullOrderbookEPL, http.MethodGet, common.EncodeURLValues("/v3/market/orderbook/level2", params), nil, &o) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, fullOrderbookEPL, http.MethodGet, common.EncodeURLValues("/v3/market/orderbook/level2", params), nil, &o) if err != nil { return nil, err } @@ -171,18 +171,18 @@ func (ku *Kucoin) GetOrderbook(ctx context.Context, symbol string) (*Orderbook, } // GetTradeHistory gets trade history of the specified pair -func (ku *Kucoin) GetTradeHistory(ctx context.Context, symbol string) ([]Trade, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, symbol string) ([]Trade, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var resp []Trade - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, tradeHistoryEPL, common.EncodeURLValues("/v1/market/histories", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, tradeHistoryEPL, common.EncodeURLValues("/v1/market/histories", params), &resp) } // GetKlines gets kline of the specified pair -func (ku *Kucoin) GetKlines(ctx context.Context, symbol, period string, start, end time.Time) ([]Kline, error) { +func (e *Exchange) GetKlines(ctx context.Context, symbol, period string, start, end time.Time) ([]Kline, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -202,17 +202,17 @@ func (ku *Kucoin) GetKlines(ctx context.Context, symbol, period string, start, e params.Set("endAt", strconv.FormatInt(end.Unix(), 10)) } var resp []Kline - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, klinesEPL, common.EncodeURLValues("/v1/market/candles", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, klinesEPL, common.EncodeURLValues("/v1/market/candles", params), &resp) } // GetCurrenciesV3 the V3 of retrieving list of currencies -func (ku *Kucoin) GetCurrenciesV3(ctx context.Context) ([]CurrencyDetail, error) { +func (e *Exchange) GetCurrenciesV3(ctx context.Context) ([]CurrencyDetail, error) { var resp []CurrencyDetail - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, spotCurrenciesV3EPL, "/v3/currencies", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, spotCurrenciesV3EPL, "/v3/currencies", &resp) } // GetCurrencyDetailV3 V3 endpoint to gets currency detail using currency code and chain information. -func (ku *Kucoin) GetCurrencyDetailV3(ctx context.Context, ccy currency.Code, chain string) (*CurrencyDetail, error) { +func (e *Exchange) GetCurrencyDetailV3(ctx context.Context, ccy currency.Code, chain string) (*CurrencyDetail, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -221,11 +221,11 @@ func (ku *Kucoin) GetCurrencyDetailV3(ctx context.Context, ccy currency.Code, ch params.Set("chain", chain) } var resp *CurrencyDetail - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, spotCurrencyDetailEPL, common.EncodeURLValues("/v3/currencies/"+ccy.Upper().String(), params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, spotCurrencyDetailEPL, common.EncodeURLValues("/v3/currencies/"+ccy.Upper().String(), params), &resp) } // GetFiatPrice gets fiat prices of currencies, default base currency is USD -func (ku *Kucoin) GetFiatPrice(ctx context.Context, base, currencies string) (map[string]types.Number, error) { +func (e *Exchange) GetFiatPrice(ctx context.Context, base, currencies string) (map[string]types.Number, error) { params := url.Values{} if base != "" { params.Set("base", base) @@ -234,60 +234,60 @@ func (ku *Kucoin) GetFiatPrice(ctx context.Context, base, currencies string) (ma params.Set("currencies", currencies) } var resp map[string]types.Number - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, fiatPriceEPL, common.EncodeURLValues("/v1/prices", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, fiatPriceEPL, common.EncodeURLValues("/v1/prices", params), &resp) } // GetLeveragedTokenInfo returns leveraged token information -func (ku *Kucoin) GetLeveragedTokenInfo(ctx context.Context, ccy currency.Code) ([]LeveragedTokenInfo, error) { +func (e *Exchange) GetLeveragedTokenInfo(ctx context.Context, ccy currency.Code) ([]LeveragedTokenInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []LeveragedTokenInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, leveragedTokenInfoEPL, http.MethodGet, common.EncodeURLValues("/v3/etf/info", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, leveragedTokenInfoEPL, http.MethodGet, common.EncodeURLValues("/v3/etf/info", params), nil, &resp) } // GetMarkPrice gets index price of the specified pair -func (ku *Kucoin) GetMarkPrice(ctx context.Context, symbol string) (*MarkPrice, error) { +func (e *Exchange) GetMarkPrice(ctx context.Context, symbol string) (*MarkPrice, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *MarkPrice - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, getMarkPriceEPL, "/v1/mark-price/"+symbol+"/current", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMarkPriceEPL, "/v1/mark-price/"+symbol+"/current", &resp) } // GetAllMarginTradingPairsMarkPrices retrieves all margin trading pairs ticker mark price information -func (ku *Kucoin) GetAllMarginTradingPairsMarkPrices(ctx context.Context) ([]MarkPrice, error) { +func (e *Exchange) GetAllMarginTradingPairsMarkPrices(ctx context.Context) ([]MarkPrice, error) { var resp []MarkPrice - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, getAllMarginMarkPriceEPL, "/v3/mark-price/all-symbols", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAllMarginMarkPriceEPL, "/v3/mark-price/all-symbols", &resp) } // GetMarginConfiguration gets configure info of the margin -func (ku *Kucoin) GetMarginConfiguration(ctx context.Context) (*MarginConfiguration, error) { +func (e *Exchange) GetMarginConfiguration(ctx context.Context) (*MarginConfiguration, error) { var resp *MarginConfiguration - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, getMarginConfigurationEPL, "/v1/margin/config", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMarginConfigurationEPL, "/v1/margin/config", &resp) } // GetMarginAccount gets configure info of the margin -func (ku *Kucoin) GetMarginAccount(ctx context.Context) (*MarginAccounts, error) { +func (e *Exchange) GetMarginAccount(ctx context.Context) (*MarginAccounts, error) { var resp *MarginAccounts - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginAccountDetailEPL, http.MethodGet, "/v1/margin/account", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginAccountDetailEPL, http.MethodGet, "/v1/margin/account", nil, &resp) } // GetCrossMarginRiskLimitCurrencyConfig risk limit and currency configuration of cross margin account // isIsolated: true - isolated, false - cross ; default false -func (ku *Kucoin) GetCrossMarginRiskLimitCurrencyConfig(ctx context.Context, symbol string, ccy currency.Code) ([]CrossMarginRiskLimitCurrencyConfig, error) { +func (e *Exchange) GetCrossMarginRiskLimitCurrencyConfig(ctx context.Context, symbol string, ccy currency.Code) ([]CrossMarginRiskLimitCurrencyConfig, error) { var resp []CrossMarginRiskLimitCurrencyConfig - return resp, ku.getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx, false, symbol, ccy, &resp) + return resp, e.getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx, false, symbol, ccy, &resp) } // GetIsolatedMarginRiskLimitCurrencyConfig risk limit and currency configuration of cross isolated margin -func (ku *Kucoin) GetIsolatedMarginRiskLimitCurrencyConfig(ctx context.Context, symbol string, ccy currency.Code) ([]IsolatedMarginRiskLimitCurrencyConfig, error) { +func (e *Exchange) GetIsolatedMarginRiskLimitCurrencyConfig(ctx context.Context, symbol string, ccy currency.Code) ([]IsolatedMarginRiskLimitCurrencyConfig, error) { var resp []IsolatedMarginRiskLimitCurrencyConfig - return resp, ku.getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx, true, symbol, ccy, &resp) + return resp, e.getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx, true, symbol, ccy, &resp) } -func (ku *Kucoin) getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx context.Context, isIsolated bool, symbol string, ccy currency.Code, resp any) error { +func (e *Exchange) getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx context.Context, isIsolated bool, symbol string, ccy currency.Code, resp any) error { params := url.Values{} if isIsolated { params.Set("isIsolated", "true") @@ -298,11 +298,11 @@ func (ku *Kucoin) getCrossOrIsolatedMarginRiskLimitCurrencyConfig(ctx context.Co if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } - return ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, crossIsolatedMarginRiskLimitCurrencyConfigEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/currencies", params), nil, &resp) + return e.SendAuthHTTPRequest(ctx, exchange.RestSpot, crossIsolatedMarginRiskLimitCurrencyConfigEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/currencies", params), nil, &resp) } // PostMarginBorrowOrder used to post borrow order -func (ku *Kucoin) PostMarginBorrowOrder(ctx context.Context, arg *MarginBorrowParam) (*BorrowAndRepaymentOrderResp, error) { +func (e *Exchange) PostMarginBorrowOrder(ctx context.Context, arg *MarginBorrowParam) (*BorrowAndRepaymentOrderResp, error) { if *arg == (MarginBorrowParam{}) { return nil, common.ErrNilPointer } @@ -316,11 +316,11 @@ func (ku *Kucoin) PostMarginBorrowOrder(ctx context.Context, arg *MarginBorrowPa return nil, fmt.Errorf("%w , size = %f", order.ErrAmountBelowMin, arg.Size) } var resp *BorrowAndRepaymentOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, postMarginBorrowOrderEPL, http.MethodPost, "/v3/margin/borrow", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, postMarginBorrowOrderEPL, http.MethodPost, "/v3/margin/borrow", arg, &resp) } // GetMarginBorrowingHistory retrieves the borrowing orders for cross and isolated margin accounts -func (ku *Kucoin) GetMarginBorrowingHistory(ctx context.Context, ccy currency.Code, isIsolated bool, +func (e *Exchange) GetMarginBorrowingHistory(ctx context.Context, ccy currency.Code, isIsolated bool, symbol, orderNo string, startTime, endTime time.Time, currentPage, pageSize int64, @@ -353,11 +353,11 @@ func (ku *Kucoin) GetMarginBorrowingHistory(ctx context.Context, ccy currency.Co params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *BorrowRepayDetailResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginBorrowingHistoryEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/borrow", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginBorrowingHistoryEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/borrow", params), nil, &resp) } // PostRepayment used to initiate an application for the repayment of cross or isolated margin borrowing. -func (ku *Kucoin) PostRepayment(ctx context.Context, arg *RepayParam) (*BorrowAndRepaymentOrderResp, error) { +func (e *Exchange) PostRepayment(ctx context.Context, arg *RepayParam) (*BorrowAndRepaymentOrderResp, error) { if *arg == (RepayParam{}) { return nil, common.ErrNilPointer } @@ -368,11 +368,11 @@ func (ku *Kucoin) PostRepayment(ctx context.Context, arg *RepayParam) (*BorrowAn return nil, fmt.Errorf("%w , size = %f", order.ErrAmountBelowMin, arg.Size) } var resp *BorrowAndRepaymentOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, postMarginRepaymentEPL, http.MethodPost, "/v3/margin/repay", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, postMarginRepaymentEPL, http.MethodPost, "/v3/margin/repay", arg, &resp) } // GetCrossIsolatedMarginInterestRecords request via this endpoint to get the interest records of the cross/isolated margin lending -func (ku *Kucoin) GetCrossIsolatedMarginInterestRecords(ctx context.Context, isIsolated bool, symbol string, ccy currency.Code, startTime, endTime time.Time, currentPage, pageSize int64) (*MarginInterestRecords, error) { +func (e *Exchange) GetCrossIsolatedMarginInterestRecords(ctx context.Context, isIsolated bool, symbol string, ccy currency.Code, startTime, endTime time.Time, currentPage, pageSize int64) (*MarginInterestRecords, error) { params := url.Values{} if isIsolated { params.Set("isIsolated", "true") @@ -396,11 +396,11 @@ func (ku *Kucoin) GetCrossIsolatedMarginInterestRecords(ctx context.Context, isI params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *MarginInterestRecords - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getCrossIsolatedMarginInterestRecordsEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/interest", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getCrossIsolatedMarginInterestRecordsEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/interest", params), nil, &resp) } // GetRepaymentHistory retrieves the repayment orders for cross and isolated margin accounts. -func (ku *Kucoin) GetRepaymentHistory(ctx context.Context, ccy currency.Code, isIsolated bool, +func (e *Exchange) GetRepaymentHistory(ctx context.Context, ccy currency.Code, isIsolated bool, symbol, orderNo string, startTime, endTime time.Time, currentPage, pageSize int64, @@ -432,41 +432,41 @@ func (ku *Kucoin) GetRepaymentHistory(ctx context.Context, ccy currency.Code, is params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *BorrowRepayDetailResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginRepaymentHistoryEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/repay", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginRepaymentHistoryEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/repay", params), nil, &resp) } // GetIsolatedMarginPairConfig get the current isolated margin trading pair configuration -func (ku *Kucoin) GetIsolatedMarginPairConfig(ctx context.Context) ([]IsolatedMarginPairConfig, error) { +func (e *Exchange) GetIsolatedMarginPairConfig(ctx context.Context) ([]IsolatedMarginPairConfig, error) { var resp []IsolatedMarginPairConfig - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginPairConfigEPL, http.MethodGet, "/v1/isolated/symbols", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginPairConfigEPL, http.MethodGet, "/v1/isolated/symbols", nil, &resp) } // GetIsolatedMarginAccountInfo get all isolated margin accounts of the current user -func (ku *Kucoin) GetIsolatedMarginAccountInfo(ctx context.Context, balanceCurrency string) (*IsolatedMarginAccountInfo, error) { +func (e *Exchange) GetIsolatedMarginAccountInfo(ctx context.Context, balanceCurrency string) (*IsolatedMarginAccountInfo, error) { params := url.Values{} if balanceCurrency != "" { params.Set("balanceCurrency", balanceCurrency) } var resp *IsolatedMarginAccountInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginAccountInfoEPL, http.MethodGet, common.EncodeURLValues("/v1/isolated/accounts", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginAccountInfoEPL, http.MethodGet, common.EncodeURLValues("/v1/isolated/accounts", params), nil, &resp) } // GetSingleIsolatedMarginAccountInfo get single isolated margin accounts of the current user -func (ku *Kucoin) GetSingleIsolatedMarginAccountInfo(ctx context.Context, symbol string) (*AssetInfo, error) { +func (e *Exchange) GetSingleIsolatedMarginAccountInfo(ctx context.Context, symbol string) (*AssetInfo, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *AssetInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, singleIsolatedMarginAccountInfoEPL, http.MethodGet, "/v1/isolated/account/"+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, singleIsolatedMarginAccountInfoEPL, http.MethodGet, "/v1/isolated/account/"+symbol, nil, &resp) } // GetCurrentServerTime gets the server time -func (ku *Kucoin) GetCurrentServerTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetCurrentServerTime(ctx context.Context) (time.Time, error) { resp := struct { Timestamp types.Time `json:"data"` Error }{} - err := ku.SendHTTPRequest(ctx, exchange.RestSpot, currentServerTimeEPL, "/v1/timestamp", &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, currentServerTimeEPL, "/v1/timestamp", &resp) if err != nil { return time.Time{}, err } @@ -474,23 +474,23 @@ func (ku *Kucoin) GetCurrentServerTime(ctx context.Context) (time.Time, error) { } // GetServiceStatus gets the service status -func (ku *Kucoin) GetServiceStatus(ctx context.Context) (*ServiceStatus, error) { +func (e *Exchange) GetServiceStatus(ctx context.Context) (*ServiceStatus, error) { var resp *ServiceStatus - return resp, ku.SendHTTPRequest(ctx, exchange.RestSpot, serviceStatusEPL, "/v1/status", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, serviceStatusEPL, "/v1/status", &resp) } // --------------------------------------------- Spot High Frequency(HF) Pro Account --------------------------- // HFSpotPlaceOrder places a high frequency spot order // There are two types of orders: (limit) order: set price and quantity for the transaction. (market) order : set amount or quantity for the transaction. -func (ku *Kucoin) HFSpotPlaceOrder(ctx context.Context, arg *PlaceHFParam) (string, error) { - return ku.SendSpotHFPlaceOrder(ctx, arg, "/v1/hf/orders") +func (e *Exchange) HFSpotPlaceOrder(ctx context.Context, arg *PlaceHFParam) (string, error) { + return e.SendSpotHFPlaceOrder(ctx, arg, "/v1/hf/orders") } // SpotPlaceHFOrderTest order test endpoint, the request parameters and return parameters of this endpoint are exactly the same as the order endpoint, // and can be used to verify whether the signature is correct and other operations. -func (ku *Kucoin) SpotPlaceHFOrderTest(ctx context.Context, arg *PlaceHFParam) (string, error) { - return ku.SendSpotHFPlaceOrder(ctx, arg, "/v1/hf/orders/test") +func (e *Exchange) SpotPlaceHFOrderTest(ctx context.Context, arg *PlaceHFParam) (string, error) { + return e.SendSpotHFPlaceOrder(ctx, arg, "/v1/hf/orders/test") } // ValidatePlaceOrderParams validates an order placement parameters. @@ -519,7 +519,7 @@ func (a *PlaceHFParam) ValidatePlaceOrderParams() error { // SendSpotHFPlaceOrder sends a spot high-frequency order to the specified path // Use HFSpotPlaceOrder to place an order or SpotPlaceHFOrderTest to send a test order -func (ku *Kucoin) SendSpotHFPlaceOrder(ctx context.Context, arg *PlaceHFParam, path string) (string, error) { +func (e *Exchange) SendSpotHFPlaceOrder(ctx context.Context, arg *PlaceHFParam, path string) (string, error) { err := arg.ValidatePlaceOrderParams() if err != nil { return "", err @@ -527,21 +527,21 @@ func (ku *Kucoin) SendSpotHFPlaceOrder(ctx context.Context, arg *PlaceHFParam, p resp := &struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfPlaceOrderEPL, http.MethodPost, path, arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfPlaceOrderEPL, http.MethodPost, path, arg, &resp) } // SyncPlaceHFOrder this interface will synchronously return the order information after the order matching is completed. -func (ku *Kucoin) SyncPlaceHFOrder(ctx context.Context, arg *PlaceHFParam) (*SyncPlaceHFOrderResp, error) { +func (e *Exchange) SyncPlaceHFOrder(ctx context.Context, arg *PlaceHFParam) (*SyncPlaceHFOrderResp, error) { err := arg.ValidatePlaceOrderParams() if err != nil { return nil, err } var resp *SyncPlaceHFOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncPlaceOrderEPL, http.MethodPost, "/v1/hf/orders/sync", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncPlaceOrderEPL, http.MethodPost, "/v1/hf/orders/sync", arg, &resp) } // PlaceMultipleOrders endpoint supports sequential batch order placement from a single endpoint. A maximum of 5 orders can be placed simultaneously. -func (ku *Kucoin) PlaceMultipleOrders(ctx context.Context, args []PlaceHFParam) ([]PlaceOrderResp, error) { +func (e *Exchange) PlaceMultipleOrders(ctx context.Context, args []PlaceHFParam) ([]PlaceOrderResp, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } @@ -552,11 +552,11 @@ func (ku *Kucoin) PlaceMultipleOrders(ctx context.Context, args []PlaceHFParam) } } var resp []PlaceOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfMultipleOrdersEPL, http.MethodPost, "/v1/hf/orders/multi", &PlaceOrderParams{OrderList: args}, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfMultipleOrdersEPL, http.MethodPost, "/v1/hf/orders/multi", &PlaceOrderParams{OrderList: args}, &resp) } // SyncPlaceMultipleHFOrders this interface will synchronously return the order information after the order matching is completed -func (ku *Kucoin) SyncPlaceMultipleHFOrders(ctx context.Context, args []PlaceHFParam) ([]SyncPlaceHFOrderResp, error) { +func (e *Exchange) SyncPlaceMultipleHFOrders(ctx context.Context, args []PlaceHFParam) ([]SyncPlaceHFOrderResp, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } @@ -567,11 +567,11 @@ func (ku *Kucoin) SyncPlaceMultipleHFOrders(ctx context.Context, args []PlaceHFP } } var resp []SyncPlaceHFOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncPlaceMultipleHFOrdersEPL, http.MethodPost, "/v1/hf/orders/multi/sync", args, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncPlaceMultipleHFOrdersEPL, http.MethodPost, "/v1/hf/orders/multi/sync", args, &resp) } // ModifyHFOrder modifies a high frequency order. -func (ku *Kucoin) ModifyHFOrder(ctx context.Context, arg *ModifyHFOrderParam) (string, error) { +func (e *Exchange) ModifyHFOrder(ctx context.Context, arg *ModifyHFOrderParam) (string, error) { if *arg == (ModifyHFOrderParam{}) { return "", common.ErrNilPointer } @@ -581,11 +581,11 @@ func (ku *Kucoin) ModifyHFOrder(ctx context.Context, arg *ModifyHFOrderParam) (s resp := &struct { NewOrderID string `json:"newOrderId"` }{} - return resp.NewOrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfModifyOrderEPL, http.MethodPost, "/v1/hf/orders/alter", arg, &resp) + return resp.NewOrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfModifyOrderEPL, http.MethodPost, "/v1/hf/orders/alter", arg, &resp) } // CancelHFOrder used to cancel a high-frequency order by orderId. -func (ku *Kucoin) CancelHFOrder(ctx context.Context, orderID, symbol string) (string, error) { +func (e *Exchange) CancelHFOrder(ctx context.Context, orderID, symbol string) (string, error) { if orderID == "" { return "", order.ErrOrderIDNotSet } @@ -595,36 +595,36 @@ func (ku *Kucoin) CancelHFOrder(ctx context.Context, orderID, symbol string) (st resp := &struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelHFOrderEPL, http.MethodDelete, "/v1/hf/orders/"+orderID+symbolQuery+symbol, nil, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelHFOrderEPL, http.MethodDelete, "/v1/hf/orders/"+orderID+symbolQuery+symbol, nil, &resp) } // SyncCancelHFOrder this interface will synchronously return the order information after the order canceling is completed. -func (ku *Kucoin) SyncCancelHFOrder(ctx context.Context, orderID, symbol string) (*SyncCancelHFOrderResp, error) { +func (e *Exchange) SyncCancelHFOrder(ctx context.Context, orderID, symbol string) (*SyncCancelHFOrderResp, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } - return ku.SendSyncCancelHFOrder(ctx, orderID, symbol, "/v1/hf/orders/sync/") + return e.SendSyncCancelHFOrder(ctx, orderID, symbol, "/v1/hf/orders/sync/") } // SyncCancelHFOrderByClientOrderID this interface will synchronously return the order information after the order canceling is completed. -func (ku *Kucoin) SyncCancelHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*SyncCancelHFOrderResp, error) { +func (e *Exchange) SyncCancelHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*SyncCancelHFOrderResp, error) { if clientOrderID == "" { return nil, order.ErrClientOrderIDMustBeSet } - return ku.SendSyncCancelHFOrder(ctx, clientOrderID, symbol, "/v1/hf/orders/sync/client-order/") + return e.SendSyncCancelHFOrder(ctx, clientOrderID, symbol, "/v1/hf/orders/sync/client-order/") } // SendSyncCancelHFOrder sends a sync-cancel high-frequency order by order ID or client supplied order ID. -func (ku *Kucoin) SendSyncCancelHFOrder(ctx context.Context, id, symbol, path string) (*SyncCancelHFOrderResp, error) { +func (e *Exchange) SendSyncCancelHFOrder(ctx context.Context, id, symbol, path string) (*SyncCancelHFOrderResp, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *SyncCancelHFOrderResp - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncCancelOrderEPL, http.MethodDelete, path+id+symbolQuery+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSyncCancelOrderEPL, http.MethodDelete, path+id+symbolQuery+symbol, nil, &resp) } // CancelHFOrderByClientOrderID sends out a request to cancel a high-frequency order using clientOid. -func (ku *Kucoin) CancelHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (string, error) { +func (e *Exchange) CancelHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (string, error) { if clientOrderID == "" { return "", order.ErrClientOrderIDMustBeSet } @@ -634,11 +634,11 @@ func (ku *Kucoin) CancelHFOrderByClientOrderID(ctx context.Context, clientOrderI resp := &struct { ClientOrderID string `json:"clientOid"` }{} - return resp.ClientOrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelOrderByClientOrderIDEPL, http.MethodDelete, "/v1/hf/orders/client-order/"+clientOrderID+symbolQuery+symbol, nil, &resp) + return resp.ClientOrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelOrderByClientOrderIDEPL, http.MethodDelete, "/v1/hf/orders/client-order/"+clientOrderID+symbolQuery+symbol, nil, &resp) } // CancelSpecifiedNumberHFOrdersByOrderID cancel the specified quantity of the order according to the orderId. -func (ku *Kucoin) CancelSpecifiedNumberHFOrdersByOrderID(ctx context.Context, orderID, symbol string, cancelSize float64) (*CancelOrderByNumberResponse, error) { +func (e *Exchange) CancelSpecifiedNumberHFOrdersByOrderID(ctx context.Context, orderID, symbol string, cancelSize float64) (*CancelOrderByNumberResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -652,43 +652,43 @@ func (ku *Kucoin) CancelSpecifiedNumberHFOrdersByOrderID(ctx context.Context, or params.Set("symbol", symbol) params.Set("cancelSize", strconv.FormatFloat(cancelSize, 'f', -1, 64)) var resp *CancelOrderByNumberResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelSpecifiedNumberHFOrdersByOrderIDEPL, http.MethodDelete, common.EncodeURLValues("/v1/hf/orders/cancel/"+orderID, params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelSpecifiedNumberHFOrdersByOrderIDEPL, http.MethodDelete, common.EncodeURLValues("/v1/hf/orders/cancel/"+orderID, params), nil, &resp) } // CancelAllHFOrdersBySymbol cancel all open high-frequency orders -func (ku *Kucoin) CancelAllHFOrdersBySymbol(ctx context.Context, symbol string) (string, error) { +func (e *Exchange) CancelAllHFOrdersBySymbol(ctx context.Context, symbol string) (string, error) { if symbol == "" { return "", currency.ErrSymbolStringEmpty } var resp string - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelAllOrdersBySymbolEPL, http.MethodDelete, "/v1/hf/orders?symbol="+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelAllOrdersBySymbolEPL, http.MethodDelete, "/v1/hf/orders?symbol="+symbol, nil, &resp) } // CancelAllHFOrders cancels all high-frequency orders for all symbols -func (ku *Kucoin) CancelAllHFOrders(ctx context.Context) (*CancelAllHFOrdersResponse, error) { +func (e *Exchange) CancelAllHFOrders(ctx context.Context) (*CancelAllHFOrdersResponse, error) { var resp *CancelAllHFOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelAllOrdersEPL, http.MethodDelete, "/v1/hf/orders/cancelAll", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCancelAllOrdersEPL, http.MethodDelete, "/v1/hf/orders/cancelAll", nil, &resp) } // GetActiveHFOrders retrieves all high-frequency active orders -func (ku *Kucoin) GetActiveHFOrders(ctx context.Context, symbol string) ([]OrderDetail, error) { +func (e *Exchange) GetActiveHFOrders(ctx context.Context, symbol string) ([]OrderDetail, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp []OrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfGetAllActiveOrdersEPL, http.MethodGet, "/v1/hf/orders/active?symbol="+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfGetAllActiveOrdersEPL, http.MethodGet, "/v1/hf/orders/active?symbol="+symbol, nil, &resp) } // GetSymbolsWithActiveHFOrderList retrieves all trading pairs that the user has active orders -func (ku *Kucoin) GetSymbolsWithActiveHFOrderList(ctx context.Context) ([]string, error) { +func (e *Exchange) GetSymbolsWithActiveHFOrderList(ctx context.Context) ([]string, error) { resp := &struct { Symbols []string `json:"symbols"` }{} - return resp.Symbols, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSymbolsWithActiveOrdersEPL, http.MethodGet, "/v1/hf/orders/active/symbols", nil, &resp) + return resp.Symbols, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfSymbolsWithActiveOrdersEPL, http.MethodGet, "/v1/hf/orders/active/symbols", nil, &resp) } // GetHFCompletedOrderList obtains a list of filled HF orders and returns paginated data. The returned data is sorted in descending order based on the latest order update times. -func (ku *Kucoin) GetHFCompletedOrderList(ctx context.Context, symbol, side, orderType, lastID string, startAt, endAt time.Time, limit int64) (*CompletedHFOrder, error) { +func (e *Exchange) GetHFCompletedOrderList(ctx context.Context, symbol, side, orderType, lastID string, startAt, endAt time.Time, limit int64) (*CompletedHFOrder, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -713,7 +713,7 @@ func (ku *Kucoin) GetHFCompletedOrderList(ctx context.Context, symbol, side, ord params.Set(order.Limit.Lower(), strconv.FormatInt(limit, 10)) } var resp *CompletedHFOrder - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCompletedOrderListEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/orders/done", params), nil, &resp) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfCompletedOrderListEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/orders/done", params), nil, &resp) if err != nil { return nil, err } @@ -725,17 +725,17 @@ func (ku *Kucoin) GetHFCompletedOrderList(ctx context.Context, symbol, side, ord // GetHFOrderDetailsByOrderID obtain information for a single HF order using the order id. // If the order is not an active order, you can only get data within the time range of 3 _ 24 hours (ie: from the current time to 3 _ 24 hours ago). -func (ku *Kucoin) GetHFOrderDetailsByOrderID(ctx context.Context, orderID, symbol string) (*OrderDetail, error) { - return ku.GetHFOrderDetailsByID(ctx, orderID, symbol, "/v1/hf/orders/") +func (e *Exchange) GetHFOrderDetailsByOrderID(ctx context.Context, orderID, symbol string) (*OrderDetail, error) { + return e.GetHFOrderDetailsByID(ctx, orderID, symbol, "/v1/hf/orders/") } // GetHFOrderDetailsByClientOrderID used to obtain information about a single order using clientOid. If the order does not exist, then there will be a prompt saying that the order does not exist. -func (ku *Kucoin) GetHFOrderDetailsByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*OrderDetail, error) { - return ku.GetHFOrderDetailsByID(ctx, clientOrderID, symbol, "/v1/hf/orders/client-order/") +func (e *Exchange) GetHFOrderDetailsByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*OrderDetail, error) { + return e.GetHFOrderDetailsByID(ctx, clientOrderID, symbol, "/v1/hf/orders/client-order/") } // GetHFOrderDetailsByID retrieves a high-frequency order by order ID or client supplied ID. -func (ku *Kucoin) GetHFOrderDetailsByID(ctx context.Context, orderID, symbol, path string) (*OrderDetail, error) { +func (e *Exchange) GetHFOrderDetailsByID(ctx context.Context, orderID, symbol, path string) (*OrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -743,7 +743,7 @@ func (ku *Kucoin) GetHFOrderDetailsByID(ctx context.Context, orderID, symbol, pa return nil, currency.ErrSymbolStringEmpty } var resp *OrderDetail - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfOrderDetailByOrderIDEPL, http.MethodGet, path+orderID+symbolQuery+symbol, nil, &resp) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfOrderDetailByOrderIDEPL, http.MethodGet, path+orderID+symbolQuery+symbol, nil, &resp) if err != nil { return nil, err } @@ -756,7 +756,7 @@ func (ku *Kucoin) GetHFOrderDetailsByID(ctx context.Context, orderID, symbol, pa // AutoCancelHFOrderSetting automatically cancel all orders of the set trading pair after the specified time. // If this interface is not called again for renewal or cancellation before the set time, // the system will help the user to cancel the order of the corresponding trading pair. Otherwise it will not. -func (ku *Kucoin) AutoCancelHFOrderSetting(ctx context.Context, timeout int64, symbols []string) (*AutoCancelHFOrderResponse, error) { +func (e *Exchange) AutoCancelHFOrderSetting(ctx context.Context, timeout int64, symbols []string) (*AutoCancelHFOrderResponse, error) { if timeout == 0 { return nil, errTimeoutRequired } @@ -768,17 +768,17 @@ func (ku *Kucoin) AutoCancelHFOrderSetting(ctx context.Context, timeout int64, s Symbols: symbols, } var resp *AutoCancelHFOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, autoCancelHFOrderSettingEPL, http.MethodPost, "/v1/hf/orders/dead-cancel-all", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, autoCancelHFOrderSettingEPL, http.MethodPost, "/v1/hf/orders/dead-cancel-all", arg, &resp) } // AutoCancelHFOrderSettingQuery query the settings of automatic order cancellation -func (ku *Kucoin) AutoCancelHFOrderSettingQuery(ctx context.Context) (*AutoCancelHFOrderResponse, error) { +func (e *Exchange) AutoCancelHFOrderSettingQuery(ctx context.Context) (*AutoCancelHFOrderResponse, error) { var resp *AutoCancelHFOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, autoCancelHFOrderSettingQueryEPL, http.MethodGet, "/v1/hf/orders/dead-cancel-all/query", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, autoCancelHFOrderSettingQueryEPL, http.MethodGet, "/v1/hf/orders/dead-cancel-all/query", nil, &resp) } // GetHFFilledList retrieves a list of the latest HF transaction details. The returned results are paginated. The data is sorted in descending order according to time. -func (ku *Kucoin) GetHFFilledList(ctx context.Context, orderID, symbol, side, orderType, lastID string, startAt, endAt time.Time, limit int64) (*HFOrderFills, error) { +func (e *Exchange) GetHFFilledList(ctx context.Context, orderID, symbol, side, orderType, lastID string, startAt, endAt time.Time, limit int64) (*HFOrderFills, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -806,23 +806,23 @@ func (ku *Kucoin) GetHFFilledList(ctx context.Context, orderID, symbol, side, or params.Set(order.Limit.Lower(), strconv.FormatInt(limit, 10)) } var resp *HFOrderFills - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfFilledListEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/fills", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfFilledListEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/fills", params), nil, &resp) } // PostOrder used to place two types of orders: limit and market // Note: use this only for SPOT trades -func (ku *Kucoin) PostOrder(ctx context.Context, arg *SpotOrderParam) (string, error) { - return ku.HandlePostOrder(ctx, arg, "/v1/orders") +func (e *Exchange) PostOrder(ctx context.Context, arg *SpotOrderParam) (string, error) { + return e.HandlePostOrder(ctx, arg, "/v1/orders") } // PostOrderTest used to verify whether the signature is correct and other operations. // After placing an order, the order will not enter the matching system, and the order cannot be queried. -func (ku *Kucoin) PostOrderTest(ctx context.Context, arg *SpotOrderParam) (string, error) { - return ku.HandlePostOrder(ctx, arg, "/v1/orders/test") +func (e *Exchange) PostOrderTest(ctx context.Context, arg *SpotOrderParam) (string, error) { + return e.HandlePostOrder(ctx, arg, "/v1/orders/test") } // HandlePostOrder applies a spot order placement or tests the order placement process. -func (ku *Kucoin) HandlePostOrder(ctx context.Context, arg *SpotOrderParam, path string) (string, error) { +func (e *Exchange) HandlePostOrder(ctx context.Context, arg *SpotOrderParam, path string) (string, error) { if arg.ClientOrderID == "" { // NOTE: 128 bit max length character string. UUID recommended. return "", order.ErrClientOrderIDMustBeSet @@ -858,21 +858,21 @@ func (ku *Kucoin) HandlePostOrder(ctx context.Context, arg *SpotOrderParam, path } `json:"data"` Error } - return resp.Data.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeOrderEPL, http.MethodPost, path, &arg, &resp) + return resp.Data.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeOrderEPL, http.MethodPost, path, &arg, &resp) } // PostMarginOrderTest a test endpoint used to place two types of margin orders: limit and margin. -func (ku *Kucoin) PostMarginOrderTest(ctx context.Context, arg *MarginOrderParam) (*PostMarginOrderResp, error) { - return ku.SendPostMarginOrder(ctx, arg, "/v1/margin/order/test") +func (e *Exchange) PostMarginOrderTest(ctx context.Context, arg *MarginOrderParam) (*PostMarginOrderResp, error) { + return e.SendPostMarginOrder(ctx, arg, "/v1/margin/order/test") } // PostMarginOrder used to place two types of margin orders: limit and market -func (ku *Kucoin) PostMarginOrder(ctx context.Context, arg *MarginOrderParam) (*PostMarginOrderResp, error) { - return ku.SendPostMarginOrder(ctx, arg, "/v1/margin/order") +func (e *Exchange) PostMarginOrder(ctx context.Context, arg *MarginOrderParam) (*PostMarginOrderResp, error) { + return e.SendPostMarginOrder(ctx, arg, "/v1/margin/order") } // SendPostMarginOrder applies a margin order placement or tests the order placement process. -func (ku *Kucoin) SendPostMarginOrder(ctx context.Context, arg *MarginOrderParam, path string) (*PostMarginOrderResp, error) { +func (e *Exchange) SendPostMarginOrder(ctx context.Context, arg *MarginOrderParam, path string) (*PostMarginOrderResp, error) { if arg.ClientOrderID == "" { return nil, order.ErrClientOrderIDMustBeSet } @@ -907,13 +907,13 @@ func (ku *Kucoin) SendPostMarginOrder(ctx context.Context, arg *MarginOrderParam PostMarginOrderResp Error }{} - return &resp.PostMarginOrderResp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeMarginOrdersEPL, http.MethodPost, path, &arg, &resp) + return &resp.PostMarginOrderResp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeMarginOrdersEPL, http.MethodPost, path, &arg, &resp) } // PostBulkOrder used to place 5 orders at the same time. The order type must be a limit order of the same symbol // Note: it supports only SPOT trades // Note: To check if order was posted successfully, check status field in response -func (ku *Kucoin) PostBulkOrder(ctx context.Context, symbol string, orderList []OrderRequest) ([]PostBulkOrderResp, error) { +func (e *Exchange) PostBulkOrder(ctx context.Context, symbol string, orderList []OrderRequest) ([]PostBulkOrderResp, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -945,11 +945,11 @@ func (ku *Kucoin) PostBulkOrder(ctx context.Context, symbol string, orderList [] resp := &struct { Data []PostBulkOrderResp `json:"data"` }{} - return resp.Data, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeBulkOrdersEPL, http.MethodPost, "/v1/orders/multi", arg, &resp) + return resp.Data, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeBulkOrdersEPL, http.MethodPost, "/v1/orders/multi", arg, &resp) } // CancelSingleOrder used to cancel single order previously placed -func (ku *Kucoin) CancelSingleOrder(ctx context.Context, orderID string) ([]string, error) { +func (e *Exchange) CancelSingleOrder(ctx context.Context, orderID string) ([]string, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -957,20 +957,20 @@ func (ku *Kucoin) CancelSingleOrder(ctx context.Context, orderID string) ([]stri CancelledOrderIDs []string `json:"cancelledOrderIds"` Error }{} - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOrderEPL, http.MethodDelete, "/v1/orders/"+orderID, nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOrderEPL, http.MethodDelete, "/v1/orders/"+orderID, nil, &resp) } // CancelOrderByClientOID used to cancel order via the clientOid -func (ku *Kucoin) CancelOrderByClientOID(ctx context.Context, orderID string) (*CancelOrderResponse, error) { +func (e *Exchange) CancelOrderByClientOID(ctx context.Context, orderID string) (*CancelOrderResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *CancelOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOrderByClientOrderIDEPL, http.MethodDelete, "/v1/order/client-order/"+orderID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOrderByClientOrderIDEPL, http.MethodDelete, "/v1/order/client-order/"+orderID, nil, &resp) } // CancelAllOpenOrders used to cancel all order based upon the parameters passed -func (ku *Kucoin) CancelAllOpenOrders(ctx context.Context, symbol, tradeType string) ([]string, error) { +func (e *Exchange) CancelAllOpenOrders(ctx context.Context, symbol, tradeType string) ([]string, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -984,17 +984,17 @@ func (ku *Kucoin) CancelAllOpenOrders(ctx context.Context, symbol, tradeType str }{ CancelledOrderIDs: []string{}, } - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelAllOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v1/orders", params), nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelAllOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v1/orders", params), nil, &resp) } // ListOrders gets the user order list -func (ku *Kucoin) ListOrders(ctx context.Context, status, symbol, side, orderType, tradeType string, startAt, endAt time.Time) (*OrdersListResponse, error) { +func (e *Exchange) ListOrders(ctx context.Context, status, symbol, side, orderType, tradeType string, startAt, endAt time.Time) (*OrdersListResponse, error) { params := FillParams(symbol, side, orderType, tradeType, startAt, endAt) if status != "" { params.Set("status", status) } var resp *OrdersListResponse - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, listOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/orders", params), nil, &resp) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, listOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/orders", params), nil, &resp) if err != nil { return nil, err } @@ -1026,47 +1026,47 @@ func FillParams(symbol, side, orderType, tradeType string, startAt, endAt time.T } // GetRecentOrders get orders in the last 24 hours. -func (ku *Kucoin) GetRecentOrders(ctx context.Context) ([]OrderDetail, error) { +func (e *Exchange) GetRecentOrders(ctx context.Context) ([]OrderDetail, error) { var resp []OrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, recentOrdersEPL, http.MethodGet, "/v1/limit/orders", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, recentOrdersEPL, http.MethodGet, "/v1/limit/orders", nil, &resp) } // GetOrderByID get a single order info by order ID -func (ku *Kucoin) GetOrderByID(ctx context.Context, orderID string) (*OrderDetail, error) { +func (e *Exchange) GetOrderByID(ctx context.Context, orderID string) (*OrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *OrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, orderDetailByIDEPL, http.MethodGet, "/v1/orders/"+orderID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, orderDetailByIDEPL, http.MethodGet, "/v1/orders/"+orderID, nil, &resp) } // GetOrderByClientSuppliedOrderID get a single order info by client order ID -func (ku *Kucoin) GetOrderByClientSuppliedOrderID(ctx context.Context, clientOID string) (*OrderDetail, error) { +func (e *Exchange) GetOrderByClientSuppliedOrderID(ctx context.Context, clientOID string) (*OrderDetail, error) { if clientOID == "" { return nil, order.ErrClientOrderIDMustBeSet } var resp *OrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOrderByClientSuppliedOrderIDEPL, http.MethodGet, "/v1/order/client-order/"+clientOID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOrderByClientSuppliedOrderIDEPL, http.MethodGet, "/v1/order/client-order/"+clientOID, nil, &resp) } // GetFills get fills -func (ku *Kucoin) GetFills(ctx context.Context, orderID, symbol, side, orderType, tradeType string, startAt, endAt time.Time) (*ListFills, error) { +func (e *Exchange) GetFills(ctx context.Context, orderID, symbol, side, orderType, tradeType string, startAt, endAt time.Time) (*ListFills, error) { params := FillParams(symbol, side, orderType, tradeType, startAt, endAt) if orderID != "" { params.Set("orderId", orderID) } var resp *ListFills - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, listFillsEPL, http.MethodGet, common.EncodeURLValues("/v1/fills", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, listFillsEPL, http.MethodGet, common.EncodeURLValues("/v1/fills", params), nil, &resp) } // GetRecentFills get a list of 1000 fills in last 24 hours -func (ku *Kucoin) GetRecentFills(ctx context.Context) ([]Fill, error) { +func (e *Exchange) GetRecentFills(ctx context.Context) ([]Fill, error) { var resp []Fill - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getRecentFillsEPL, http.MethodGet, "/v1/limit/fills", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getRecentFillsEPL, http.MethodGet, "/v1/limit/fills", nil, &resp) } // PostStopOrder used to place two types of stop orders: limit and market -func (ku *Kucoin) PostStopOrder(ctx context.Context, clientOID, side, symbol, orderType, remark, stop, stp, +func (e *Exchange) PostStopOrder(ctx context.Context, clientOID, side, symbol, orderType, remark, stop, stp, tradeType, timeInForce string, size, price, stopPrice, cancelAfter, visibleSize, funds float64, postOnly, hidden, iceberg bool, ) (string, error) { @@ -1141,11 +1141,11 @@ func (ku *Kucoin) PostStopOrder(ctx context.Context, clientOID, side, symbol, or OrderID string `json:"orderId"` Error }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeStopOrderEPL, http.MethodPost, "/v1/stop-order", arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeStopOrderEPL, http.MethodPost, "/v1/stop-order", arg, &resp) } // CancelStopOrder used to cancel single stop order previously placed -func (ku *Kucoin) CancelStopOrder(ctx context.Context, orderID string) ([]string, error) { +func (e *Exchange) CancelStopOrder(ctx context.Context, orderID string) ([]string, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -1153,11 +1153,11 @@ func (ku *Kucoin) CancelStopOrder(ctx context.Context, orderID string) ([]string Data []string `json:"cancelledOrderIds"` Error }{} - return resp.Data, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderEPL, http.MethodDelete, "/v1/stop-order/"+orderID, nil, &resp) + return resp.Data, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderEPL, http.MethodDelete, "/v1/stop-order/"+orderID, nil, &resp) } // CancelStopOrderByClientOrderID used to cancel single stop order previously placed by client supplied order ID. -func (ku *Kucoin) CancelStopOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) ([]string, error) { +func (e *Exchange) CancelStopOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) ([]string, error) { if clientOrderID == "" { return nil, order.ErrClientOrderIDMustBeSet } @@ -1170,11 +1170,11 @@ func (ku *Kucoin) CancelStopOrderByClientOrderID(ctx context.Context, clientOrde Data []string `json:"cancelledOrderIds"` Error }{} - return resp.Data, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancelOrderByClientOid", params), nil, &resp) + return resp.Data, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancelOrderByClientOid", params), nil, &resp) } // CancelStopOrders used to cancel all order based upon the parameters passed -func (ku *Kucoin) CancelStopOrders(ctx context.Context, symbol, tradeType string, orderIDs []string) ([]string, error) { +func (e *Exchange) CancelStopOrders(ctx context.Context, symbol, tradeType string, orderIDs []string) ([]string, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -1191,11 +1191,11 @@ func (ku *Kucoin) CancelStopOrders(ctx context.Context, symbol, tradeType string }{ CancelledOrderIDs: []string{}, } - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancel", params), nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancel", params), nil, &resp) } // GetStopOrder used to cancel single stop order previously placed -func (ku *Kucoin) GetStopOrder(ctx context.Context, orderID string) (*StopOrder, error) { +func (e *Exchange) GetStopOrder(ctx context.Context, orderID string) (*StopOrder, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -1203,11 +1203,11 @@ func (ku *Kucoin) GetStopOrder(ctx context.Context, orderID string) (*StopOrder, StopOrder Error }{} - return &resp.StopOrder, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getStopOrderDetailEPL, http.MethodGet, "/v1/stop-order/"+orderID, nil, &resp) + return &resp.StopOrder, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getStopOrderDetailEPL, http.MethodGet, "/v1/stop-order/"+orderID, nil, &resp) } // ListStopOrders get all current untriggered stop orders -func (ku *Kucoin) ListStopOrders(ctx context.Context, symbol, side, orderType, tradeType string, orderIDs []string, startAt, endAt time.Time, currentPage, pageSize int64) (*StopOrderListResponse, error) { +func (e *Exchange) ListStopOrders(ctx context.Context, symbol, side, orderType, tradeType string, orderIDs []string, startAt, endAt time.Time, currentPage, pageSize int64) (*StopOrderListResponse, error) { params := FillParams(symbol, side, orderType, tradeType, startAt, endAt) if len(orderIDs) > 0 { params.Set("orderIds", strings.Join(orderIDs, ",")) @@ -1219,11 +1219,11 @@ func (ku *Kucoin) ListStopOrders(ctx context.Context, symbol, side, orderType, t params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *StopOrderListResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, listStopOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/stop-order", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, listStopOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/stop-order", params), nil, &resp) } // GetStopOrderByClientID get a stop order information via the clientOID -func (ku *Kucoin) GetStopOrderByClientID(ctx context.Context, symbol, clientOID string) ([]StopOrder, error) { +func (e *Exchange) GetStopOrderByClientID(ctx context.Context, symbol, clientOID string) ([]StopOrder, error) { if clientOID == "" { return nil, order.ErrClientOrderIDMustBeSet } @@ -1233,11 +1233,11 @@ func (ku *Kucoin) GetStopOrderByClientID(ctx context.Context, symbol, clientOID params.Set("symbol", symbol) } var resp []StopOrder - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getStopOrderByClientIDEPL, http.MethodGet, common.EncodeURLValues("/v1/stop-order/queryOrderByClientOid", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getStopOrderByClientIDEPL, http.MethodGet, common.EncodeURLValues("/v1/stop-order/queryOrderByClientOid", params), nil, &resp) } // CancelStopOrderByClientID used to cancel a stop order via the clientOID. -func (ku *Kucoin) CancelStopOrderByClientID(ctx context.Context, symbol, clientOID string) (*CancelOrderResponse, error) { +func (e *Exchange) CancelStopOrderByClientID(ctx context.Context, symbol, clientOID string) (*CancelOrderResponse, error) { if clientOID == "" { return nil, order.ErrClientOrderIDMustBeSet } @@ -1247,13 +1247,13 @@ func (ku *Kucoin) CancelStopOrderByClientID(ctx context.Context, symbol, clientO params.Set("symbol", symbol) } var resp *CancelOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderByClientIDEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancelOrderByClientOid", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelStopOrderByClientIDEPL, http.MethodDelete, common.EncodeURLValues("/v1/stop-order/cancelOrderByClientOid", params), nil, &resp) } // ------------------------------------------------ OCO Order ----------------------------------------------------------------- // PlaceOCOOrder creates a new One cancel other(OCO) order. -func (ku *Kucoin) PlaceOCOOrder(ctx context.Context, arg *OCOOrderParams) (string, error) { +func (e *Exchange) PlaceOCOOrder(ctx context.Context, arg *OCOOrderParams) (string, error) { if *arg == (OCOOrderParams{}) { return "", common.ErrNilPointer } @@ -1283,33 +1283,33 @@ func (ku *Kucoin) PlaceOCOOrder(ctx context.Context, arg *OCOOrderParams) (strin resp := &struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeOCOOrderEPL, http.MethodPost, "/v3/oco/order", &arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeOCOOrderEPL, http.MethodPost, "/v3/oco/order", &arg, &resp) } // CancelOCOOrderByOrderID cancels a single oco order previously placed by order ID. -func (ku *Kucoin) CancelOCOOrderByOrderID(ctx context.Context, orderID string) (*OCOOrderCancellationResponse, error) { +func (e *Exchange) CancelOCOOrderByOrderID(ctx context.Context, orderID string) (*OCOOrderCancellationResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } - return ku.CancelOCOOrderByID(ctx, "/v3/oco/order/", orderID) + return e.CancelOCOOrderByID(ctx, "/v3/oco/order/", orderID) } // CancelOCOOrderByClientOrderID cancels a single oco order previously placed by client order ID. -func (ku *Kucoin) CancelOCOOrderByClientOrderID(ctx context.Context, clientOrderID string) (*OCOOrderCancellationResponse, error) { +func (e *Exchange) CancelOCOOrderByClientOrderID(ctx context.Context, clientOrderID string) (*OCOOrderCancellationResponse, error) { if clientOrderID == "" { return nil, order.ErrClientOrderIDMustBeSet } - return ku.CancelOCOOrderByID(ctx, "/v3/oco/client-order/", clientOrderID) + return e.CancelOCOOrderByID(ctx, "/v3/oco/client-order/", clientOrderID) } // CancelOCOOrderByID sends a cancel OCO order by order ID or client supplied order ID. -func (ku *Kucoin) CancelOCOOrderByID(ctx context.Context, path, id string) (*OCOOrderCancellationResponse, error) { +func (e *Exchange) CancelOCOOrderByID(ctx context.Context, path, id string) (*OCOOrderCancellationResponse, error) { var resp *OCOOrderCancellationResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOCOOrderByIDEPL, http.MethodDelete, path+id, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelOCOOrderByIDEPL, http.MethodDelete, path+id, nil, &resp) } // CancelOCOMultipleOrders batch cancel OCO orders through orderIds. -func (ku *Kucoin) CancelOCOMultipleOrders(ctx context.Context, orderIDs []string, symbol string) (*OCOOrderCancellationResponse, error) { +func (e *Exchange) CancelOCOMultipleOrders(ctx context.Context, orderIDs []string, symbol string) (*OCOOrderCancellationResponse, error) { params := url.Values{} if len(orderIDs) > 0 { params.Set("orderIds", strings.Join(orderIDs, ",")) @@ -1318,39 +1318,39 @@ func (ku *Kucoin) CancelOCOMultipleOrders(ctx context.Context, orderIDs []string params.Set("symbol", symbol) } var resp *OCOOrderCancellationResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelMultipleOCOOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v3/oco/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelMultipleOCOOrdersEPL, http.MethodDelete, common.EncodeURLValues("/v3/oco/orders", params), nil, &resp) } // GetOCOOrderInfoByOrderID to get a oco order information via the order ID. -func (ku *Kucoin) GetOCOOrderInfoByOrderID(ctx context.Context, orderID string) (*OCOOrderInfo, error) { - return ku.GetOCOOrderInfoByID(ctx, orderID, "/v3/oco/order/") +func (e *Exchange) GetOCOOrderInfoByOrderID(ctx context.Context, orderID string) (*OCOOrderInfo, error) { + return e.GetOCOOrderInfoByID(ctx, orderID, "/v3/oco/order/") } // GetOCOOrderInfoByClientOrderID to get a oco order information via the client order ID. -func (ku *Kucoin) GetOCOOrderInfoByClientOrderID(ctx context.Context, clientOrderID string) (*OCOOrderInfo, error) { - return ku.GetOCOOrderInfoByID(ctx, clientOrderID, "/v3/oco/client-order/") +func (e *Exchange) GetOCOOrderInfoByClientOrderID(ctx context.Context, clientOrderID string) (*OCOOrderInfo, error) { + return e.GetOCOOrderInfoByID(ctx, clientOrderID, "/v3/oco/client-order/") } // GetOCOOrderInfoByID sends a request to get an OCO order by order ID or client supplied order ID. -func (ku *Kucoin) GetOCOOrderInfoByID(ctx context.Context, id, path string) (*OCOOrderInfo, error) { +func (e *Exchange) GetOCOOrderInfoByID(ctx context.Context, id, path string) (*OCOOrderInfo, error) { if id == "" { return nil, order.ErrOrderIDNotSet } var resp *OCOOrderInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrderByIDEPL, http.MethodGet, path+id, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrderByIDEPL, http.MethodGet, path+id, nil, &resp) } // GetOCOOrderDetailsByOrderID get a oco order detail via the order ID. -func (ku *Kucoin) GetOCOOrderDetailsByOrderID(ctx context.Context, orderID string) (*OCOOrderDetail, error) { +func (e *Exchange) GetOCOOrderDetailsByOrderID(ctx context.Context, orderID string) (*OCOOrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *OCOOrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrderDetailsByOrderIDEPL, http.MethodGet, "/v3/oco/order/details/"+orderID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrderDetailsByOrderIDEPL, http.MethodGet, "/v3/oco/order/details/"+orderID, nil, &resp) } // GetOCOOrderList retrieves list of OCO orders. -func (ku *Kucoin) GetOCOOrderList(ctx context.Context, pageSize, currentPage int64, symbol string, startAt, endAt time.Time, orderIDs []string) (*OCOOrders, error) { +func (e *Exchange) GetOCOOrderList(ctx context.Context, pageSize, currentPage int64, symbol string, startAt, endAt time.Time, orderIDs []string) (*OCOOrders, error) { if pageSize < 10 { return nil, fmt.Errorf("%w, pageSize must be between 10 and 500", errPageSizeRequired) } @@ -1373,24 +1373,24 @@ func (ku *Kucoin) GetOCOOrderList(ctx context.Context, pageSize, currentPage int params.Set("orderIds", strings.Join(orderIDs, ",")) } var resp *OCOOrders - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/oco/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getOCOOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/oco/orders", params), nil, &resp) } // ----------------------------------------------------------- Margin HF Trade ------------------------------------------------------------- // PlaceMarginHFOrder used to place cross-margin or isolated-margin high-frequency margin trading -func (ku *Kucoin) PlaceMarginHFOrder(ctx context.Context, arg *PlaceMarginHFOrderParam) (*MarginHFOrderResponse, error) { - return ku.SendPlaceMarginHFOrder(ctx, arg, "/v3/hf/margin/order") +func (e *Exchange) PlaceMarginHFOrder(ctx context.Context, arg *PlaceMarginHFOrderParam) (*MarginHFOrderResponse, error) { + return e.SendPlaceMarginHFOrder(ctx, arg, "/v3/hf/margin/order") } // PlaceMarginHFOrderTest used to verify whether the signature is correct and other operations. After placing an order, // the order will not enter the matching system, and the order cannot be queried. -func (ku *Kucoin) PlaceMarginHFOrderTest(ctx context.Context, arg *PlaceMarginHFOrderParam) (*MarginHFOrderResponse, error) { - return ku.SendPlaceMarginHFOrder(ctx, arg, "/v3/hf/margin/order/test") +func (e *Exchange) PlaceMarginHFOrderTest(ctx context.Context, arg *PlaceMarginHFOrderParam) (*MarginHFOrderResponse, error) { + return e.SendPlaceMarginHFOrder(ctx, arg, "/v3/hf/margin/order/test") } // SendPlaceMarginHFOrder applies a high-frequency margin order placement or tests the order placement process. -func (ku *Kucoin) SendPlaceMarginHFOrder(ctx context.Context, arg *PlaceMarginHFOrderParam, path string) (*MarginHFOrderResponse, error) { +func (e *Exchange) SendPlaceMarginHFOrder(ctx context.Context, arg *PlaceMarginHFOrderParam, path string) (*MarginHFOrderResponse, error) { if *arg == (PlaceMarginHFOrderParam{}) { return nil, common.ErrNilPointer } @@ -1411,22 +1411,22 @@ func (ku *Kucoin) SendPlaceMarginHFOrder(ctx context.Context, arg *PlaceMarginHF return nil, order.ErrAmountBelowMin } var resp *MarginHFOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeMarginOrderEPL, http.MethodPost, path, arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, placeMarginOrderEPL, http.MethodPost, path, arg, &resp) } // CancelMarginHFOrderByOrderID cancels a single order by orderId. If the order cannot be canceled (sold or canceled), // an error message will be returned, and the reason can be obtained according to the returned msg. -func (ku *Kucoin) CancelMarginHFOrderByOrderID(ctx context.Context, orderID, symbol string) (string, error) { - return ku.CancelMarginHFOrderByID(ctx, orderID, symbol, "/v3/hf/margin/orders/") +func (e *Exchange) CancelMarginHFOrderByOrderID(ctx context.Context, orderID, symbol string) (string, error) { + return e.CancelMarginHFOrderByID(ctx, orderID, symbol, "/v3/hf/margin/orders/") } // CancelMarginHFOrderByClientOrderID to cancel a single order by clientOid. -func (ku *Kucoin) CancelMarginHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (string, error) { - return ku.CancelMarginHFOrderByID(ctx, clientOrderID, symbol, "/v3/hf/margin/orders/client-order/") +func (e *Exchange) CancelMarginHFOrderByClientOrderID(ctx context.Context, clientOrderID, symbol string) (string, error) { + return e.CancelMarginHFOrderByID(ctx, clientOrderID, symbol, "/v3/hf/margin/orders/client-order/") } // CancelMarginHFOrderByID sends a cancel order high frequency margin orders by order ID or client supplied order ID. -func (ku *Kucoin) CancelMarginHFOrderByID(ctx context.Context, id, symbol, path string) (string, error) { +func (e *Exchange) CancelMarginHFOrderByID(ctx context.Context, id, symbol, path string) (string, error) { if id == "" { return "", order.ErrOrderIDNotSet } @@ -1436,12 +1436,12 @@ func (ku *Kucoin) CancelMarginHFOrderByID(ctx context.Context, id, symbol, path resp := &struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelMarginHFOrderByIDEPL, http.MethodDelete, path+id+symbolQuery+symbol, nil, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelMarginHFOrderByIDEPL, http.MethodDelete, path+id+symbolQuery+symbol, nil, &resp) } // CancelAllMarginHFOrdersBySymbol cancel all open high-frequency Margin orders(orders created through POST /api/v3/hf/margin/order). // Transaction type: MARGIN_TRADE - cross margin trade, MARGIN_ISOLATED_TRADE - isolated margin trade -func (ku *Kucoin) CancelAllMarginHFOrdersBySymbol(ctx context.Context, symbol, tradeType string) (string, error) { +func (e *Exchange) CancelAllMarginHFOrdersBySymbol(ctx context.Context, symbol, tradeType string) (string, error) { if symbol == "" { return "", currency.ErrSymbolStringEmpty } @@ -1452,11 +1452,11 @@ func (ku *Kucoin) CancelAllMarginHFOrdersBySymbol(ctx context.Context, symbol, t params.Set("symbol", symbol) params.Set("tradeType", tradeType) var resp string - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelAllMarginHFOrdersBySymbolEPL, http.MethodDelete, common.EncodeURLValues("/v3/hf/margin/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelAllMarginHFOrdersBySymbolEPL, http.MethodDelete, common.EncodeURLValues("/v3/hf/margin/orders", params), nil, &resp) } // GetActiveMarginHFOrders retrieves list if active high-frequency margin orders -func (ku *Kucoin) GetActiveMarginHFOrders(ctx context.Context, symbol, tradeType string) ([]OrderDetail, error) { +func (e *Exchange) GetActiveMarginHFOrders(ctx context.Context, symbol, tradeType string) ([]OrderDetail, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -1465,12 +1465,12 @@ func (ku *Kucoin) GetActiveMarginHFOrders(ctx context.Context, symbol, tradeType params.Set("tradeType", tradeType) } var resp []OrderDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getActiveMarginHFOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/orders/active", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getActiveMarginHFOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/orders/active", params), nil, &resp) } // GetFilledHFMarginOrders list of filled margin HF orders and returns paginated data. // The returned data is sorted in descending order based on the latest order update times. -func (ku *Kucoin) GetFilledHFMarginOrders(ctx context.Context, symbol, tradeType, side, orderType string, startAt, endAt time.Time, lastID, limit int64) (*FilledMarginHFOrdersResponse, error) { +func (e *Exchange) GetFilledHFMarginOrders(ctx context.Context, symbol, tradeType, side, orderType string, startAt, endAt time.Time, lastID, limit int64) (*FilledMarginHFOrdersResponse, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -1499,21 +1499,21 @@ func (ku *Kucoin) GetFilledHFMarginOrders(ctx context.Context, symbol, tradeType params.Set(order.Limit.Lower(), strconv.FormatInt(limit, 10)) } var resp *FilledMarginHFOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getFilledHFMarginOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/orders/done", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getFilledHFMarginOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/orders/done", params), nil, &resp) } // GetMarginHFOrderDetailByOrderID retrieves the detail of a HF margin order by order ID. -func (ku *Kucoin) GetMarginHFOrderDetailByOrderID(ctx context.Context, orderID, symbol string) (*OrderDetail, error) { - return ku.GetMarginHFOrderDetailByID(ctx, orderID, symbol, "/v3/hf/margin/orders/") +func (e *Exchange) GetMarginHFOrderDetailByOrderID(ctx context.Context, orderID, symbol string) (*OrderDetail, error) { + return e.GetMarginHFOrderDetailByID(ctx, orderID, symbol, "/v3/hf/margin/orders/") } // GetMarginHFOrderDetailByClientOrderID retrieves the detaul of a HF margin order by client order ID. -func (ku *Kucoin) GetMarginHFOrderDetailByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*OrderDetail, error) { - return ku.GetMarginHFOrderDetailByID(ctx, clientOrderID, symbol, "/v3/hf/margin/orders/client-order/") +func (e *Exchange) GetMarginHFOrderDetailByClientOrderID(ctx context.Context, clientOrderID, symbol string) (*OrderDetail, error) { + return e.GetMarginHFOrderDetailByID(ctx, clientOrderID, symbol, "/v3/hf/margin/orders/client-order/") } // GetMarginHFOrderDetailByID sends an HTTP request to fetch margin high frequency orders by order ID or client supplied order ID. -func (ku *Kucoin) GetMarginHFOrderDetailByID(ctx context.Context, orderID, symbol, path string) (*OrderDetail, error) { +func (e *Exchange) GetMarginHFOrderDetailByID(ctx context.Context, orderID, symbol, path string) (*OrderDetail, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -1524,7 +1524,7 @@ func (ku *Kucoin) GetMarginHFOrderDetailByID(ctx context.Context, orderID, symbo params.Set("symbol", symbol) params.Set("orderId", orderID) var resp *OrderDetail - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getMarginHFOrderDetailByOrderIDEPL, http.MethodGet, path+orderID+symbolQuery+symbol, nil, &resp) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getMarginHFOrderDetailByOrderIDEPL, http.MethodGet, path+orderID+symbolQuery+symbol, nil, &resp) if err != nil { return nil, err } @@ -1535,7 +1535,7 @@ func (ku *Kucoin) GetMarginHFOrderDetailByID(ctx context.Context, orderID, symbo } // GetMarginHFTradeFills to obtain a list of the latest margin HF transaction details. The returned results are paginated. The data is sorted in descending order according to time. -func (ku *Kucoin) GetMarginHFTradeFills(ctx context.Context, orderID, symbol, tradeType, side, orderType string, startAt, endAt time.Time, lastID, limit int64) (*HFMarginOrderTransaction, error) { +func (e *Exchange) GetMarginHFTradeFills(ctx context.Context, orderID, symbol, tradeType, side, orderType string, startAt, endAt time.Time, lastID, limit int64) (*HFMarginOrderTransaction, error) { if tradeType == "" { return nil, errTradeTypeMissing } @@ -1567,11 +1567,11 @@ func (ku *Kucoin) GetMarginHFTradeFills(ctx context.Context, orderID, symbol, tr params.Set(order.Limit.Lower(), strconv.FormatInt(limit, 10)) } var resp *HFMarginOrderTransaction - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getMarginHFTradeFillsEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/fills", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getMarginHFTradeFillsEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/fills", params), nil, &resp) } // CreateSubUser creates a new sub-user for the account. -func (ku *Kucoin) CreateSubUser(ctx context.Context, subAccountName, password, remarks, access string) (*SubAccount, error) { +func (e *Exchange) CreateSubUser(ctx context.Context, subAccountName, password, remarks, access string) (*SubAccount, error) { if subAccountName == "" { return nil, fmt.Errorf("%w, subaccount name is required", errInvalidSubAccountName) } @@ -1590,11 +1590,11 @@ func (ku *Kucoin) CreateSubUser(ctx context.Context, subAccountName, password, r Access: access, } var resp *SubAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, createSubUserEPL, http.MethodPost, "/v2/sub/user/created", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, createSubUserEPL, http.MethodPost, "/v2/sub/user/created", arg, &resp) } // GetSubAccountSpotAPIList used to obtain a list of Spot APIs pertaining to a sub-account. -func (ku *Kucoin) GetSubAccountSpotAPIList(ctx context.Context, subAccountName, apiKeys string) ([]SpotAPISubAccount, error) { +func (e *Exchange) GetSubAccountSpotAPIList(ctx context.Context, subAccountName, apiKeys string) ([]SpotAPISubAccount, error) { if subAccountName == "" { return nil, errInvalidSubAccountName } @@ -1604,11 +1604,11 @@ func (ku *Kucoin) GetSubAccountSpotAPIList(ctx context.Context, subAccountName, params.Set("apiKey", apiKeys) } var resp []SpotAPISubAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountSpotAPIListEPL, http.MethodGet, common.EncodeURLValues("/v1/sub/api-key", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountSpotAPIListEPL, http.MethodGet, common.EncodeURLValues("/v1/sub/api-key", params), nil, &resp) } // CreateSpotAPIsForSubAccount can be used to create Spot APIs for sub-accounts. -func (ku *Kucoin) CreateSpotAPIsForSubAccount(ctx context.Context, arg *SpotAPISubAccountParams) (*SpotAPISubAccount, error) { +func (e *Exchange) CreateSpotAPIsForSubAccount(ctx context.Context, arg *SpotAPISubAccountParams) (*SpotAPISubAccount, error) { if arg.SubAccountName == "" { return nil, errInvalidSubAccountName } @@ -1619,11 +1619,11 @@ func (ku *Kucoin) CreateSpotAPIsForSubAccount(ctx context.Context, arg *SpotAPIS return nil, errRemarkIsRequired } var resp *SpotAPISubAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, createSpotAPIForSubAccountEPL, http.MethodPost, "/v1/sub/api-key", &arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, createSpotAPIForSubAccountEPL, http.MethodPost, "/v1/sub/api-key", &arg, &resp) } // ModifySubAccountSpotAPIs modifies sub-account Spot APIs. -func (ku *Kucoin) ModifySubAccountSpotAPIs(ctx context.Context, arg *SpotAPISubAccountParams) (*SpotAPISubAccount, error) { +func (e *Exchange) ModifySubAccountSpotAPIs(ctx context.Context, arg *SpotAPISubAccountParams) (*SpotAPISubAccount, error) { if arg.SubAccountName == "" { return nil, errInvalidSubAccountName } @@ -1634,11 +1634,11 @@ func (ku *Kucoin) ModifySubAccountSpotAPIs(ctx context.Context, arg *SpotAPISubA return nil, fmt.Errorf("%w, must contain 7-32 characters. cannot contain any spaces", errInvalidPassPhraseInstance) } var resp *SpotAPISubAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubAccountSpotAPIEPL, http.MethodPut, "/v1/sub/api-key/update", &arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubAccountSpotAPIEPL, http.MethodPut, "/v1/sub/api-key/update", &arg, &resp) } // DeleteSubAccountSpotAPI delete sub-account Spot APIs. -func (ku *Kucoin) DeleteSubAccountSpotAPI(ctx context.Context, apiKey, subAccountName, passphrase string) (*DeleteSubAccountResponse, error) { +func (e *Exchange) DeleteSubAccountSpotAPI(ctx context.Context, apiKey, subAccountName, passphrase string) (*DeleteSubAccountResponse, error) { if subAccountName == "" { return nil, errInvalidSubAccountName } @@ -1653,17 +1653,17 @@ func (ku *Kucoin) DeleteSubAccountSpotAPI(ctx context.Context, apiKey, subAccoun params.Set("subName", subAccountName) params.Set("passphrase", passphrase) var resp *DeleteSubAccountResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, deleteSubAccountSpotAPIEPL, http.MethodDelete, common.EncodeURLValues("/v1/sub/api-key", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, deleteSubAccountSpotAPIEPL, http.MethodDelete, common.EncodeURLValues("/v1/sub/api-key", params), nil, &resp) } // GetUserInfoOfAllSubAccounts get the user info of all sub-users via this interface. -func (ku *Kucoin) GetUserInfoOfAllSubAccounts(ctx context.Context) (*SubAccountResponse, error) { +func (e *Exchange) GetUserInfoOfAllSubAccounts(ctx context.Context) (*SubAccountResponse, error) { var resp *SubAccountResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, allUserSubAccountsV2EPL, http.MethodGet, "/v2/sub/user", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, allUserSubAccountsV2EPL, http.MethodGet, "/v2/sub/user", nil, &resp) } // GetPaginatedListOfSubAccounts to retrieve a paginated list of sub-accounts. Pagination is required. -func (ku *Kucoin) GetPaginatedListOfSubAccounts(ctx context.Context, currentPage, pageSize int64) (*SubAccountResponse, error) { +func (e *Exchange) GetPaginatedListOfSubAccounts(ctx context.Context, currentPage, pageSize int64) (*SubAccountResponse, error) { params := url.Values{} if pageSize > 0 { params.Set("pageSize", strconv.FormatInt(pageSize, 10)) @@ -1672,12 +1672,12 @@ func (ku *Kucoin) GetPaginatedListOfSubAccounts(ctx context.Context, currentPage params.Set("currentPage", strconv.FormatInt(currentPage, 10)) } var resp *SubAccountResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubAccountAPIEPL, http.MethodGet, common.EncodeURLValues("/v1/sub/api-key/update", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubAccountAPIEPL, http.MethodGet, common.EncodeURLValues("/v1/sub/api-key/update", params), nil, &resp) } // GetAllAccounts get all accounts // accountType possible values are main、trade、margin、trade_hf -func (ku *Kucoin) GetAllAccounts(ctx context.Context, ccy currency.Code, accountType string) ([]AccountInfo, error) { +func (e *Exchange) GetAllAccounts(ctx context.Context, ccy currency.Code, accountType string) ([]AccountInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1686,20 +1686,20 @@ func (ku *Kucoin) GetAllAccounts(ctx context.Context, ccy currency.Code, account params.Set("type", accountType) } var resp []AccountInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, allAccountEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, allAccountEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts", params), nil, &resp) } // GetAccountDetail get information of single account -func (ku *Kucoin) GetAccountDetail(ctx context.Context, accountID string) (*AccountInfo, error) { +func (e *Exchange) GetAccountDetail(ctx context.Context, accountID string) (*AccountInfo, error) { if accountID == "" { return nil, errAccountIDMissing } var resp *AccountInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountDetailEPL, http.MethodGet, "/v1/accounts/"+accountID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountDetailEPL, http.MethodGet, "/v1/accounts/"+accountID, nil, &resp) } // GetCrossMarginAccountsDetail retrieves the info of the cross margin account. -func (ku *Kucoin) GetCrossMarginAccountsDetail(ctx context.Context, quoteCurrency, queryType string) (*CrossMarginAccountDetail, error) { +func (e *Exchange) GetCrossMarginAccountsDetail(ctx context.Context, quoteCurrency, queryType string) (*CrossMarginAccountDetail, error) { params := url.Values{} if quoteCurrency != "" { params.Set("quoteCurrency", quoteCurrency) @@ -1708,11 +1708,11 @@ func (ku *Kucoin) GetCrossMarginAccountsDetail(ctx context.Context, quoteCurrenc params.Set("queryType", queryType) } var resp *CrossMarginAccountDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, crossMarginAccountsDetailEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/accounts", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, crossMarginAccountsDetailEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/accounts", params), nil, &resp) } // GetIsolatedMarginAccountDetail to get the info of the isolated margin account. -func (ku *Kucoin) GetIsolatedMarginAccountDetail(ctx context.Context, symbol, queryCurrency, queryType string) (*IsolatedMarginAccountDetail, error) { +func (e *Exchange) GetIsolatedMarginAccountDetail(ctx context.Context, symbol, queryCurrency, queryType string) (*IsolatedMarginAccountDetail, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -1724,21 +1724,21 @@ func (ku *Kucoin) GetIsolatedMarginAccountDetail(ctx context.Context, symbol, qu params.Set("queryType", queryType) } var resp *IsolatedMarginAccountDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginAccountDetailEPL, http.MethodGet, common.EncodeURLValues("/v3/isolated/accounts", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, isolatedMarginAccountDetailEPL, http.MethodGet, common.EncodeURLValues("/v3/isolated/accounts", params), nil, &resp) } // GetFuturesAccountDetail retrieves futures account detail information -func (ku *Kucoin) GetFuturesAccountDetail(ctx context.Context, ccy currency.Code) (*FuturesAccountOverview, error) { +func (e *Exchange) GetFuturesAccountDetail(ctx context.Context, ccy currency.Code) (*FuturesAccountOverview, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp *FuturesAccountOverview - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountsDetailEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountsDetailEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview", params), nil, &resp) } // GetSubAccounts retrieves all sub-account information -func (ku *Kucoin) GetSubAccounts(ctx context.Context, subUserID string, includeBaseAmount bool) (*SubAccounts, error) { +func (e *Exchange) GetSubAccounts(ctx context.Context, subUserID string, includeBaseAmount bool) (*SubAccounts, error) { if subUserID == "" { return nil, fmt.Errorf("%w, sub-users ID is required", order.ErrOrderIDNotSet) } @@ -1749,17 +1749,17 @@ func (ku *Kucoin) GetSubAccounts(ctx context.Context, subUserID string, includeB params.Set("includeBaseAmount", "false") } var resp *SubAccounts - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountsEPL, http.MethodGet, common.EncodeURLValues("/v1/sub-accounts/"+subUserID, params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountsEPL, http.MethodGet, common.EncodeURLValues("/v1/sub-accounts/"+subUserID, params), nil, &resp) } // GetAllFuturesSubAccountBalances retrieves all futures subaccount balances -func (ku *Kucoin) GetAllFuturesSubAccountBalances(ctx context.Context, ccy currency.Code) (*FuturesSubAccountBalance, error) { +func (e *Exchange) GetAllFuturesSubAccountBalances(ctx context.Context, ccy currency.Code) (*FuturesSubAccountBalance, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp *FuturesSubAccountBalance - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, allFuturesSubAccountBalancesEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview-all", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, allFuturesSubAccountBalancesEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview-all", params), nil, &resp) } // populateParams populates account ledger request parameters. @@ -1791,7 +1791,7 @@ func populateParams(ccy currency.Code, direction, bizType string, lastID, limit // GetAccountLedgers retrieves the transaction records from all types of your accounts, supporting inquiry of various currencies. // bizType possible values: 'DEPOSIT' -deposit, 'WITHDRAW' -withdraw, 'TRANSFER' -transfer, 'SUB_TRANSFER' -subaccount transfer,'TRADE_EXCHANGE' -trade, 'MARGIN_EXCHANGE' -margin trade, 'KUCOIN_BONUS' -bonus -func (ku *Kucoin) GetAccountLedgers(ctx context.Context, ccy currency.Code, direction, bizType string, startAt, endAt time.Time) (*AccountLedgerResponse, error) { +func (e *Exchange) GetAccountLedgers(ctx context.Context, ccy currency.Code, direction, bizType string, startAt, endAt time.Time) (*AccountLedgerResponse, error) { params := populateParams(ccy, direction, bizType, 0, 0, time.Time{}, time.Time{}) if !startAt.IsZero() && !endAt.IsZero() { err := common.StartEndTimeCheck(startAt, endAt) @@ -1802,28 +1802,28 @@ func (ku *Kucoin) GetAccountLedgers(ctx context.Context, ccy currency.Code, dire params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *AccountLedgerResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts/ledgers", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts/ledgers", params), nil, &resp) } // GetAccountLedgersHFTrade returns all transfer (in and out) records in high-frequency trading account and supports multi-coin queries. // The query results are sorted in descending order by createdAt and id. -func (ku *Kucoin) GetAccountLedgersHFTrade(ctx context.Context, ccy currency.Code, direction, bizType string, lastID, limit int64, startTime, endTime time.Time) ([]LedgerInfo, error) { +func (e *Exchange) GetAccountLedgersHFTrade(ctx context.Context, ccy currency.Code, direction, bizType string, lastID, limit int64, startTime, endTime time.Time) ([]LedgerInfo, error) { params := populateParams(ccy, direction, bizType, lastID, limit, startTime, endTime) var resp []LedgerInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfAccountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/accounts/ledgers", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfAccountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/hf/accounts/ledgers", params), nil, &resp) } // GetAccountLedgerHFMargin returns all transfer (in and out) records in high-frequency margin trading account and supports multi-coin queries. -func (ku *Kucoin) GetAccountLedgerHFMargin(ctx context.Context, ccy currency.Code, direction, bizType string, lastID, limit int64, startTime, endTime time.Time) ([]LedgerInfo, error) { +func (e *Exchange) GetAccountLedgerHFMargin(ctx context.Context, ccy currency.Code, direction, bizType string, lastID, limit int64, startTime, endTime time.Time) ([]LedgerInfo, error) { params := populateParams(ccy, direction, bizType, lastID, limit, startTime, endTime) var resp []LedgerInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfAccountLedgersMarginEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/account/ledgers", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, hfAccountLedgersMarginEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/account/ledgers", params), nil, &resp) } // GetFuturesAccountLedgers If there are open positions, the status of the first page returned will be Pending, // indicating the realised profit and loss in the current 8-hour settlement period. // Type RealisedPNL-Realised profit and loss, Deposit-Deposit, Withdrawal-withdraw, Transferin-Transfer in, TransferOut-Transfer out -func (ku *Kucoin) GetFuturesAccountLedgers(ctx context.Context, ccy currency.Code, forward bool, startAt, endAt time.Time, offset, maxCount int64) (*FuturesLedgerInfo, error) { +func (e *Exchange) GetFuturesAccountLedgers(ctx context.Context, ccy currency.Code, forward bool, startAt, endAt time.Time, offset, maxCount int64) (*FuturesLedgerInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -1846,17 +1846,17 @@ func (ku *Kucoin) GetFuturesAccountLedgers(ctx context.Context, ccy currency.Cod params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FuturesLedgerInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/transaction-history", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountLedgersEPL, http.MethodGet, common.EncodeURLValues("/v1/transaction-history", params), nil, &resp) } // GetAllSubAccountsInfoV1 retrieves the user info of all sub-account via this interface. -func (ku *Kucoin) GetAllSubAccountsInfoV1(ctx context.Context) ([]SubAccount, error) { +func (e *Exchange) GetAllSubAccountsInfoV1(ctx context.Context) ([]SubAccount, error) { var resp []SubAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountInfoV1EPL, http.MethodGet, "/v1/sub/user", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountInfoV1EPL, http.MethodGet, "/v1/sub/user", nil, &resp) } // GetAllSubAccountsInfoV2 retrieves list of sub-accounts. -func (ku *Kucoin) GetAllSubAccountsInfoV2(ctx context.Context, currentPage, pageSize int64) (*SubAccountV2Response, error) { +func (e *Exchange) GetAllSubAccountsInfoV2(ctx context.Context, currentPage, pageSize int64) (*SubAccountV2Response, error) { params := url.Values{} if currentPage > 0 { params.Set("currentPage", strconv.FormatInt(currentPage, 10)) @@ -1865,29 +1865,29 @@ func (ku *Kucoin) GetAllSubAccountsInfoV2(ctx context.Context, currentPage, page params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *SubAccountV2Response - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountsInfoV2EPL, http.MethodGet, "/v2/sub/user", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountsInfoV2EPL, http.MethodGet, "/v2/sub/user", nil, &resp) } // GetAccountSummaryInformation this can be used to obtain account summary information. -func (ku *Kucoin) GetAccountSummaryInformation(ctx context.Context) (*AccountSummaryInformation, error) { +func (e *Exchange) GetAccountSummaryInformation(ctx context.Context) (*AccountSummaryInformation, error) { var resp *AccountSummaryInformation - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountSummaryInfoEPL, http.MethodGet, "/v2/user-info", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, accountSummaryInfoEPL, http.MethodGet, "/v2/user-info", nil, &resp) } // GetAggregatedSubAccountBalance get the account info of all sub-users -func (ku *Kucoin) GetAggregatedSubAccountBalance(ctx context.Context) ([]SubAccountInfo, error) { +func (e *Exchange) GetAggregatedSubAccountBalance(ctx context.Context) ([]SubAccountInfo, error) { var resp []SubAccountInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountBalancesEPL, http.MethodGet, "/v1/sub-accounts", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, subAccountBalancesEPL, http.MethodGet, "/v1/sub-accounts", nil, &resp) } // GetAllSubAccountsBalanceV2 retrieves sub-account balance information through the V2 API -func (ku *Kucoin) GetAllSubAccountsBalanceV2(ctx context.Context) (*SubAccountsBalanceV2, error) { +func (e *Exchange) GetAllSubAccountsBalanceV2(ctx context.Context) (*SubAccountsBalanceV2, error) { var resp *SubAccountsBalanceV2 - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountBalancesV2EPL, http.MethodGet, "/v2/sub-accounts", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountBalancesV2EPL, http.MethodGet, "/v2/sub-accounts", nil, &resp) } // GetPaginatedSubAccountInformation this endpoint can be used to get paginated sub-account information. Pagination is required. -func (ku *Kucoin) GetPaginatedSubAccountInformation(ctx context.Context, currentPage, pageSize int64) ([]SubAccountInfo, error) { +func (e *Exchange) GetPaginatedSubAccountInformation(ctx context.Context, currentPage, pageSize int64) ([]SubAccountInfo, error) { params := url.Values{} if currentPage != 0 { params.Set("currentPage", strconv.FormatInt(currentPage, 10)) @@ -1896,12 +1896,12 @@ func (ku *Kucoin) GetPaginatedSubAccountInformation(ctx context.Context, current params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp []SubAccountInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountsBalanceEPL, http.MethodGet, common.EncodeURLValues("/v1/sub-accounts", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, allSubAccountsBalanceEPL, http.MethodGet, common.EncodeURLValues("/v1/sub-accounts", params), nil, &resp) } // GetTransferableBalance get the transferable balance of a specified account // The account type:MAIN、TRADE、TRADE_HF、MARGIN、ISOLATED -func (ku *Kucoin) GetTransferableBalance(ctx context.Context, ccy currency.Code, accountType, tag string) (*TransferableBalanceInfo, error) { +func (e *Exchange) GetTransferableBalance(ctx context.Context, ccy currency.Code, accountType, tag string) (*TransferableBalanceInfo, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1915,11 +1915,11 @@ func (ku *Kucoin) GetTransferableBalance(ctx context.Context, ccy currency.Code, params.Set("tag", tag) } var resp *TransferableBalanceInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getTransferablesEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts/transferable", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getTransferablesEPL, http.MethodGet, common.EncodeURLValues("/v1/accounts/transferable", params), nil, &resp) } // GetUniversalTransfer support transfer between master and sub accounts (only applicable to master account APIKey). -func (ku *Kucoin) GetUniversalTransfer(ctx context.Context, arg *UniversalTransferParam) (string, error) { +func (e *Exchange) GetUniversalTransfer(ctx context.Context, arg *UniversalTransferParam) (string, error) { if *arg == (UniversalTransferParam{}) { return "", common.ErrNilPointer } @@ -1939,11 +1939,11 @@ func (ku *Kucoin) GetUniversalTransfer(ctx context.Context, arg *UniversalTransf return "", fmt.Errorf("%w, toAccountType is empty", errAccountTypeMissing) } var resp string - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, flexiTransferEPL, http.MethodPost, "/v3/accounts/universal-transfer", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, flexiTransferEPL, http.MethodPost, "/v3/accounts/universal-transfer", arg, &resp) } // TransferMainToSubAccount used to transfer funds from main account to sub-account -func (ku *Kucoin) TransferMainToSubAccount(ctx context.Context, ccy currency.Code, amount float64, clientOID, direction, accountType, subAccountType, subUserID string) (string, error) { +func (e *Exchange) TransferMainToSubAccount(ctx context.Context, ccy currency.Code, amount float64, clientOID, direction, accountType, subAccountType, subUserID string) (string, error) { if clientOID == "" { return "", order.ErrClientOrderIDMustBeSet } @@ -1979,12 +1979,12 @@ func (ku *Kucoin) TransferMainToSubAccount(ctx context.Context, ccy currency.Cod resp := struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, masterSubUserTransferEPL, http.MethodPost, "/v2/accounts/sub-transfer", arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, masterSubUserTransferEPL, http.MethodPost, "/v2/accounts/sub-transfer", arg, &resp) } // MakeInnerTransfer used to transfer funds between accounts internally // possible account types: main, trade, trade_hf, margin, isolated, margin_v2, isolated_v2, contract -func (ku *Kucoin) MakeInnerTransfer(ctx context.Context, amount float64, ccy currency.Code, clientOID, paymentAccountType, receivingAccountType, fromTag, toTag string) (string, error) { +func (e *Exchange) MakeInnerTransfer(ctx context.Context, amount float64, ccy currency.Code, clientOID, paymentAccountType, receivingAccountType, fromTag, toTag string) (string, error) { if ccy.IsEmpty() { return "", currency.ErrCurrencyCodeEmpty } @@ -2020,11 +2020,11 @@ func (ku *Kucoin) MakeInnerTransfer(ctx context.Context, amount float64, ccy cur resp := struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, innerTransferEPL, http.MethodPost, "/v2/accounts/inner-transfer", arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, innerTransferEPL, http.MethodPost, "/v2/accounts/inner-transfer", arg, &resp) } // TransferToMainOrTradeAccount transfers fund from KuCoin Futures account to Main or Trade accounts. -func (ku *Kucoin) TransferToMainOrTradeAccount(ctx context.Context, arg *FundTransferFuturesParam) (*InnerTransferToMainAndTradeResponse, error) { +func (e *Exchange) TransferToMainOrTradeAccount(ctx context.Context, arg *FundTransferFuturesParam) (*InnerTransferToMainAndTradeResponse, error) { if *arg == (FundTransferFuturesParam{}) { return nil, common.ErrNilPointer } @@ -2038,11 +2038,11 @@ func (ku *Kucoin) TransferToMainOrTradeAccount(ctx context.Context, arg *FundTra return nil, fmt.Errorf("invalid receive account type %s, only TRADE and MAIN are supported", arg.RecieveAccountType) } var resp *InnerTransferToMainAndTradeResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, toMainOrTradeAccountEPL, http.MethodPost, "/v3/transfer-out", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, toMainOrTradeAccountEPL, http.MethodPost, "/v3/transfer-out", arg, &resp) } // TransferToFuturesAccount transfers fund from KuCoin Futures account to Main or Trade accounts. -func (ku *Kucoin) TransferToFuturesAccount(ctx context.Context, arg *FundTransferToFuturesParam) (*FundTransferToFuturesResponse, error) { +func (e *Exchange) TransferToFuturesAccount(ctx context.Context, arg *FundTransferToFuturesParam) (*FundTransferToFuturesResponse, error) { if *arg == (FundTransferToFuturesParam{}) { return nil, common.ErrNilPointer } @@ -2056,11 +2056,11 @@ func (ku *Kucoin) TransferToFuturesAccount(ctx context.Context, arg *FundTransfe return nil, fmt.Errorf("invalid receive account type %s, only TRADE and MAIN are supported", arg.PaymentAccountType) } var resp *FundTransferToFuturesResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, toFuturesAccountEPL, http.MethodPost, "/v1/transfer-in", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, toFuturesAccountEPL, http.MethodPost, "/v1/transfer-in", arg, &resp) } // GetFuturesTransferOutRequestRecords retrieves futures transfers out requests. -func (ku *Kucoin) GetFuturesTransferOutRequestRecords(ctx context.Context, startAt, endAt time.Time, status, queryStatus string, ccy currency.Code, currentPage, pageSize int64) (*FuturesTransferOutResponse, error) { +func (e *Exchange) GetFuturesTransferOutRequestRecords(ctx context.Context, startAt, endAt time.Time, status, queryStatus string, ccy currency.Code, currentPage, pageSize int64) (*FuturesTransferOutResponse, error) { params := url.Values{} if !startAt.IsZero() { params.Set("startAt", strconv.FormatInt(startAt.UnixMilli(), 10)) @@ -2084,31 +2084,31 @@ func (ku *Kucoin) GetFuturesTransferOutRequestRecords(ctx context.Context, start params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *FuturesTransferOutResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransferOutRequestRecordsEPL, http.MethodGet, common.EncodeURLValues("/v1/transfer-list", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransferOutRequestRecordsEPL, http.MethodGet, common.EncodeURLValues("/v1/transfer-list", params), nil, &resp) } // CreateDepositAddress create a deposit address for a currency you intend to deposit -func (ku *Kucoin) CreateDepositAddress(ctx context.Context, arg *DepositAddressParams) (*DepositAddress, error) { +func (e *Exchange) CreateDepositAddress(ctx context.Context, arg *DepositAddressParams) (*DepositAddress, error) { if arg.Currency.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp *DepositAddress - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, createDepositAddressEPL, http.MethodPost, "/v1/deposit-addresses", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, createDepositAddressEPL, http.MethodPost, "/v1/deposit-addresses", arg, &resp) } // GetDepositAddressesV2 get all deposit addresses for the currency you intend to deposit -func (ku *Kucoin) GetDepositAddressesV2(ctx context.Context, ccy currency.Code) ([]DepositAddress, error) { +func (e *Exchange) GetDepositAddressesV2(ctx context.Context, ccy currency.Code) ([]DepositAddress, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("currency", ccy.String()) var resp []DepositAddress - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositAddressesV2EPL, http.MethodGet, common.EncodeURLValues("/v2/deposit-addresses", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositAddressesV2EPL, http.MethodGet, common.EncodeURLValues("/v2/deposit-addresses", params), nil, &resp) } // GetDepositAddressV1 get a deposit address for the currency you intend to deposit -func (ku *Kucoin) GetDepositAddressV1(ctx context.Context, ccy currency.Code, chain string) (*DepositAddress, error) { +func (e *Exchange) GetDepositAddressV1(ctx context.Context, ccy currency.Code, chain string) (*DepositAddress, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2118,12 +2118,12 @@ func (ku *Kucoin) GetDepositAddressV1(ctx context.Context, ccy currency.Code, ch params.Set("chain", chain) } var resp *DepositAddress - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositAddressesV1EPL, http.MethodGet, common.EncodeURLValues("/v1/deposit-addresses", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositAddressesV1EPL, http.MethodGet, common.EncodeURLValues("/v1/deposit-addresses", params), nil, &resp) } // GetDepositList get deposit list items and sorted to show the latest first // Status. Available value: PROCESSING, SUCCESS, and FAILURE -func (ku *Kucoin) GetDepositList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*DepositResponse, error) { +func (e *Exchange) GetDepositList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*DepositResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -2138,11 +2138,11 @@ func (ku *Kucoin) GetDepositList(ctx context.Context, ccy currency.Code, status params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *DepositResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositListEPL, http.MethodGet, common.EncodeURLValues("/v1/deposits", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, depositListEPL, http.MethodGet, common.EncodeURLValues("/v1/deposits", params), nil, &resp) } // GetHistoricalDepositList get historical deposit list items -func (ku *Kucoin) GetHistoricalDepositList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*HistoricalDepositWithdrawalResponse, error) { +func (e *Exchange) GetHistoricalDepositList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*HistoricalDepositWithdrawalResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -2157,11 +2157,11 @@ func (ku *Kucoin) GetHistoricalDepositList(ctx context.Context, ccy currency.Cod params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *HistoricalDepositWithdrawalResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, historicDepositListEPL, http.MethodGet, common.EncodeURLValues("/v1/hist-deposits", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, historicDepositListEPL, http.MethodGet, common.EncodeURLValues("/v1/hist-deposits", params), nil, &resp) } // GetWithdrawalList get withdrawal list items -func (ku *Kucoin) GetWithdrawalList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*WithdrawalsResponse, error) { +func (e *Exchange) GetWithdrawalList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*WithdrawalsResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -2176,11 +2176,11 @@ func (ku *Kucoin) GetWithdrawalList(ctx context.Context, ccy currency.Code, stat params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *WithdrawalsResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, withdrawalListEPL, http.MethodGet, common.EncodeURLValues("/v1/withdrawals", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, withdrawalListEPL, http.MethodGet, common.EncodeURLValues("/v1/withdrawals", params), nil, &resp) } // GetHistoricalWithdrawalList get historical withdrawal list items -func (ku *Kucoin) GetHistoricalWithdrawalList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*HistoricalDepositWithdrawalResponse, error) { +func (e *Exchange) GetHistoricalWithdrawalList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*HistoricalDepositWithdrawalResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -2195,11 +2195,11 @@ func (ku *Kucoin) GetHistoricalWithdrawalList(ctx context.Context, ccy currency. params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *HistoricalDepositWithdrawalResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, retrieveV1HistoricalWithdrawalListEPL, http.MethodGet, common.EncodeURLValues("/v1/hist-withdrawals", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, retrieveV1HistoricalWithdrawalListEPL, http.MethodGet, common.EncodeURLValues("/v1/hist-withdrawals", params), nil, &resp) } // GetWithdrawalQuotas get withdrawal quota details -func (ku *Kucoin) GetWithdrawalQuotas(ctx context.Context, ccy currency.Code, chain string) (*WithdrawalQuota, error) { +func (e *Exchange) GetWithdrawalQuotas(ctx context.Context, ccy currency.Code, chain string) (*WithdrawalQuota, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2209,7 +2209,7 @@ func (ku *Kucoin) GetWithdrawalQuotas(ctx context.Context, ccy currency.Code, ch params.Set("chain", chain) } var resp *WithdrawalQuota - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, withdrawalQuotaEPL, http.MethodGet, common.EncodeURLValues("/v1/withdrawals/quotas", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, withdrawalQuotaEPL, http.MethodGet, common.EncodeURLValues("/v1/withdrawals/quotas", params), nil, &resp) } // ApplyWithdrawal create a withdrawal request @@ -2219,7 +2219,7 @@ func (ku *Kucoin) GetWithdrawalQuotas(ctx context.Context, ccy currency.Code, ch // TIP: On the WEB end, you can open the switch of specified favorite addresses for withdrawal, and when it is turned on, // it will verify whether your withdrawal address(including chain) is a favorite address(it is case sensitive); if it fails validation, // it will respond with the error message {"msg":"Already set withdraw whitelist, this address is not favorite address","code":"260325"}. -func (ku *Kucoin) ApplyWithdrawal(ctx context.Context, ccy currency.Code, address, memo, remark, chain, feeDeductType string, isInner bool, amount float64) (string, error) { +func (e *Exchange) ApplyWithdrawal(ctx context.Context, ccy currency.Code, address, memo, remark, chain, feeDeductType string, isInner bool, amount float64) (string, error) { if ccy.IsEmpty() { return "", currency.ErrCurrencyCodeEmpty } @@ -2252,61 +2252,61 @@ func (ku *Kucoin) ApplyWithdrawal(ctx context.Context, ccy currency.Code, addres WithdrawalID string `json:"withdrawalId"` Error }{} - return resp.WithdrawalID, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, applyWithdrawalEPL, http.MethodPost, "/v1/withdrawals", arg, &resp) + return resp.WithdrawalID, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, applyWithdrawalEPL, http.MethodPost, "/v1/withdrawals", arg, &resp) } // CancelWithdrawal used to cancel a withdrawal request -func (ku *Kucoin) CancelWithdrawal(ctx context.Context, withdrawalID string) error { +func (e *Exchange) CancelWithdrawal(ctx context.Context, withdrawalID string) error { if withdrawalID == "" { return fmt.Errorf("%w withdrawal ID is required", order.ErrOrderIDNotSet) } - return ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalsEPL, http.MethodDelete, "/v1/withdrawals/"+withdrawalID, nil, &struct{}{}) + return e.SendAuthHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalsEPL, http.MethodDelete, "/v1/withdrawals/"+withdrawalID, nil, &struct{}{}) } // GetBasicFee get basic fee rate of users // Currency type: '0'-crypto currency, '1'-fiat currency. default is '0'-crypto currency -func (ku *Kucoin) GetBasicFee(ctx context.Context, currencyType string) (*Fees, error) { +func (e *Exchange) GetBasicFee(ctx context.Context, currencyType string) (*Fees, error) { params := url.Values{} if currencyType != "" { params.Set("currencyType", currencyType) } var resp *Fees - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, basicFeesEPL, http.MethodGet, common.EncodeURLValues("/v1/base-fee", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, basicFeesEPL, http.MethodGet, common.EncodeURLValues("/v1/base-fee", params), nil, &resp) } // GetTradingFee get fee rate of trading pairs // WARNING: There is a limit of 10 currency pairs allowed to be requested per call. -func (ku *Kucoin) GetTradingFee(ctx context.Context, pairs currency.Pairs) ([]Fees, error) { +func (e *Exchange) GetTradingFee(ctx context.Context, pairs currency.Pairs) ([]Fees, error) { if len(pairs) == 0 { return nil, currency.ErrCurrencyPairsEmpty } var resp []Fees - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, tradeFeesEPL, http.MethodGet, "/v1/trade-fees?symbols="+pairs.Upper().Join(), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, tradeFeesEPL, http.MethodGet, "/v1/trade-fees?symbols="+pairs.Upper().Join(), nil, &resp) } // ---------------------------------------------------------- Lending Market ---------------------------------------------------------------------------- // GetLendingCurrencyInformation retrieves a lending currency information. -func (ku *Kucoin) GetLendingCurrencyInformation(ctx context.Context, ccy currency.Code) ([]LendingCurrencyInfo, error) { +func (e *Exchange) GetLendingCurrencyInformation(ctx context.Context, ccy currency.Code) ([]LendingCurrencyInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []LendingCurrencyInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, lendingCurrencyInfoEPL, http.MethodGet, common.EncodeURLValues("/v3/project/list", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, lendingCurrencyInfoEPL, http.MethodGet, common.EncodeURLValues("/v3/project/list", params), nil, &resp) } // GetInterestRate retrieves the interest rates of the margin lending market over the past 7 days. -func (ku *Kucoin) GetInterestRate(ctx context.Context, ccy currency.Code) ([]InterestRate, error) { +func (e *Exchange) GetInterestRate(ctx context.Context, ccy currency.Code) ([]InterestRate, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } var resp []InterestRate - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, interestRateEPL, http.MethodGet, "/v3/project/marketInterestRate?currency="+ccy.String(), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, interestRateEPL, http.MethodGet, "/v3/project/marketInterestRate?currency="+ccy.String(), nil, &resp) } // MarginLendingSubscription retrieves margin lending subscription information. -func (ku *Kucoin) MarginLendingSubscription(ctx context.Context, ccy currency.Code, size, interestRate float64) (*OrderNumberResponse, error) { +func (e *Exchange) MarginLendingSubscription(ctx context.Context, ccy currency.Code, size, interestRate float64) (*OrderNumberResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2326,11 +2326,11 @@ func (ku *Kucoin) MarginLendingSubscription(ctx context.Context, ccy currency.Co InterestRate: interestRate, } var resp *OrderNumberResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginLendingSubscriptionEPL, http.MethodPost, "/v3/purchase", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginLendingSubscriptionEPL, http.MethodPost, "/v3/purchase", arg, &resp) } // Redemption initiate redemptions of margin lending. -func (ku *Kucoin) Redemption(ctx context.Context, ccy currency.Code, size float64, purchaseOrderNo string) (*OrderNumberResponse, error) { +func (e *Exchange) Redemption(ctx context.Context, ccy currency.Code, size float64, purchaseOrderNo string) (*OrderNumberResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2350,11 +2350,11 @@ func (ku *Kucoin) Redemption(ctx context.Context, ccy currency.Code, size float6 PurchaseOrderNumber: purchaseOrderNo, } var resp *OrderNumberResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, redemptionEPL, http.MethodPost, "/v3/redeem", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, redemptionEPL, http.MethodPost, "/v3/redeem", arg, &resp) } // ModifySubscriptionOrder is used to update the interest rates of subscription orders, which will take effect at the beginning of the next hour. -func (ku *Kucoin) ModifySubscriptionOrder(ctx context.Context, ccy currency.Code, purchaseOrderNo string, interestRate float64) (*ModifySubscriptionOrderResponse, error) { +func (e *Exchange) ModifySubscriptionOrder(ctx context.Context, ccy currency.Code, purchaseOrderNo string, interestRate float64) (*ModifySubscriptionOrderResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2370,12 +2370,12 @@ func (ku *Kucoin) ModifySubscriptionOrder(ctx context.Context, ccy currency.Code "purchaseOrderNo": purchaseOrderNo, } var resp *ModifySubscriptionOrderResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubscriptionEPL, http.MethodPost, "/v3/lend/purchase/update", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifySubscriptionEPL, http.MethodPost, "/v3/lend/purchase/update", arg, &resp) } // GetRedemptionOrders query for the redemption orders. // Status: DONE-completed; PENDING-settling -func (ku *Kucoin) GetRedemptionOrders(ctx context.Context, ccy currency.Code, status, redeemOrderNo string, currentPage, pageSize int64) (*RedemptionOrdersResponse, error) { +func (e *Exchange) GetRedemptionOrders(ctx context.Context, ccy currency.Code, status, redeemOrderNo string, currentPage, pageSize int64) (*RedemptionOrdersResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2395,11 +2395,11 @@ func (ku *Kucoin) GetRedemptionOrders(ctx context.Context, ccy currency.Code, st params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *RedemptionOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getRedemptionOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/redeem/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getRedemptionOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/redeem/orders", params), nil, &resp) } // GetSubscriptionOrders provides pagination query for the subscription orders. -func (ku *Kucoin) GetSubscriptionOrders(ctx context.Context, ccy currency.Code, purchaseOrderNo, status string, currentPage, pageSize int64) (*PurchaseSubscriptionOrdersResponse, error) { +func (e *Exchange) GetSubscriptionOrders(ctx context.Context, ccy currency.Code, purchaseOrderNo, status string, currentPage, pageSize int64) (*PurchaseSubscriptionOrdersResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2419,11 +2419,11 @@ func (ku *Kucoin) GetSubscriptionOrders(ctx context.Context, ccy currency.Code, params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *PurchaseSubscriptionOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, getSubscriptionOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/purchase/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, getSubscriptionOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/purchase/orders", params), nil, &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (ku *Kucoin) SendHTTPRequest(ctx context.Context, ePath exchange.URL, epl request.EndpointLimit, path string, result any) error { +func (e *Exchange) SendHTTPRequest(ctx context.Context, ePath exchange.URL, epl request.EndpointLimit, path string, result any) error { value := reflect.ValueOf(result) if value.Kind() != reflect.Pointer { return errInvalidResultInterface @@ -2432,18 +2432,18 @@ func (ku *Kucoin) SendHTTPRequest(ctx context.Context, ePath exchange.URL, epl r if !okay { resp = &Response{Data: result} } - endpointPath, err := ku.API.Endpoints.GetURL(ePath) + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } - err = ku.SendPayload(ctx, epl, func() (*request.Item, error) { + err = e.SendPayload(ctx, epl, func() (*request.Item, error) { return &request.Item{ Method: http.MethodGet, Path: endpointPath + path, Result: resp, - Verbose: ku.Verbose, - HTTPDebugging: ku.HTTPDebugging, - HTTPRecording: ku.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.UnauthenticatedRequest) if err != nil { @@ -2457,12 +2457,12 @@ func (ku *Kucoin) SendHTTPRequest(ctx context.Context, ePath exchange.URL, epl r // SendAuthHTTPRequest sends an authenticated HTTP request // Request parameters are added to path variable for GET and DELETE request and for other requests its passed in params variable -func (ku *Kucoin) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, epl request.EndpointLimit, method, path string, arg, result any) error { +func (e *Exchange) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, epl request.EndpointLimit, method, path string, arg, result any) error { value := reflect.ValueOf(result) if value.Kind() != reflect.Pointer { return errInvalidResultInterface } - creds, err := ku.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -2470,14 +2470,14 @@ func (ku *Kucoin) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, e if !okay { resp = &Response{Data: result} } - endpointPath, err := ku.API.Endpoints.GetURL(ePath) + endpointPath, err := e.API.Endpoints.GetURL(ePath) if err != nil { return err } if value.IsNil() || value.Kind() != reflect.Pointer { return fmt.Errorf("%w receiver has to be non-nil pointer", errInvalidResponseReceiver) } - err = ku.SendPayload(ctx, epl, func() (*request.Item, error) { + err = e.SendPayload(ctx, epl, func() (*request.Item, error) { var ( body io.Reader payload []byte @@ -2512,9 +2512,9 @@ func (ku *Kucoin) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, e Headers: headers, Body: body, Result: &resp, - Verbose: ku.Verbose, - HTTPDebugging: ku.HTTPDebugging, - HTTPRecording: ku.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) if err != nil { @@ -2541,7 +2541,7 @@ func IntervalToString(interval kline.Interval) (string, error) { } // StringToOrderStatus returns an order.Status instance from string. -func (ku *Kucoin) StringToOrderStatus(status string) (order.Status, error) { +func (e *Exchange) StringToOrderStatus(status string) (order.Status, error) { switch status { case "match": return order.Filled, nil @@ -2555,7 +2555,7 @@ func (ku *Kucoin) StringToOrderStatus(status string) (order.Status, error) { } // AccountToTradeTypeString returns the account trade type given the asset type and margin mode information for spot and margin assets. -func (ku *Kucoin) AccountToTradeTypeString(a asset.Item, marginMode string) string { +func (e *Exchange) AccountToTradeTypeString(a asset.Item, marginMode string) string { switch a { case asset.Spot: return SpotTradeType @@ -2570,7 +2570,7 @@ func (ku *Kucoin) AccountToTradeTypeString(a asset.Item, marginMode string) stri } // OrderSideString converts an order.Side instance to a string representation -func (ku *Kucoin) OrderSideString(side order.Side) (string, error) { +func (e *Exchange) OrderSideString(side order.Side) (string, error) { switch { case side.IsLong(): return order.Buy.Lower(), nil @@ -2584,19 +2584,19 @@ func (ku *Kucoin) OrderSideString(side order.Side) (string, error) { } // GetTradingPairActualFees retrieves list of trading pairs and fees. -func (ku *Kucoin) GetTradingPairActualFees(ctx context.Context, symbols []string) ([]TradingPairFee, error) { +func (e *Exchange) GetTradingPairActualFees(ctx context.Context, symbols []string) ([]TradingPairFee, error) { params := url.Values{} if len(symbols) > 0 { params.Set("symbols", strings.Join(symbols, ",")) } var resp []TradingPairFee - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, tradingPairActualFeeEPL, http.MethodGet, common.EncodeURLValues("/v1/trade-fees", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, tradingPairActualFeeEPL, http.MethodGet, common.EncodeURLValues("/v1/trade-fees", params), nil, &resp) } // ----------------------------------------------------------- Earn Endpoints ---------------------------------------------------------------- // SubscribeToEarnFixedIncomeProduct allows subscribing to fixed income products. If the subscription fails, it returns the corresponding error code. -func (ku *Kucoin) SubscribeToEarnFixedIncomeProduct(ctx context.Context, productID, accountType string, amount float64) (*SusbcribeEarn, error) { +func (e *Exchange) SubscribeToEarnFixedIncomeProduct(ctx context.Context, productID, accountType string, amount float64) (*SusbcribeEarn, error) { if productID == "" { return nil, errProductIDMissing } @@ -2607,7 +2607,7 @@ func (ku *Kucoin) SubscribeToEarnFixedIncomeProduct(ctx context.Context, product return nil, errAccountTypeMissing } var resp *SusbcribeEarn - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, subscribeToEarnEPL, http.MethodPost, "/v1/earn/orders", + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, subscribeToEarnEPL, http.MethodPost, "/v1/earn/orders", &map[string]any{ "productId": productID, "accountType": accountType, @@ -2619,7 +2619,7 @@ func (ku *Kucoin) SubscribeToEarnFixedIncomeProduct(ctx context.Context, product // If the current holding is fully redeemed or in the process of being redeemed, it indicates that the holding does not exist. // Confirmation field for early redemption penalty: 1 (confirm early redemption, and the current holding will be fully redeemed). // This parameter is valid only for fixed-term products -func (ku *Kucoin) RedeemByEarnHoldingID(ctx context.Context, orderID, fromAccountType, confirmPunishRedeem string, amount float64) (*EarnRedeem, error) { +func (e *Exchange) RedeemByEarnHoldingID(ctx context.Context, orderID, fromAccountType, confirmPunishRedeem string, amount float64) (*EarnRedeem, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2636,12 +2636,12 @@ func (ku *Kucoin) RedeemByEarnHoldingID(ctx context.Context, orderID, fromAccoun params.Set("confirmPunishRedeem", confirmPunishRedeem) } var resp *EarnRedeem - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnRedemptionEPL, http.MethodDelete, common.EncodeURLValues("/v1/earn/orders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnRedemptionEPL, http.MethodDelete, common.EncodeURLValues("/v1/earn/orders", params), nil, &resp) } // GetEarnRedeemPreviewByHoldingID retrieves redemption preview information by holding ID. // If the current holding is fully redeemed or in the process of being redeemed, it indicates that the holding does not exist. -func (ku *Kucoin) GetEarnRedeemPreviewByHoldingID(ctx context.Context, orderID, fromAccountType string) (*EarnRedemptionPreview, error) { +func (e *Exchange) GetEarnRedeemPreviewByHoldingID(ctx context.Context, orderID, fromAccountType string) (*EarnRedemptionPreview, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2651,23 +2651,23 @@ func (ku *Kucoin) GetEarnRedeemPreviewByHoldingID(ctx context.Context, orderID, params.Set("fromAccountType", fromAccountType) } var resp *EarnRedemptionPreview - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnRedemptionPreviewEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/redeem-preview", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnRedemptionPreviewEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/redeem-preview", params), nil, &resp) } // ---------------------------------------------------------------- Kucoin Earn ---------------------------------------------------------------- // GetEarnSavingsProducts retrieves savings products. If no savings products are available, an empty list is returned. -func (ku *Kucoin) GetEarnSavingsProducts(ctx context.Context, ccy currency.Code) ([]EarnSavingProduct, error) { +func (e *Exchange) GetEarnSavingsProducts(ctx context.Context, ccy currency.Code) ([]EarnSavingProduct, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []EarnSavingProduct - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, kucoinEarnSavingsProductsEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/saving/products", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, kucoinEarnSavingsProductsEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/saving/products", params), nil, &resp) } // GetEarnFixedIncomeCurrentHoldings retrieves current holding assets of fixed income products. If no current holding assets are available, an empty list is returned. -func (ku *Kucoin) GetEarnFixedIncomeCurrentHoldings(ctx context.Context, productID, productCategory string, ccy currency.Code, currentPage, pageSize int64) (*FixedIncomeEarnHoldings, error) { +func (e *Exchange) GetEarnFixedIncomeCurrentHoldings(ctx context.Context, productID, productCategory string, ccy currency.Code, currentPage, pageSize int64) (*FixedIncomeEarnHoldings, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) @@ -2685,63 +2685,63 @@ func (ku *Kucoin) GetEarnFixedIncomeCurrentHoldings(ctx context.Context, product params.Set("pageSize", strconv.FormatInt(pageSize, 10)) } var resp *FixedIncomeEarnHoldings - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, kucoinEarnFixedIncomeCurrentHoldingEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/hold-assets", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, kucoinEarnFixedIncomeCurrentHoldingEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/hold-assets", params), nil, &resp) } // GetLimitedTimePromotionProducts retrieves limited-time promotion products. If no products are available, an empty list is returned. -func (ku *Kucoin) GetLimitedTimePromotionProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { +func (e *Exchange) GetLimitedTimePromotionProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []EarnProduct - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnLimitedTimePromotionProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/promotion/products", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnLimitedTimePromotionProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/promotion/products", params), nil, &resp) } // ---------------------------------------------------------------- Staking Endpoints ---------------------------------------------------------------- // GetEarnKCSStakingProducts retrieves KCS Staking products. If no KCS Staking products are available, an empty list is returned. -func (ku *Kucoin) GetEarnKCSStakingProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { +func (e *Exchange) GetEarnKCSStakingProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []EarnProduct - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnKCSStakingProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/kcs-staking/products", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnKCSStakingProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/kcs-staking/products", params), nil, &resp) } // GetEarnStakingProducts retrieves staking products. If no staking products are available, an empty list is returned. -func (ku *Kucoin) GetEarnStakingProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { +func (e *Exchange) GetEarnStakingProducts(ctx context.Context, ccy currency.Code) ([]EarnProduct, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } var resp []EarnProduct - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnStakingProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/staking/products", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnStakingProductEPL, http.MethodGet, common.EncodeURLValues("/v1/earn/staking/products", params), nil, &resp) } // GetEarnETHStakingProducts retrieves ETH Staking products. If no ETH Staking products are available, an empty list is returned. -func (ku *Kucoin) GetEarnETHStakingProducts(ctx context.Context) ([]EarnProduct, error) { +func (e *Exchange) GetEarnETHStakingProducts(ctx context.Context) ([]EarnProduct, error) { var resp []EarnProduct - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnStakingProductEPL, http.MethodGet, "/v1/earn/eth-staking/products", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, earnStakingProductEPL, http.MethodGet, "/v1/earn/eth-staking/products", nil, &resp) } // ---------------------------------------------------------------- VIP Lending ---------------------------------------------------------------- // GetInformationOnOffExchangeFundingAndLoans retrieves accounts that are currently involved in loans. -func (ku *Kucoin) GetInformationOnOffExchangeFundingAndLoans(ctx context.Context) (*OffExchangeFundingAndLoan, error) { +func (e *Exchange) GetInformationOnOffExchangeFundingAndLoans(ctx context.Context) (*OffExchangeFundingAndLoan, error) { var resp *OffExchangeFundingAndLoan - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, vipLendingEPL, http.MethodGet, "/v1/otc-loan/loan", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, vipLendingEPL, http.MethodGet, "/v1/otc-loan/loan", nil, &resp) } // GetInformationOnAccountInvolvedInOffExchangeLoans retrieves accounts that are currently involved in off-exchange loans. -func (ku *Kucoin) GetInformationOnAccountInvolvedInOffExchangeLoans(ctx context.Context) ([]VIPLendingAccounts, error) { +func (e *Exchange) GetInformationOnAccountInvolvedInOffExchangeLoans(ctx context.Context) ([]VIPLendingAccounts, error) { var resp []VIPLendingAccounts - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, vipLendingEPL, http.MethodGet, "/v1/otc-loan/accounts", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, vipLendingEPL, http.MethodGet, "/v1/otc-loan/accounts", nil, &resp) } // GetAffilateUserRebateInformation allows getting affiliate user rebate information. -func (ku *Kucoin) GetAffilateUserRebateInformation(ctx context.Context, date time.Time, offset string, maxCount int64) ([]UserRebateInfo, error) { +func (e *Exchange) GetAffilateUserRebateInformation(ctx context.Context, date time.Time, offset string, maxCount int64) ([]UserRebateInfo, error) { if date.IsZero() { return nil, errQueryDateIsRequired } @@ -2756,22 +2756,22 @@ func (ku *Kucoin) GetAffilateUserRebateInformation(ctx context.Context, date tim params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp []UserRebateInfo - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, affilateUserRebateInfoEPL, http.MethodGet, common.EncodeURLValues("/v2/affiliate/inviter/statistics", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, affilateUserRebateInfoEPL, http.MethodGet, common.EncodeURLValues("/v2/affiliate/inviter/statistics", params), nil, &resp) } // GetMarginPairsConfigurations allows querying the configuration of cross margin trading pairs. -func (ku *Kucoin) GetMarginPairsConfigurations(ctx context.Context, symbol string) (*MarginPairConfigs, error) { +func (e *Exchange) GetMarginPairsConfigurations(ctx context.Context, symbol string) (*MarginPairConfigs, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var resp *MarginPairConfigs - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginPairsConfigurationEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/symbols", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginPairsConfigurationEPL, http.MethodGet, common.EncodeURLValues("/v3/margin/symbols", params), nil, &resp) } // ModifyLeverageMultiplier this endpoint allows modifying the leverage multiplier for cross margin or isolated margin -func (ku *Kucoin) ModifyLeverageMultiplier(ctx context.Context, symbol string, leverage int64, isIsolated bool) error { +func (e *Exchange) ModifyLeverageMultiplier(ctx context.Context, symbol string, leverage int64, isIsolated bool) error { if leverage <= 0 { return errInvalidLeverage } @@ -2784,18 +2784,18 @@ func (ku *Kucoin) ModifyLeverageMultiplier(ctx context.Context, symbol string, l Leverage: leverage, IsIsolated: isIsolated, } - return ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifyLeverageMultiplierEPL, http.MethodPost, "/v3/position/update-user-leverage", arg, &struct{}{}) + return e.SendAuthHTTPRequest(ctx, exchange.RestSpot, modifyLeverageMultiplierEPL, http.MethodPost, "/v3/position/update-user-leverage", arg, &struct{}{}) } // GetActiveHFOrderSymbols retrieves the symbols of active high-frequency orders. // Possible values for tradeType are MARGIN_TRADE for cross-margin trading // and MARGIN_ISOLATED_TRADE for isolated margin trading. -func (ku *Kucoin) GetActiveHFOrderSymbols(ctx context.Context, tradeType string) (*MarginActiveSymbolDetail, error) { +func (e *Exchange) GetActiveHFOrderSymbols(ctx context.Context, tradeType string) (*MarginActiveSymbolDetail, error) { if tradeType == "" { return nil, errTradeTypeMissing } params := url.Values{} params.Set("tradeType", tradeType) var resp *MarginActiveSymbolDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginActiveHFOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/order/active/symbols", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, marginActiveHFOrdersEPL, http.MethodGet, common.EncodeURLValues("/v3/hf/margin/order/active/symbols", params), nil, &resp) } diff --git a/exchanges/kucoin/kucoin_futures.go b/exchanges/kucoin/kucoin_futures.go index b6f87109902..23fc6bddea2 100644 --- a/exchanges/kucoin/kucoin_futures.go +++ b/exchanges/kucoin/kucoin_futures.go @@ -31,32 +31,32 @@ const ( ) // GetFuturesOpenContracts gets all open futures contract with its details -func (ku *Kucoin) GetFuturesOpenContracts(ctx context.Context) ([]Contract, error) { +func (e *Exchange) GetFuturesOpenContracts(ctx context.Context) ([]Contract, error) { var resp []Contract - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresOpenContractsEPL, "/v1/contracts/active", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresOpenContractsEPL, "/v1/contracts/active", &resp) } // GetFuturesContract get contract details -func (ku *Kucoin) GetFuturesContract(ctx context.Context, symbol string) (*Contract, error) { +func (e *Exchange) GetFuturesContract(ctx context.Context, symbol string) (*Contract, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *Contract - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresContractEPL, "/v1/contracts/"+symbol, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresContractEPL, "/v1/contracts/"+symbol, &resp) } // GetFuturesTicker get real time ticker -func (ku *Kucoin) GetFuturesTicker(ctx context.Context, symbol string) (*FuturesTicker, error) { +func (e *Exchange) GetFuturesTicker(ctx context.Context, symbol string) (*FuturesTicker, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *FuturesTicker - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickerEPL, "/v1/ticker?symbol="+symbol, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickerEPL, "/v1/ticker?symbol="+symbol, &resp) } // GetFuturesTickers does n * REST requests based on enabled pairs of the futures asset type -func (ku *Kucoin) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error) { - pairs, err := ku.GetEnabledPairs(asset.Futures) +func (e *Exchange) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error) { + pairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func (ku *Kucoin) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error for i := range pairs { var p currency.Pair - if p, err = ku.FormatExchangeCurrency(pairs[i], asset.Futures); err != nil { + if p, err = e.FormatExchangeCurrency(pairs[i], asset.Futures); err != nil { errC <- err break } @@ -75,7 +75,7 @@ func (ku *Kucoin) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error go func() { defer wg.Done() - if tick, err2 := ku.GetFuturesTicker(ctx, p.String()); err2 != nil { + if tick, err2 := e.GetFuturesTicker(ctx, p.String()); err2 != nil { errC <- err2 } else { tickersC <- &ticker.Price{ @@ -87,7 +87,7 @@ func (ku *Kucoin) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error Volume: tick.Size, Pair: p, LastUpdated: tick.FilledTime.Time(), - ExchangeName: ku.Name, + ExchangeName: e.Name, AssetType: asset.Futures, } } @@ -113,14 +113,14 @@ func (ku *Kucoin) GetFuturesTickers(ctx context.Context) ([]*ticker.Price, error } // GetFuturesOrderbook gets full orderbook for a specified symbol -func (ku *Kucoin) GetFuturesOrderbook(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetFuturesOrderbook(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o futuresOrderbookResponse - err := ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresOrderbookEPL, common.EncodeURLValues("/v1/level2/snapshot", params), &o) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, futuresOrderbookEPL, common.EncodeURLValues("/v1/level2/snapshot", params), &o) if err != nil { return nil, err } @@ -128,14 +128,14 @@ func (ku *Kucoin) GetFuturesOrderbook(ctx context.Context, symbol string) (*Orde } // GetFuturesPartOrderbook20 gets orderbook for a specified symbol with depth 20 -func (ku *Kucoin) GetFuturesPartOrderbook20(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetFuturesPartOrderbook20(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o futuresOrderbookResponse - err := ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresPartOrderbookDepth20EPL, common.EncodeURLValues("/v1/level2/depth20", params), &o) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, futuresPartOrderbookDepth20EPL, common.EncodeURLValues("/v1/level2/depth20", params), &o) if err != nil { return nil, err } @@ -143,14 +143,14 @@ func (ku *Kucoin) GetFuturesPartOrderbook20(ctx context.Context, symbol string) } // GetFuturesPartOrderbook100 gets orderbook for a specified symbol with depth 100 -func (ku *Kucoin) GetFuturesPartOrderbook100(ctx context.Context, symbol string) (*Orderbook, error) { +func (e *Exchange) GetFuturesPartOrderbook100(ctx context.Context, symbol string) (*Orderbook, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var o futuresOrderbookResponse - err := ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresPartOrderbookDepth100EPL, common.EncodeURLValues("/v1/level2/depth100", params), &o) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, futuresPartOrderbookDepth100EPL, common.EncodeURLValues("/v1/level2/depth100", params), &o) if err != nil { return nil, err } @@ -158,16 +158,16 @@ func (ku *Kucoin) GetFuturesPartOrderbook100(ctx context.Context, symbol string) } // GetFuturesTradeHistory get last 100 trades for symbol -func (ku *Kucoin) GetFuturesTradeHistory(ctx context.Context, symbol string) ([]FuturesTrade, error) { +func (e *Exchange) GetFuturesTradeHistory(ctx context.Context, symbol string) ([]FuturesTrade, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp []FuturesTrade - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresTransactionHistoryEPL, "/v1/trade/history?symbol="+symbol, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresTransactionHistoryEPL, "/v1/trade/history?symbol="+symbol, &resp) } // GetFuturesInterestRate get interest rate -func (ku *Kucoin) GetFuturesInterestRate(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FundingInterestRateResponse, error) { +func (e *Exchange) GetFuturesInterestRate(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FundingInterestRateResponse, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -188,11 +188,11 @@ func (ku *Kucoin) GetFuturesInterestRate(ctx context.Context, symbol string, sta params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FundingInterestRateResponse - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresInterestRateEPL, common.EncodeURLValues("/v1/interest/query", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresInterestRateEPL, common.EncodeURLValues("/v1/interest/query", params), &resp) } // GetFuturesIndexList retrieves futures index information for a symbol -func (ku *Kucoin) GetFuturesIndexList(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FuturesIndexResponse, error) { +func (e *Exchange) GetFuturesIndexList(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FuturesIndexResponse, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -213,20 +213,20 @@ func (ku *Kucoin) GetFuturesIndexList(ctx context.Context, symbol string, startA params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FuturesIndexResponse - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresIndexListEPL, common.EncodeURLValues("/v1/index/query", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresIndexListEPL, common.EncodeURLValues("/v1/index/query", params), &resp) } // GetFuturesCurrentMarkPrice get current mark price -func (ku *Kucoin) GetFuturesCurrentMarkPrice(ctx context.Context, symbol string) (*FuturesMarkPrice, error) { +func (e *Exchange) GetFuturesCurrentMarkPrice(ctx context.Context, symbol string) (*FuturesMarkPrice, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *FuturesMarkPrice - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresCurrentMarkPriceEPL, "/v1/mark-price/"+symbol+"/current", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresCurrentMarkPriceEPL, "/v1/mark-price/"+symbol+"/current", &resp) } // GetFuturesPremiumIndex get premium index -func (ku *Kucoin) GetFuturesPremiumIndex(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FuturesInterestRateResponse, error) { +func (e *Exchange) GetFuturesPremiumIndex(ctx context.Context, symbol string, startAt, endAt time.Time, reverse, forward bool, offset, maxCount int64) (*FuturesInterestRateResponse, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -247,26 +247,26 @@ func (ku *Kucoin) GetFuturesPremiumIndex(ctx context.Context, symbol string, sta params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FuturesInterestRateResponse - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresPremiumIndexEPL, common.EncodeURLValues("/v1/premium/query", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresPremiumIndexEPL, common.EncodeURLValues("/v1/premium/query", params), &resp) } // Get24HourFuturesTransactionVolume retrieves a 24 hour transaction volume -func (ku *Kucoin) Get24HourFuturesTransactionVolume(ctx context.Context) (*TransactionVolume, error) { +func (e *Exchange) Get24HourFuturesTransactionVolume(ctx context.Context) (*TransactionVolume, error) { var resp *TransactionVolume - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransactionVolumeEPL, http.MethodGet, "/v1/trade-statistics", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransactionVolumeEPL, http.MethodGet, "/v1/trade-statistics", nil, &resp) } // GetFuturesCurrentFundingRate get current funding rate -func (ku *Kucoin) GetFuturesCurrentFundingRate(ctx context.Context, symbol string) (*FuturesFundingRate, error) { +func (e *Exchange) GetFuturesCurrentFundingRate(ctx context.Context, symbol string) (*FuturesFundingRate, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *FuturesFundingRate - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresCurrentFundingRateEPL, "/v1/funding-rate/"+symbol+"/current", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresCurrentFundingRateEPL, "/v1/funding-rate/"+symbol+"/current", &resp) } // GetPublicFundingRate query the funding rate at each settlement time point within a certain time range of the corresponding contract -func (ku *Kucoin) GetPublicFundingRate(ctx context.Context, symbol string, from, to time.Time) ([]FundingHistoryItem, error) { +func (e *Exchange) GetPublicFundingRate(ctx context.Context, symbol string, from, to time.Time) ([]FundingHistoryItem, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -279,16 +279,16 @@ func (ku *Kucoin) GetPublicFundingRate(ctx context.Context, symbol string, from, params.Set("from", strconv.FormatInt(from.UnixMilli(), 10)) params.Set("to", strconv.FormatInt(to.UnixMilli(), 10)) var resp []FundingHistoryItem - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresPublicFundingRateEPL, common.EncodeURLValues("/v1/contract/funding-rates", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresPublicFundingRateEPL, common.EncodeURLValues("/v1/contract/funding-rates", params), &resp) } // GetFuturesServerTime get server time -func (ku *Kucoin) GetFuturesServerTime(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetFuturesServerTime(ctx context.Context) (time.Time, error) { resp := struct { Data types.Time `json:"data"` Error }{} - err := ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresServerTimeEPL, "/v1/timestamp", &resp) + err := e.SendHTTPRequest(ctx, exchange.RestFutures, futuresServerTimeEPL, "/v1/timestamp", &resp) if err != nil { return time.Time{}, err } @@ -296,13 +296,13 @@ func (ku *Kucoin) GetFuturesServerTime(ctx context.Context) (time.Time, error) { } // GetFuturesServiceStatus get service status -func (ku *Kucoin) GetFuturesServiceStatus(ctx context.Context) (*FuturesServiceStatus, error) { +func (e *Exchange) GetFuturesServiceStatus(ctx context.Context) (*FuturesServiceStatus, error) { var resp *FuturesServiceStatus - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresServiceStatusEPL, "/v1/status", &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresServiceStatusEPL, "/v1/status", &resp) } // GetFuturesKline get contract's kline data -func (ku *Kucoin) GetFuturesKline(ctx context.Context, granularity int64, symbol string, from, to time.Time) ([]FuturesKline, error) { +func (e *Exchange) GetFuturesKline(ctx context.Context, granularity int64, symbol string, from, to time.Time) ([]FuturesKline, error) { if granularity == 0 { return nil, kline.ErrInvalidInterval } @@ -323,35 +323,35 @@ func (ku *Kucoin) GetFuturesKline(ctx context.Context, granularity int64, symbol params.Set("to", strconv.FormatInt(to.UnixMilli(), 10)) } var resp []FuturesKline - return resp, ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresKlineEPL, common.EncodeURLValues("/v1/kline/query", params), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestFutures, futuresKlineEPL, common.EncodeURLValues("/v1/kline/query", params), &resp) } // PostFuturesOrder used to place two types of futures orders: limit and market -func (ku *Kucoin) PostFuturesOrder(ctx context.Context, arg *FuturesOrderParam) (string, error) { - err := ku.FillFuturesPostOrderArgumentFilter(arg) +func (e *Exchange) PostFuturesOrder(ctx context.Context, arg *FuturesOrderParam) (string, error) { + err := e.FillFuturesPostOrderArgumentFilter(arg) if err != nil { return "", err } resp := struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPlaceOrderEPL, http.MethodPost, kucoinFuturesOrder, &arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPlaceOrderEPL, http.MethodPost, kucoinFuturesOrder, &arg, &resp) } // PostFuturesOrderTest a test endpoint to place a single futures order -func (ku *Kucoin) PostFuturesOrderTest(ctx context.Context, arg *FuturesOrderParam) (string, error) { - err := ku.FillFuturesPostOrderArgumentFilter(arg) +func (e *Exchange) PostFuturesOrderTest(ctx context.Context, arg *FuturesOrderParam) (string, error) { + err := e.FillFuturesPostOrderArgumentFilter(arg) if err != nil { return "", err } resp := struct { OrderID string `json:"orderId"` }{} - return resp.OrderID, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPlaceOrderEPL, http.MethodPost, kucoinFuturesOrder+"/test", &arg, &resp) + return resp.OrderID, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPlaceOrderEPL, http.MethodPost, kucoinFuturesOrder+"/test", &arg, &resp) } // FillFuturesPostOrderArgumentFilter verifies futures order request parameters -func (ku *Kucoin) FillFuturesPostOrderArgumentFilter(arg *FuturesOrderParam) error { +func (e *Exchange) FillFuturesPostOrderArgumentFilter(arg *FuturesOrderParam) error { if *arg == (FuturesOrderParam{}) { return common.ErrNilPointer } @@ -398,35 +398,35 @@ func (ku *Kucoin) FillFuturesPostOrderArgumentFilter(arg *FuturesOrderParam) err // PlaceMultipleFuturesOrders used to place multiple futures orders // The maximum limit orders for a single contract is 100 per account, and the maximum stop orders for a single contract is 50 per account -func (ku *Kucoin) PlaceMultipleFuturesOrders(ctx context.Context, args []FuturesOrderParam) ([]FuturesOrderRespItem, error) { +func (e *Exchange) PlaceMultipleFuturesOrders(ctx context.Context, args []FuturesOrderParam) ([]FuturesOrderRespItem, error) { if len(args) == 0 { return nil, fmt.Errorf("%w, not order to place", common.ErrEmptyParams) } var err error for x := range args { - err = ku.FillFuturesPostOrderArgumentFilter(&args[x]) + err = e.FillFuturesPostOrderArgumentFilter(&args[x]) if err != nil { return nil, err } } var resp []FuturesOrderRespItem - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, multipleFuturesOrdersEPL, http.MethodPost, "/v1/orders/multi", args, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, multipleFuturesOrdersEPL, http.MethodPost, "/v1/orders/multi", args, &resp) } // CancelFuturesOrderByOrderID used to cancel single order previously placed including a stop order -func (ku *Kucoin) CancelFuturesOrderByOrderID(ctx context.Context, orderID string) ([]string, error) { - return ku.cancelFuturesOrderByID(ctx, orderID, "/v1/orders/", "") +func (e *Exchange) CancelFuturesOrderByOrderID(ctx context.Context, orderID string) ([]string, error) { + return e.cancelFuturesOrderByID(ctx, orderID, "/v1/orders/", "") } // CancelFuturesOrderByClientOrderID cancels a futures order by using client order ID -func (ku *Kucoin) CancelFuturesOrderByClientOrderID(ctx context.Context, symbol, clientOrderID string) ([]string, error) { +func (e *Exchange) CancelFuturesOrderByClientOrderID(ctx context.Context, symbol, clientOrderID string) ([]string, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } - return ku.cancelFuturesOrderByID(ctx, clientOrderID, "/v1/orders/client-order/", symbol) + return e.cancelFuturesOrderByID(ctx, clientOrderID, "/v1/orders/client-order/", symbol) } -func (ku *Kucoin) cancelFuturesOrderByID(ctx context.Context, id, path, symbol string) ([]string, error) { +func (e *Exchange) cancelFuturesOrderByID(ctx context.Context, id, path, symbol string) ([]string, error) { if id == "" { return nil, order.ErrOrderIDNotSet } @@ -437,11 +437,11 @@ func (ku *Kucoin) cancelFuturesOrderByID(ctx context.Context, id, path, symbol s resp := struct { CancelledOrderIDs []string `json:"cancelledOrderIds"` }{} - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresCancelAnOrderEPL, http.MethodDelete, common.EncodeURLValues(path+id, params), nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresCancelAnOrderEPL, http.MethodDelete, common.EncodeURLValues(path+id, params), nil, &resp) } // CancelMultipleFuturesLimitOrders used to cancel all futures order excluding stop orders -func (ku *Kucoin) CancelMultipleFuturesLimitOrders(ctx context.Context, symbol string) ([]string, error) { +func (e *Exchange) CancelMultipleFuturesLimitOrders(ctx context.Context, symbol string) ([]string, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -449,11 +449,11 @@ func (ku *Kucoin) CancelMultipleFuturesLimitOrders(ctx context.Context, symbol s resp := struct { CancelledOrderIDs []string `json:"cancelledOrderIds"` }{} - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresLimitOrderMassCancelationEPL, http.MethodDelete, common.EncodeURLValues(kucoinFuturesOrder, params), nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresLimitOrderMassCancelationEPL, http.MethodDelete, common.EncodeURLValues(kucoinFuturesOrder, params), nil, &resp) } // CancelAllFuturesStopOrders used to cancel all untriggered stop orders -func (ku *Kucoin) CancelAllFuturesStopOrders(ctx context.Context, symbol string) ([]string, error) { +func (e *Exchange) CancelAllFuturesStopOrders(ctx context.Context, symbol string) ([]string, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -461,11 +461,11 @@ func (ku *Kucoin) CancelAllFuturesStopOrders(ctx context.Context, symbol string) resp := struct { CancelledOrderIDs []string `json:"cancelledOrderIds"` }{} - return resp.CancelledOrderIDs, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresCancelMultipleLimitOrdersEPL, http.MethodDelete, common.EncodeURLValues(kucoinFuturesStopOrder, params), nil, &resp) + return resp.CancelledOrderIDs, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresCancelMultipleLimitOrdersEPL, http.MethodDelete, common.EncodeURLValues(kucoinFuturesStopOrder, params), nil, &resp) } // GetFuturesOrders gets the user current futures order list -func (ku *Kucoin) GetFuturesOrders(ctx context.Context, status, symbol, side, orderType string, startAt, endAt time.Time) (*FutureOrdersResponse, error) { +func (e *Exchange) GetFuturesOrders(ctx context.Context, status, symbol, side, orderType string, startAt, endAt time.Time) (*FutureOrdersResponse, error) { params := url.Values{} if status != "" { params.Set("status", status) @@ -486,11 +486,11 @@ func (ku *Kucoin) GetFuturesOrders(ctx context.Context, status, symbol, side, or params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *FutureOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveOrderListEPL, http.MethodGet, common.EncodeURLValues(kucoinFuturesOrder, params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveOrderListEPL, http.MethodGet, common.EncodeURLValues(kucoinFuturesOrder, params), nil, &resp) } // GetUntriggeredFuturesStopOrders gets the untriggered stop orders list -func (ku *Kucoin) GetUntriggeredFuturesStopOrders(ctx context.Context, symbol, side, orderType string, startAt, endAt time.Time) (*FutureOrdersResponse, error) { +func (e *Exchange) GetUntriggeredFuturesStopOrders(ctx context.Context, symbol, side, orderType string, startAt, endAt time.Time) (*FutureOrdersResponse, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) @@ -508,21 +508,21 @@ func (ku *Kucoin) GetUntriggeredFuturesStopOrders(ctx context.Context, symbol, s params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *FutureOrdersResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, cancelUntriggeredFuturesStopOrdersEPL, http.MethodGet, common.EncodeURLValues(kucoinFuturesStopOrder, params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, cancelUntriggeredFuturesStopOrdersEPL, http.MethodGet, common.EncodeURLValues(kucoinFuturesStopOrder, params), nil, &resp) } // GetFuturesRecentCompletedOrders gets list of recent 1000 orders in the last 24 hours -func (ku *Kucoin) GetFuturesRecentCompletedOrders(ctx context.Context, symbol string) ([]FuturesOrder, error) { +func (e *Exchange) GetFuturesRecentCompletedOrders(ctx context.Context, symbol string) ([]FuturesOrder, error) { params := url.Values{} if symbol != "" { params.Set("symbol", symbol) } var resp []FuturesOrder - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRecentCompletedOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/recentDoneOrders", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRecentCompletedOrdersEPL, http.MethodGet, common.EncodeURLValues("/v1/recentDoneOrders", params), nil, &resp) } // GetFuturesOrderDetails gets single order details by order ID -func (ku *Kucoin) GetFuturesOrderDetails(ctx context.Context, orderID, clientOrderID string) (*FuturesOrder, error) { +func (e *Exchange) GetFuturesOrderDetails(ctx context.Context, orderID, clientOrderID string) (*FuturesOrder, error) { path := "/v1/orders/" if orderID == "" && clientOrderID == "" { return nil, fmt.Errorf("%w either client order ID or order id required", order.ErrOrderIDNotSet) @@ -535,20 +535,20 @@ func (ku *Kucoin) GetFuturesOrderDetails(ctx context.Context, orderID, clientOrd params.Set("clientOid", clientOrderID) } var resp *FuturesOrder - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOrdersByIDEPL, http.MethodGet, common.EncodeURLValues(path+orderID, params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOrdersByIDEPL, http.MethodGet, common.EncodeURLValues(path+orderID, params), nil, &resp) } // GetFuturesOrderDetailsByClientOrderID gets single order details by client ID -func (ku *Kucoin) GetFuturesOrderDetailsByClientOrderID(ctx context.Context, clientOrderID string) (*FuturesOrder, error) { +func (e *Exchange) GetFuturesOrderDetailsByClientOrderID(ctx context.Context, clientOrderID string) (*FuturesOrder, error) { if clientOrderID == "" { return nil, order.ErrClientOrderIDMustBeSet } var resp *FuturesOrder - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOrderDetailsByClientOrderIDEPL, http.MethodGet, "/v1/orders/byClientOid?clientOid="+clientOrderID, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOrderDetailsByClientOrderIDEPL, http.MethodGet, "/v1/orders/byClientOid?clientOid="+clientOrderID, nil, &resp) } // GetFuturesFills gets list of recent fills -func (ku *Kucoin) GetFuturesFills(ctx context.Context, orderID, symbol, side, orderType string, startAt, endAt time.Time) (*FutureFillsResponse, error) { +func (e *Exchange) GetFuturesFills(ctx context.Context, orderID, symbol, side, orderType string, startAt, endAt time.Time) (*FutureFillsResponse, error) { params := url.Values{} if orderID != "" { params.Set("orderId", orderID) @@ -569,41 +569,41 @@ func (ku *Kucoin) GetFuturesFills(ctx context.Context, orderID, symbol, side, or params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *FutureFillsResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveFillsEPL, http.MethodGet, common.EncodeURLValues("/v1/fills", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveFillsEPL, http.MethodGet, common.EncodeURLValues("/v1/fills", params), nil, &resp) } // GetFuturesRecentFills gets list of 1000 recent fills in the last 24 hrs -func (ku *Kucoin) GetFuturesRecentFills(ctx context.Context) ([]FuturesFill, error) { +func (e *Exchange) GetFuturesRecentFills(ctx context.Context) ([]FuturesFill, error) { var resp []FuturesFill - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRecentFillsEPL, http.MethodGet, "/v1/recentFills", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRecentFillsEPL, http.MethodGet, "/v1/recentFills", nil, &resp) } // GetFuturesOpenOrderStats gets the total number and value of the all your active orders -func (ku *Kucoin) GetFuturesOpenOrderStats(ctx context.Context, symbol string) (*FuturesOpenOrderStats, error) { +func (e *Exchange) GetFuturesOpenOrderStats(ctx context.Context, symbol string) (*FuturesOpenOrderStats, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *FuturesOpenOrderStats - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOpenOrderStatsEPL, http.MethodGet, "/v1/openOrderStatistics?symbol="+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresOpenOrderStatsEPL, http.MethodGet, "/v1/openOrderStatistics?symbol="+symbol, nil, &resp) } // GetFuturesPosition gets the position details of a specified position -func (ku *Kucoin) GetFuturesPosition(ctx context.Context, symbol string) (*FuturesPosition, error) { +func (e *Exchange) GetFuturesPosition(ctx context.Context, symbol string) (*FuturesPosition, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp *FuturesPosition - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionEPL, http.MethodGet, "/v1/position?symbol="+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionEPL, http.MethodGet, "/v1/position?symbol="+symbol, nil, &resp) } // GetFuturesPositionList gets the list of position with details -func (ku *Kucoin) GetFuturesPositionList(ctx context.Context) ([]FuturesPosition, error) { +func (e *Exchange) GetFuturesPositionList(ctx context.Context) ([]FuturesPosition, error) { var resp []FuturesPosition - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionListEPL, http.MethodGet, "/v1/positions", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionListEPL, http.MethodGet, "/v1/positions", nil, &resp) } // SetAutoDepositMargin enable/disable of auto-deposit margin -func (ku *Kucoin) SetAutoDepositMargin(ctx context.Context, symbol string, status bool) (bool, error) { +func (e *Exchange) SetAutoDepositMargin(ctx context.Context, symbol string, status bool) (bool, error) { if symbol == "" { return false, currency.ErrSymbolStringEmpty } @@ -611,20 +611,20 @@ func (ku *Kucoin) SetAutoDepositMargin(ctx context.Context, symbol string, statu params["symbol"] = symbol params["status"] = status var resp bool - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, setAutoDepositMarginEPL, http.MethodPost, "/v1/position/margin/auto-deposit-status", params, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, setAutoDepositMarginEPL, http.MethodPost, "/v1/position/margin/auto-deposit-status", params, &resp) } // GetMaxWithdrawMargin query the maximum amount of margin that the current position supports withdrawal -func (ku *Kucoin) GetMaxWithdrawMargin(ctx context.Context, symbol string) (float64, error) { +func (e *Exchange) GetMaxWithdrawMargin(ctx context.Context, symbol string) (float64, error) { if symbol == "" { return 0, currency.ErrSymbolStringEmpty } var resp types.Number - return resp.Float64(), ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, maxWithdrawMarginEPL, http.MethodGet, "/v1/margin/maxWithdrawMargin?symbol="+symbol, nil, &resp) + return resp.Float64(), e.SendAuthHTTPRequest(ctx, exchange.RestFutures, maxWithdrawMarginEPL, http.MethodGet, "/v1/margin/maxWithdrawMargin?symbol="+symbol, nil, &resp) } // RemoveMarginManually removes a margin manually -func (ku *Kucoin) RemoveMarginManually(ctx context.Context, arg *WithdrawMarginResponse) (*MarginRemovingResponse, error) { +func (e *Exchange) RemoveMarginManually(ctx context.Context, arg *WithdrawMarginResponse) (*MarginRemovingResponse, error) { if *arg == (WithdrawMarginResponse{}) { return nil, common.ErrNilPointer } @@ -635,11 +635,11 @@ func (ku *Kucoin) RemoveMarginManually(ctx context.Context, arg *WithdrawMarginR return nil, fmt.Errorf("%w, withdrawAmount must be greater than 0", order.ErrAmountBelowMin) } var resp *MarginRemovingResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, removeMarginManuallyEPL, http.MethodPost, "/v1/margin/withdrawMargin", arg, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpot, removeMarginManuallyEPL, http.MethodPost, "/v1/margin/withdrawMargin", arg, &resp) } // AddMargin is used to add margin manually -func (ku *Kucoin) AddMargin(ctx context.Context, symbol, uniqueID string, margin float64) (*FuturesPosition, error) { +func (e *Exchange) AddMargin(ctx context.Context, symbol, uniqueID string, margin float64) (*FuturesPosition, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -654,20 +654,20 @@ func (ku *Kucoin) AddMargin(ctx context.Context, symbol, uniqueID string, margin } params["margin"] = strconv.FormatFloat(margin, 'f', -1, 64) var resp *FuturesPosition - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAddMarginManuallyEPL, http.MethodPost, "/v1/position/margin/deposit-margin", params, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAddMarginManuallyEPL, http.MethodPost, "/v1/position/margin/deposit-margin", params, &resp) } // GetFuturesRiskLimitLevel gets information about risk limit level of a specific contract -func (ku *Kucoin) GetFuturesRiskLimitLevel(ctx context.Context, symbol string) ([]FuturesRiskLimitLevel, error) { +func (e *Exchange) GetFuturesRiskLimitLevel(ctx context.Context, symbol string) ([]FuturesRiskLimitLevel, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } var resp []FuturesRiskLimitLevel - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRiskLimitLevelEPL, http.MethodGet, "/v1/contracts/risk-limit/"+symbol, nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRiskLimitLevelEPL, http.MethodGet, "/v1/contracts/risk-limit/"+symbol, nil, &resp) } // FuturesUpdateRiskLmitLevel is used to adjustment the risk limit level -func (ku *Kucoin) FuturesUpdateRiskLmitLevel(ctx context.Context, symbol string, level int64) (bool, error) { +func (e *Exchange) FuturesUpdateRiskLmitLevel(ctx context.Context, symbol string, level int64) (bool, error) { if symbol == "" { return false, currency.ErrSymbolStringEmpty } @@ -675,11 +675,11 @@ func (ku *Kucoin) FuturesUpdateRiskLmitLevel(ctx context.Context, symbol string, params["symbol"] = symbol params["level"] = strconv.FormatInt(level, 10) var resp bool - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresUpdateRiskLimitLevelEPL, http.MethodPost, "/v1/position/risk-limit-level/change", params, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresUpdateRiskLimitLevelEPL, http.MethodPost, "/v1/position/risk-limit-level/change", params, &resp) } // GetFuturesFundingHistory gets information about funding history -func (ku *Kucoin) GetFuturesFundingHistory(ctx context.Context, symbol string, offset, maxCount int64, reverse, forward bool, startAt, endAt time.Time) (*FuturesFundingHistoryResponse, error) { +func (e *Exchange) GetFuturesFundingHistory(ctx context.Context, symbol string, offset, maxCount int64, reverse, forward bool, startAt, endAt time.Time) (*FuturesFundingHistoryResponse, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -700,21 +700,21 @@ func (ku *Kucoin) GetFuturesFundingHistory(ctx context.Context, symbol string, o params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FuturesFundingHistoryResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresFundingHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/funding-history", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresFundingHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/funding-history", params), nil, &resp) } // GetFuturesAccountOverview gets future account overview -func (ku *Kucoin) GetFuturesAccountOverview(ctx context.Context, ccy string) (*FuturesAccount, error) { +func (e *Exchange) GetFuturesAccountOverview(ctx context.Context, ccy string) (*FuturesAccount, error) { params := url.Values{} if ccy != "" { params.Set("currency", ccy) } var resp *FuturesAccount - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountOverviewEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAccountOverviewEPL, http.MethodGet, common.EncodeURLValues("/v1/account-overview", params), nil, &resp) } // GetFuturesTransactionHistory gets future transaction history -func (ku *Kucoin) GetFuturesTransactionHistory(ctx context.Context, ccy currency.Code, txType string, offset, maxCount int64, forward bool, startAt, endAt time.Time) (*FuturesTransactionHistoryResponse, error) { +func (e *Exchange) GetFuturesTransactionHistory(ctx context.Context, ccy currency.Code, txType string, offset, maxCount int64, forward bool, startAt, endAt time.Time) (*FuturesTransactionHistoryResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("currency", ccy.String()) @@ -736,11 +736,11 @@ func (ku *Kucoin) GetFuturesTransactionHistory(ctx context.Context, ccy currency params.Set("maxCount", strconv.FormatInt(maxCount, 10)) } var resp *FuturesTransactionHistoryResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveTransactionHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/transaction-history", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresRetrieveTransactionHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/transaction-history", params), nil, &resp) } // CreateFuturesSubAccountAPIKey is used to create Futures APIs for sub-accounts -func (ku *Kucoin) CreateFuturesSubAccountAPIKey(ctx context.Context, ipWhitelist, passphrase, permission, remark, subName string) (*APIKeyDetail, error) { +func (e *Exchange) CreateFuturesSubAccountAPIKey(ctx context.Context, ipWhitelist, passphrase, permission, remark, subName string) (*APIKeyDetail, error) { if remark == "" { return nil, errRemarkIsRequired } @@ -761,11 +761,11 @@ func (ku *Kucoin) CreateFuturesSubAccountAPIKey(ctx context.Context, ipWhitelist params["permission"] = permission } var resp *APIKeyDetail - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, createSubAccountAPIKeyEPL, http.MethodPost, "/v1/sub/api-key", params, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, createSubAccountAPIKeyEPL, http.MethodPost, "/v1/sub/api-key", params, &resp) } // TransferFuturesFundsToMainAccount helps in transferring funds from futures to main/trade account -func (ku *Kucoin) TransferFuturesFundsToMainAccount(ctx context.Context, amount float64, ccy currency.Code, recAccountType string) (*TransferRes, error) { +func (e *Exchange) TransferFuturesFundsToMainAccount(ctx context.Context, amount float64, ccy currency.Code, recAccountType string) (*TransferRes, error) { if amount <= 0 { return nil, order.ErrAmountBelowMin } @@ -780,11 +780,11 @@ func (ku *Kucoin) TransferFuturesFundsToMainAccount(ctx context.Context, amount params["currency"] = ccy.String() params["recAccountType"] = recAccountType var resp *TransferRes - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, transferOutToMainEPL, http.MethodPost, "/v3/transfer-out", params, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, transferOutToMainEPL, http.MethodPost, "/v3/transfer-out", params, &resp) } // TransferFundsToFuturesAccount helps in transferring funds from payee account to futures account -func (ku *Kucoin) TransferFundsToFuturesAccount(ctx context.Context, amount float64, ccy currency.Code, payAccountType string) error { +func (e *Exchange) TransferFundsToFuturesAccount(ctx context.Context, amount float64, ccy currency.Code, payAccountType string) error { if amount <= 0 { return order.ErrAmountBelowMin } @@ -801,11 +801,11 @@ func (ku *Kucoin) TransferFundsToFuturesAccount(ctx context.Context, amount floa resp := struct { Error }{} - return ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, transferFundToFuturesAccountEPL, http.MethodPost, "/v1/transfer-in", params, &resp) + return e.SendAuthHTTPRequest(ctx, exchange.RestFutures, transferFundToFuturesAccountEPL, http.MethodPost, "/v1/transfer-in", params, &resp) } // GetFuturesTransferOutList gets list of transfer out -func (ku *Kucoin) GetFuturesTransferOutList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*TransferListsResponse, error) { +func (e *Exchange) GetFuturesTransferOutList(ctx context.Context, ccy currency.Code, status string, startAt, endAt time.Time) (*TransferListsResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -821,7 +821,7 @@ func (ku *Kucoin) GetFuturesTransferOutList(ctx context.Context, ccy currency.Co params.Set("endAt", strconv.FormatInt(endAt.UnixMilli(), 10)) } var resp *TransferListsResponse - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransferOutListEPL, http.MethodGet, common.EncodeURLValues("/v1/transfer-list", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTransferOutListEPL, http.MethodGet, common.EncodeURLValues("/v1/transfer-list", params), nil, &resp) } func processFuturesOB(ob [][2]float64) []orderbook.Level { @@ -845,18 +845,18 @@ func constructFuturesOrderbook(o *futuresOrderbookResponse) *Orderbook { } // GetFuturesTradingPairsActualFees retrieves the actual fee rate of the trading pair. The fee rate of your sub-account is the same as that of the master account -func (ku *Kucoin) GetFuturesTradingPairsActualFees(ctx context.Context, symbol string) (*TradingPairFee, error) { +func (e *Exchange) GetFuturesTradingPairsActualFees(ctx context.Context, symbol string) (*TradingPairFee, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } params := url.Values{} params.Set("symbol", symbol) var resp *TradingPairFee - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTradingPairFeeEPL, http.MethodGet, common.EncodeURLValues("/v1/trade-fees", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresTradingPairFeeEPL, http.MethodGet, common.EncodeURLValues("/v1/trade-fees", params), nil, &resp) } // GetPositionHistory query position history information records -func (ku *Kucoin) GetPositionHistory(ctx context.Context, symbol string, from, to time.Time, limit, pageID int64) (*FuturesPositionHistory, error) { +func (e *Exchange) GetPositionHistory(ctx context.Context, symbol string, from, to time.Time, limit, pageID int64) (*FuturesPositionHistory, error) { params := url.Values{} if !from.IsZero() && !to.IsZero() { err := common.StartEndTimeCheck(from, to) @@ -876,11 +876,11 @@ func (ku *Kucoin) GetPositionHistory(ctx context.Context, symbol string, from, t params.Set("pageId", strconv.FormatInt(pageID, 10)) } var resp *FuturesPositionHistory - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/history-positions", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("/v1/history-positions", params), nil, &resp) } // GetMaximumOpenPositionSize retrieves a maximum open position size -func (ku *Kucoin) GetMaximumOpenPositionSize(ctx context.Context, symbol string, price float64, leverage int64) (*FuturesMaxOpenPositionSize, error) { +func (e *Exchange) GetMaximumOpenPositionSize(ctx context.Context, symbol string, price float64, leverage int64) (*FuturesMaxOpenPositionSize, error) { if symbol == "" { return nil, currency.ErrSymbolStringEmpty } @@ -895,11 +895,11 @@ func (ku *Kucoin) GetMaximumOpenPositionSize(ctx context.Context, symbol string, params.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) params.Set("leverage", strconv.FormatInt(leverage, 10)) var resp *FuturesMaxOpenPositionSize - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresMaxOpenPositionsSizeEPL, http.MethodGet, common.EncodeURLValues("/v2/getMaxOpenSize", params), nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresMaxOpenPositionsSizeEPL, http.MethodGet, common.EncodeURLValues("/v2/getMaxOpenSize", params), nil, &resp) } // GetLatestTickersForAllContracts retrieves all futures instruments ticker information -func (ku *Kucoin) GetLatestTickersForAllContracts(ctx context.Context) ([]WsFuturesTicker, error) { +func (e *Exchange) GetLatestTickersForAllContracts(ctx context.Context) ([]WsFuturesTicker, error) { var resp []WsFuturesTicker - return resp, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAllTickersInfoEPL, http.MethodGet, "/v1/allTickers", nil, &resp) + return resp, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAllTickersInfoEPL, http.MethodGet, "/v1/allTickers", nil, &resp) } diff --git a/exchanges/kucoin/kucoin_test.go b/exchanges/kucoin/kucoin_test.go index 01c6c81ea39..69b5c9b74ec 100644 --- a/exchanges/kucoin/kucoin_test.go +++ b/exchanges/kucoin/kucoin_test.go @@ -45,23 +45,23 @@ const ( ) var ( - ku *Kucoin + e *Exchange spotTradablePair, marginTradablePair, futuresTradablePair currency.Pair assertToTradablePairMap map[asset.Item]currency.Pair ) func TestMain(m *testing.M) { - ku = new(Kucoin) - if err := testexch.Setup(ku); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Kucoin Setup error: %s", err) } if apiKey != "" && apiSecret != "" && passPhrase != "" { - ku.API.AuthenticatedSupport = true - ku.API.AuthenticatedWebsocketSupport = true - ku.API.CredentialsValidator.RequiresBase64DecodeSecret = false - ku.SetCredentials(apiKey, apiSecret, passPhrase, "", "", "") - ku.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.API.CredentialsValidator.RequiresBase64DecodeSecret = false + e.SetCredentials(apiKey, apiSecret, passPhrase, "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) } getFirstTradablePairOfAssets(context.Background()) @@ -78,35 +78,35 @@ func TestMain(m *testing.M) { // Spot asset test cases starts from here func TestGetSymbols(t *testing.T) { t.Parallel() - symbols, err := ku.GetSymbols(t.Context(), "") + symbols, err := e.GetSymbols(t.Context(), "") assert.NoError(t, err) assert.NotEmpty(t, symbols) // Using market string reduces the scope of what is returned. - symbols, err = ku.GetSymbols(t.Context(), "ETF") + symbols, err = e.GetSymbols(t.Context(), "ETF") assert.NoError(t, err) assert.NotEmpty(t, symbols, "should return all available ETF symbols") } func TestGetTicker(t *testing.T) { t.Parallel() - _, err := ku.GetTicker(t.Context(), "") + _, err := e.GetTicker(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetTicker(t.Context(), spotTradablePair.String()) + result, err := e.GetTicker(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllTickers(t *testing.T) { t.Parallel() - result, err := ku.GetTickers(t.Context()) + result, err := e.GetTickers(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesTickers(t *testing.T) { t.Parallel() - tickers, err := ku.GetFuturesTickers(t.Context()) + tickers, err := e.GetFuturesTickers(t.Context()) assert.NoError(t, err) for i := range tickers { assert.Positive(t, tickers[i].Last, "Last should be positive") @@ -114,63 +114,63 @@ func TestGetFuturesTickers(t *testing.T) { assert.Positive(t, tickers[i].Ask, "Ask should be positive") assert.NotEmpty(t, tickers[i].Pair, "Pair should not be empty") assert.NotEmpty(t, tickers[i].LastUpdated, "LastUpdated should not be empty") - assert.Equal(t, ku.Name, tickers[i].ExchangeName) + assert.Equal(t, e.Name, tickers[i].ExchangeName) assert.Equal(t, asset.Futures, tickers[i].AssetType) } } func TestGet24hrStats(t *testing.T) { t.Parallel() - _, err := ku.Get24hrStats(t.Context(), "") + _, err := e.Get24hrStats(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.Get24hrStats(t.Context(), spotTradablePair.String()) + result, err := e.Get24hrStats(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarketList(t *testing.T) { t.Parallel() - _, err := ku.GetMarketList(t.Context()) + _, err := e.GetMarketList(t.Context()) assert.NoError(t, err) } func TestGetPartOrderbook20(t *testing.T) { t.Parallel() - _, err := ku.GetPartOrderbook20(t.Context(), "") + _, err := e.GetPartOrderbook20(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetPartOrderbook20(t.Context(), spotTradablePair.String()) + result, err := e.GetPartOrderbook20(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetPartOrderbook100(t *testing.T) { t.Parallel() - _, err := ku.GetPartOrderbook100(t.Context(), "") + _, err := e.GetPartOrderbook100(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetPartOrderbook100(t.Context(), spotTradablePair.String()) + result, err := e.GetPartOrderbook100(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := ku.GetOrderbook(t.Context(), "") + _, err := e.GetOrderbook(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetOrderbook(t.Context(), spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetOrderbook(t.Context(), spotTradablePair.String()) assert.NoError(t, err) } func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := ku.GetTradeHistory(t.Context(), "") + _, err := e.GetTradeHistory(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.GetTradeHistory(t.Context(), spotTradablePair.String()) + _, err = e.GetTradeHistory(t.Context(), spotTradablePair.String()) assert.NoError(t, err) } @@ -194,126 +194,126 @@ func TestKlineUnmarshalJSON(t *testing.T) { func TestGetKlines(t *testing.T) { t.Parallel() - _, err := ku.GetKlines(t.Context(), "", "1week", time.Time{}, time.Time{}) + _, err := e.GetKlines(t.Context(), "", "1week", time.Time{}, time.Time{}) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.GetKlines(t.Context(), spotTradablePair.String(), "invalid-period", time.Time{}, time.Time{}) + _, err = e.GetKlines(t.Context(), spotTradablePair.String(), "invalid-period", time.Time{}, time.Time{}) require.ErrorIs(t, err, errInvalidPeriod) - result, err := ku.GetKlines(t.Context(), spotTradablePair.String(), "1week", time.Time{}, time.Time{}) + result, err := e.GetKlines(t.Context(), spotTradablePair.String(), "1week", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetKlines(t.Context(), spotTradablePair.String(), "5min", time.Now().Add(-time.Hour*1), time.Now()) + result, err = e.GetKlines(t.Context(), spotTradablePair.String(), "5min", time.Now().Add(-time.Hour*1), time.Now()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrenciesV3(t *testing.T) { t.Parallel() - _, err := ku.GetCurrenciesV3(t.Context()) + _, err := e.GetCurrenciesV3(t.Context()) assert.NoError(t, err) } func TestGetCurrencyV3(t *testing.T) { t.Parallel() - _, err := ku.GetCurrencyDetailV3(t.Context(), currency.EMPTYCODE, "") + _, err := e.GetCurrencyDetailV3(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := ku.GetCurrencyDetailV3(t.Context(), currency.BTC, "") + result, err := e.GetCurrencyDetailV3(t.Context(), currency.BTC, "") assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetCurrencyDetailV3(t.Context(), currency.BTC, "ETH") + result, err = e.GetCurrencyDetailV3(t.Context(), currency.BTC, "ETH") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFiatPrice(t *testing.T) { t.Parallel() - result, err := ku.GetFiatPrice(t.Context(), "", "") + result, err := e.GetFiatPrice(t.Context(), "", "") assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetFiatPrice(t.Context(), "EUR", "ETH,BTC") + result, err = e.GetFiatPrice(t.Context(), "EUR", "ETH,BTC") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetLeveragedTokenInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetLeveragedTokenInfo(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeveragedTokenInfo(t.Context(), currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarkPrice(t *testing.T) { t.Parallel() - _, err := ku.GetMarkPrice(t.Context(), "") + _, err := e.GetMarkPrice(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetMarkPrice(t.Context(), marginTradablePair.String()) + result, err := e.GetMarkPrice(t.Context(), marginTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllMarginTradingPairsMarkPrices(t *testing.T) { t.Parallel() - result, err := ku.GetAllMarginTradingPairsMarkPrices(t.Context()) + result, err := e.GetAllMarginTradingPairsMarkPrices(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarginConfiguration(t *testing.T) { t.Parallel() - result, err := ku.GetMarginConfiguration(t.Context()) + result, err := e.GetMarginConfiguration(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarginAccount(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetMarginAccount(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMarginAccount(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetCrossMarginRiskLimitCurrencyConfig(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetCrossMarginRiskLimitCurrencyConfig(t.Context(), "", currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCrossMarginRiskLimitCurrencyConfig(t.Context(), "", currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetIsolatedMarginRiskLimitCurrencyConfig(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetIsolatedMarginRiskLimitCurrencyConfig(t.Context(), "", currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetIsolatedMarginRiskLimitCurrencyConfig(t.Context(), "", currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestPostBorrowOrder(t *testing.T) { t.Parallel() - _, err := ku.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{}) + _, err := e.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{IsIsolated: true}) + _, err = e.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{IsIsolated: true}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{IsIsolated: true, Currency: currency.BTC}) + _, err = e.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{IsIsolated: true, Currency: currency.BTC}) require.ErrorIs(t, err, errTimeInForceRequired) - _, err = ku.PostMarginBorrowOrder(t.Context(), + _, err = e.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{ Currency: currency.USDT, TimeInForce: "FOK", Size: 0, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PostMarginBorrowOrder(t.Context(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PostMarginBorrowOrder(t.Context(), &MarginBorrowParam{ Currency: currency.USDT, TimeInForce: "IOC", @@ -325,27 +325,27 @@ func TestPostBorrowOrder(t *testing.T) { func TestGetMarginBorrowingHistory(t *testing.T) { t.Parallel() - _, err := ku.GetMarginBorrowingHistory(t.Context(), currency.EMPTYCODE, true, marginTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) + _, err := e.GetMarginBorrowingHistory(t.Context(), currency.EMPTYCODE, true, marginTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.GetMarginBorrowingHistory(t.Context(), currency.BTC, true, "", "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) + _, err = e.GetMarginBorrowingHistory(t.Context(), currency.BTC, true, "", "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetMarginBorrowingHistory(t.Context(), currency.BTC, true, marginTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetMarginBorrowingHistory(t.Context(), currency.BTC, true, marginTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) assert.NoError(t, err) } func TestPostRepayment(t *testing.T) { t.Parallel() - _, err := ku.PostRepayment(t.Context(), &RepayParam{}) + _, err := e.PostRepayment(t.Context(), &RepayParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.PostRepayment(t.Context(), &RepayParam{Size: 0.05}) + _, err = e.PostRepayment(t.Context(), &RepayParam{Size: 0.05}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.PostRepayment(t.Context(), &RepayParam{Currency: currency.ETH}) + _, err = e.PostRepayment(t.Context(), &RepayParam{Currency: currency.ETH}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PostRepayment(t.Context(), &RepayParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PostRepayment(t.Context(), &RepayParam{ Currency: currency.USDT, Size: 0.05, }) @@ -355,63 +355,63 @@ func TestPostRepayment(t *testing.T) { func TestGetCrossIsolatedMarginInterestRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetCrossIsolatedMarginInterestRecords(t.Context(), false, "", currency.BTC, time.Now().Add(-time.Hour*50), time.Now(), 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCrossIsolatedMarginInterestRecords(t.Context(), false, "", currency.BTC, time.Now().Add(-time.Hour*50), time.Now(), 0, 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetRepaymentHistory(t *testing.T) { t.Parallel() - _, err := ku.GetRepaymentHistory(t.Context(), currency.EMPTYCODE, true, spotTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) + _, err := e.GetRepaymentHistory(t.Context(), currency.EMPTYCODE, true, spotTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetRepaymentHistory(t.Context(), currency.BTC, true, spotTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRepaymentHistory(t.Context(), currency.BTC, true, spotTradablePair.String(), "", time.Time{}, time.Now().Add(-time.Hour*80), 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetIsolatedMarginPairConfig(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetIsolatedMarginPairConfig(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetIsolatedMarginPairConfig(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetIsolatedMarginAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetIsolatedMarginAccountInfo(t.Context(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetIsolatedMarginAccountInfo(t.Context(), "") assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetIsolatedMarginAccountInfo(t.Context(), "USDT") + result, err = e.GetIsolatedMarginAccountInfo(t.Context(), "USDT") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetSingleIsolatedMarginAccountInfo(t *testing.T) { t.Parallel() - _, err := ku.GetSingleIsolatedMarginAccountInfo(t.Context(), "") + _, err := e.GetSingleIsolatedMarginAccountInfo(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetSingleIsolatedMarginAccountInfo(t.Context(), spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSingleIsolatedMarginAccountInfo(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrentServerTime(t *testing.T) { t.Parallel() - result, err := ku.GetCurrentServerTime(t.Context()) + result, err := e.GetCurrentServerTime(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetServiceStatus(t *testing.T) { t.Parallel() - result, err := ku.GetServiceStatus(t.Context()) + result, err := e.GetServiceStatus(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } @@ -420,7 +420,7 @@ func TestPostOrder(t *testing.T) { t.Parallel() // default order type is limit - _, err := ku.PostOrder(t.Context(), &SpotOrderParam{ + _, err := e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: "", }) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) @@ -428,31 +428,31 @@ func TestPostOrder(t *testing.T) { customID, err := uuid.NewV4() assert.NoError(t, err) - _, err = ku.PostOrder(t.Context(), &SpotOrderParam{ + _, err = e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, OrderType: "", }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostOrder(t.Context(), &SpotOrderParam{ + _, err = e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: currency.EMPTYPAIR, Size: 0.1, Side: "buy", Price: 234565, }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = ku.PostOrder(t.Context(), &SpotOrderParam{ + _, err = e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "limit", Size: 0.1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.PostOrder(t.Context(), &SpotOrderParam{ + _, err = e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, Side: "buy", OrderType: "limit", Price: 234565, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PostOrder(t.Context(), &SpotOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, @@ -468,7 +468,7 @@ func TestPostOrderTest(t *testing.T) { t.Parallel() // default order type is limit - _, err := ku.PostOrderTest(t.Context(), &SpotOrderParam{ + _, err := e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: "", }) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) @@ -476,31 +476,31 @@ func TestPostOrderTest(t *testing.T) { customID, err := uuid.NewV4() assert.NoError(t, err) - _, err = ku.PostOrderTest(t.Context(), &SpotOrderParam{ + _, err = e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, OrderType: "", }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostOrderTest(t.Context(), &SpotOrderParam{ + _, err = e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: currency.EMPTYPAIR, Size: 0.1, Side: "buy", Price: 234565, }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = ku.PostOrderTest(t.Context(), &SpotOrderParam{ + _, err = e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "limit", Size: 0.1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.PostOrderTest(t.Context(), &SpotOrderParam{ + _, err = e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, Side: "buy", OrderType: "limit", Price: 234565, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.PostOrderTest(t.Context(), &SpotOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.PostOrderTest(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, @@ -515,7 +515,7 @@ func TestPostOrderTest(t *testing.T) { func TestHandlePostOrder(t *testing.T) { t.Parallel() // default order type is limit - _, err := ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err := e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: "", }, "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) @@ -523,46 +523,46 @@ func TestHandlePostOrder(t *testing.T) { customID, err := uuid.NewV4() assert.NoError(t, err) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, OrderType: "", }, "") require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: currency.EMPTYPAIR, Size: 0.1, Side: "buy", Price: 234565, }, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "OCO", Size: 0.1, }, "") require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "limit", Size: 0.1, }, "") require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "limit", Size: 0, Price: 1000, }, "") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Side: "buy", Symbol: spotTradablePair, OrderType: "limit", Size: .1, Price: 1000, VisibleSize: -1, }, "") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.HandlePostOrder(t.Context(), &SpotOrderParam{ + _, err = e.HandlePostOrder(t.Context(), &SpotOrderParam{ ClientOrderID: customID.String(), Symbol: spotTradablePair, Side: "buy", OrderType: "market", Price: 234565, }, "") @@ -572,35 +572,35 @@ func TestHandlePostOrder(t *testing.T) { func TestPostMarginOrder(t *testing.T) { t.Parallel() // default order type is limit - _, err := ku.PostMarginOrder(t.Context(), &MarginOrderParam{ + _, err := e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "", }) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.PostMarginOrder(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair, OrderType: "", }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostMarginOrder(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: currency.EMPTYPAIR, Size: 0.1, Side: "buy", Price: 234565, }) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.PostMarginOrder(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, OrderType: "limit", Size: 0.1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.PostMarginOrder(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair, Side: "buy", OrderType: "limit", Price: 234565, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) // default order type is limit and margin mode is cross - result, err := ku.PostMarginOrder(t.Context(), + result, err := e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, @@ -610,7 +610,7 @@ func TestPostMarginOrder(t *testing.T) { assert.NotNil(t, result) // market isolated order - result, err = ku.PostMarginOrder(t.Context(), + result, err = e.PostMarginOrder(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, @@ -624,35 +624,35 @@ func TestPostMarginOrder(t *testing.T) { func TestPostMarginOrderTest(t *testing.T) { t.Parallel() // default order type is limit - _, err := ku.PostMarginOrderTest(t.Context(), &MarginOrderParam{ + _, err := e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "", }) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.PostMarginOrderTest(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair, OrderType: "", }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostMarginOrderTest(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: currency.EMPTYPAIR, Size: 0.1, Side: "buy", Price: 234565, }) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.PostMarginOrderTest(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, OrderType: "limit", Size: 0.1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.PostMarginOrderTest(t.Context(), &MarginOrderParam{ + _, err = e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Symbol: marginTradablePair, Side: "buy", OrderType: "limit", Price: 234565, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) // default order type is limit and margin mode is cross - result, err := ku.PostMarginOrderTest(t.Context(), + result, err := e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, @@ -662,7 +662,7 @@ func TestPostMarginOrderTest(t *testing.T) { assert.NotNil(t, result) // market isolated order - result, err = ku.PostMarginOrderTest(t.Context(), + result, err = e.PostMarginOrderTest(t.Context(), &MarginOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: marginTradablePair, @@ -675,32 +675,32 @@ func TestPostMarginOrderTest(t *testing.T) { func TestPostBulkOrder(t *testing.T) { t.Parallel() - _, err := ku.PostBulkOrder(t.Context(), "", []OrderRequest{}) + _, err := e.PostBulkOrder(t.Context(), "", []OrderRequest{}) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{}) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := OrderRequest{ Size: 0.01, } - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) arg.ClientOID = "3d07008668054da6b3cb12e432c2b13a" arg.Size = 0 - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "Sell" - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.Price = 1000 - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{arg}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - _, err = ku.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.PostBulkOrder(t.Context(), spotTradablePair.String(), []OrderRequest{ { ClientOID: "3d07008668054da6b3cb12e432c2b13a", Side: "buy", @@ -721,30 +721,30 @@ func TestPostBulkOrder(t *testing.T) { func TestCancelSingleOrder(t *testing.T) { t.Parallel() - _, err := ku.CancelSingleOrder(t.Context(), "") + _, err := e.CancelSingleOrder(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelSingleOrder(t.Context(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelSingleOrder(t.Context(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelOrderByClientOID(t *testing.T) { t.Parallel() - _, err := ku.CancelOrderByClientOID(t.Context(), "") + _, err := e.CancelOrderByClientOID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelOrderByClientOID(t.Context(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelOrderByClientOID(t.Context(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllOpenOrders(t.Context(), "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllOpenOrders(t.Context(), "", "") assert.NoError(t, err) assert.NotNil(t, result) } @@ -756,51 +756,51 @@ func TestGetOrders(t *testing.T) { var resp *OrdersListResponse err := json.Unmarshal([]byte(ordersListResponseJSON), &resp) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - result, err := ku.ListOrders(t.Context(), "", "", "", "", "", time.Time{}, time.Time{}) + result, err := e.ListOrders(t.Context(), "", "", "", "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetRecentOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetRecentOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecentOrders(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderByID(t *testing.T) { t.Parallel() - _, err := ku.GetOrderByID(t.Context(), "") + _, err := e.GetOrderByID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetOrderByID(t.Context(), "5c35c02703aa673ceec2a168") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderByID(t.Context(), "5c35c02703aa673ceec2a168") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderByClientOID(t *testing.T) { t.Parallel() - _, err := ku.GetOrderByClientSuppliedOrderID(t.Context(), "") + _, err := e.GetOrderByClientSuppliedOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetOrderByClientSuppliedOrderID(t.Context(), "6d539dc614db312") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderByClientSuppliedOrderID(t.Context(), "6d539dc614db312") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFills(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFills(t.Context(), "", "", "", "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFills(t.Context(), "", "", "", "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetFills(t.Context(), "5c35c02703aa673ceec2a168", spotTradablePair.String(), "buy", "limit", SpotTradeType, time.Now().Add(-time.Hour*12), time.Now()) + result, err = e.GetFills(t.Context(), "5c35c02703aa673ceec2a168", spotTradablePair.String(), "buy", "limit", SpotTradeType, time.Now().Add(-time.Hour*12), time.Now()) assert.NoError(t, err) assert.NotNil(t, result) } @@ -813,53 +813,53 @@ func TestGetRecentFills(t *testing.T) { err := json.Unmarshal([]byte(limitFillsResponseJSON), &resp) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetRecentFills(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecentFills(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestPostStopOrder(t *testing.T) { t.Parallel() - _, err := ku.PostStopOrder(t.Context(), "", "buy", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) + _, err := e.PostStopOrder(t.Context(), "", "buy", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) + _, err = e.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "buy", "", "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) + _, err = e.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "buy", "", "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "buy", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PostStopOrder(t.Context(), "5bd6e9286d99522a52e458de", "buy", spotTradablePair.String(), "", "", "entry", "CO", SpotTradeType, "", 0.1, 1, 10, 0, 0, 0, true, false, false) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelStopOrder(t *testing.T) { t.Parallel() - _, err := ku.CancelStopOrder(t.Context(), "") + _, err := e.CancelStopOrder(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelStopOrder(t.Context(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelStopOrder(t.Context(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelStopOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelStopOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) + _, err := e.CancelStopOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelStopOrderByClientOrderID(t.Context(), "5bd6e9286d99522a52e458de", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelStopOrderByClientOrderID(t.Context(), "5bd6e9286d99522a52e458de", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllStopOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelStopOrders(t.Context(), "", "", []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelStopOrders(t.Context(), "", "", []string{}) assert.NoError(t, err) assert.NotNil(t, result) } @@ -871,103 +871,103 @@ func TestGetStopOrder(t *testing.T) { var resp *StopOrder err := json.Unmarshal([]byte(stopOrderResponseJSON), &resp) assert.NoError(t, err) - _, err = ku.GetStopOrder(t.Context(), "") + _, err = e.GetStopOrder(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetStopOrder(t.Context(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetStopOrder(t.Context(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllStopOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.ListStopOrders(t.Context(), "", "", "", "", []string{}, time.Time{}, time.Time{}, 0, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ListStopOrders(t.Context(), "", "", "", "", []string{}, time.Time{}, time.Time{}, 0, 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetStopOrderByClientID(t *testing.T) { t.Parallel() - _, err := ku.GetStopOrderByClientID(t.Context(), "", "") + _, err := e.GetStopOrderByClientID(t.Context(), "", "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetStopOrderByClientID(t.Context(), "", "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetStopOrderByClientID(t.Context(), "", "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelStopOrderByClientID(t *testing.T) { t.Parallel() - _, err := ku.CancelStopOrderByClientID(t.Context(), "", "") + _, err := e.CancelStopOrderByClientID(t.Context(), "", "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelStopOrderByClientID(t.Context(), "", "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelStopOrderByClientID(t.Context(), "", "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAllAccounts(t.Context(), currency.EMPTYCODE, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAllAccounts(t.Context(), currency.EMPTYCODE, "") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAccount(t *testing.T) { t.Parallel() - _, err := ku.GetAccountDetail(t.Context(), "") + _, err := e.GetAccountDetail(t.Context(), "") require.ErrorIs(t, err, errAccountIDMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAccountDetail(t.Context(), "62fcd1969474ea0001fd20e4") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountDetail(t.Context(), "62fcd1969474ea0001fd20e4") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetCrossMarginAccountsDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetCrossMarginAccountsDetail(t.Context(), "KCS", "MARGIN_V2") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCrossMarginAccountsDetail(t.Context(), "KCS", "MARGIN_V2") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetIsolatedMarginAccountDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetIsolatedMarginAccountDetail(t.Context(), marginTradablePair.String(), "BTC", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetIsolatedMarginAccountDetail(t.Context(), marginTradablePair.String(), "BTC", "") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesAccountDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesAccountDetail(t.Context(), currency.USDT) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesAccountDetail(t.Context(), currency.USDT) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetSubAccounts(t *testing.T) { t.Parallel() - _, err := ku.GetSubAccounts(t.Context(), "", false) + _, err := e.GetSubAccounts(t.Context(), "", false) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetSubAccounts(t.Context(), "5caefba7d9575a0688f83c45", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccounts(t.Context(), "5caefba7d9575a0688f83c45", false) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllFuturesSubAccountBalances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAllFuturesSubAccountBalances(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAllFuturesSubAccountBalances(t.Context(), currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } @@ -980,128 +980,128 @@ func TestGetAccountLedgers(t *testing.T) { err := json.Unmarshal([]byte(accountLedgerResponseJSON), &resp) assert.NoError(t, err) - _, err = ku.GetAccountLedgers(t.Context(), currency.EMPTYCODE, "", "", time.Now(), time.Now().Add(-time.Hour*24*10)) + _, err = e.GetAccountLedgers(t.Context(), currency.EMPTYCODE, "", "", time.Now(), time.Now().Add(-time.Hour*24*10)) require.ErrorIs(t, err, common.ErrStartAfterEnd) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAccountLedgers(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountLedgers(t.Context(), currency.EMPTYCODE, "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountLedgersHFTrade(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err := ku.GetAccountLedgersHFTrade(t.Context(), currency.BTC, "", "", 0, 10, time.Time{}, time.Now()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountLedgersHFTrade(t.Context(), currency.BTC, "", "", 0, 10, time.Time{}, time.Now()) assert.NoError(t, err) } func TestGetAccountLedgerHFMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAccountLedgerHFMargin(t.Context(), currency.BTC, "", "", 0, 0, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountLedgerHFMargin(t.Context(), currency.BTC, "", "", 0, 0, time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesAccountLedgers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesAccountLedgers(t.Context(), currency.BTC, true, time.Time{}, time.Now(), 0, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesAccountLedgers(t.Context(), currency.BTC, true, time.Time{}, time.Now(), 0, 100) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllSubAccountsInfoV1(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAllSubAccountsInfoV1(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAllSubAccountsInfoV1(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllSubAccountsInfoV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAllSubAccountsInfoV2(t.Context(), 0, 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAllSubAccountsInfoV2(t.Context(), 0, 30) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountSummaryInformation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAccountSummaryInformation(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountSummaryInformation(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAggregatedSubAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAggregatedSubAccountBalance(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAggregatedSubAccountBalance(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAllSubAccountsBalanceV2(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAllSubAccountsBalanceV2(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAllSubAccountsBalanceV2(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetPaginatedSubAccountInformation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetPaginatedSubAccountInformation(t.Context(), 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPaginatedSubAccountInformation(t.Context(), 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetTransferableBalance(t *testing.T) { t.Parallel() - _, err := ku.GetTransferableBalance(t.Context(), currency.EMPTYCODE, "MAIN", "") + _, err := e.GetTransferableBalance(t.Context(), currency.EMPTYCODE, "MAIN", "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.GetTransferableBalance(t.Context(), currency.BTC, "", "") + _, err = e.GetTransferableBalance(t.Context(), currency.BTC, "", "") require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetTransferableBalance(t.Context(), currency.BTC, "MAIN", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTransferableBalance(t.Context(), currency.BTC, "MAIN", "") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetUniversalTransfer(t *testing.T) { t.Parallel() - _, err := ku.GetUniversalTransfer(t.Context(), &UniversalTransferParam{}) + _, err := e.GetUniversalTransfer(t.Context(), &UniversalTransferParam{}) require.ErrorIs(t, err, common.ErrNilPointer) arg := &UniversalTransferParam{ ToAccountTag: "1234", } - _, err = ku.GetUniversalTransfer(t.Context(), arg) + _, err = e.GetUniversalTransfer(t.Context(), arg) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) arg.ClientSuppliedOrderID = "64ccc0f164781800010d8c09" - _, err = ku.GetUniversalTransfer(t.Context(), arg) + _, err = e.GetUniversalTransfer(t.Context(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 1 - _, err = ku.GetUniversalTransfer(t.Context(), arg) + _, err = e.GetUniversalTransfer(t.Context(), arg) require.ErrorIs(t, err, errAccountTypeMissing) arg.FromAccountType = "MAIN" - _, err = ku.GetUniversalTransfer(t.Context(), arg) + _, err = e.GetUniversalTransfer(t.Context(), arg) require.ErrorIs(t, err, errTransferTypeMissing) arg.TransferType = "INTERNAL" - _, err = ku.GetUniversalTransfer(t.Context(), arg) + _, err = e.GetUniversalTransfer(t.Context(), arg) require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.GetUniversalTransfer(t.Context(), &UniversalTransferParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.GetUniversalTransfer(t.Context(), &UniversalTransferParam{ ClientSuppliedOrderID: "64ccc0f164781800010d8c09", TransferType: "INTERNAL", Currency: currency.BTC, @@ -1112,7 +1112,7 @@ func TestGetUniversalTransfer(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetUniversalTransfer(t.Context(), &UniversalTransferParam{ + result, err = e.GetUniversalTransfer(t.Context(), &UniversalTransferParam{ ClientSuppliedOrderID: "64ccc0f164781800010d8c09", TransferType: "PARENT_TO_SUB", Currency: currency.BTC, @@ -1127,53 +1127,53 @@ func TestGetUniversalTransfer(t *testing.T) { func TestTransferMainToSubAccount(t *testing.T) { t.Parallel() - _, err := ku.TransferMainToSubAccount(t.Context(), currency.EMPTYCODE, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") + _, err := e.TransferMainToSubAccount(t.Context(), currency.EMPTYCODE, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "", "OUT", "", "", "5caefba7d9575a0688f83c45") + _, err = e.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "", "OUT", "", "", "5caefba7d9575a0688f83c45") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.TransferMainToSubAccount(t.Context(), currency.BTC, 0, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") + _, err = e.TransferMainToSubAccount(t.Context(), currency.BTC, 0, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "", "", "", "5caefba7d9575a0688f83c45") + _, err = e.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "", "", "", "5caefba7d9575a0688f83c45") require.ErrorIs(t, err, errTransferDirectionRequired) - _, err = ku.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "") + _, err = e.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "") require.ErrorIs(t, err, errSubUserIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TransferMainToSubAccount(t.Context(), currency.BTC, 1, "62fcd1969474ea0001fd20e4", "OUT", "", "", "5caefba7d9575a0688f83c45") assert.NoError(t, err) assert.NotNil(t, result) } func TestMakeInnerTransfer(t *testing.T) { t.Parallel() - _, err := ku.MakeInnerTransfer(t.Context(), 0, currency.EMPTYCODE, "62fcd1969474ea0001fd20e4", "trade", "main", "1", "") + _, err := e.MakeInnerTransfer(t.Context(), 0, currency.EMPTYCODE, "62fcd1969474ea0001fd20e4", "trade", "main", "1", "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.MakeInnerTransfer(t.Context(), 0, currency.USDT, "", "trade", "main", "1", "") + _, err = e.MakeInnerTransfer(t.Context(), 0, currency.USDT, "", "trade", "main", "1", "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.MakeInnerTransfer(t.Context(), 0, currency.USDT, "62fcd1969474ea0001fd20e4", "", "main", "", "") + _, err = e.MakeInnerTransfer(t.Context(), 0, currency.USDT, "62fcd1969474ea0001fd20e4", "", "main", "", "") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.MakeInnerTransfer(t.Context(), 1, currency.USDT, "62fcd1969474ea0001fd20e4", "", "main", "", "") + _, err = e.MakeInnerTransfer(t.Context(), 1, currency.USDT, "62fcd1969474ea0001fd20e4", "", "main", "", "") require.ErrorIs(t, err, errAccountTypeMissing) - _, err = ku.MakeInnerTransfer(t.Context(), 5, currency.USDT, "62fcd1969474ea0001fd20e4", "margin_hf", "", "", "") + _, err = e.MakeInnerTransfer(t.Context(), 5, currency.USDT, "62fcd1969474ea0001fd20e4", "margin_hf", "", "", "") require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.MakeInnerTransfer(t.Context(), 10, currency.USDT, "62fcd1969474ea0001fd20e4", "main", "trade_hf", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.MakeInnerTransfer(t.Context(), 10, currency.USDT, "62fcd1969474ea0001fd20e4", "main", "trade_hf", "", "") assert.NoError(t, err) assert.NotNil(t, result) } func TestTransferToMainOrTradeAccount(t *testing.T) { t.Parallel() - _, err := ku.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{}) + _, err := e.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{RecieveAccountType: "MAIN"}) + _, err = e.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{RecieveAccountType: "MAIN"}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{Amount: 1, RecieveAccountType: "MAIN"}) + _, err = e.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{Amount: 1, RecieveAccountType: "MAIN"}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TransferToMainOrTradeAccount(t.Context(), &FundTransferFuturesParam{ Amount: 1, Currency: currency.USDT, RecieveAccountType: SpotTradeType, @@ -1184,15 +1184,15 @@ func TestTransferToMainOrTradeAccount(t *testing.T) { func TestTransferToFuturesAccount(t *testing.T) { t.Parallel() - _, err := ku.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{}) + _, err := e.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{PaymentAccountType: "Main"}) + _, err = e.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{PaymentAccountType: "Main"}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{PaymentAccountType: "Main", Amount: 12}) + _, err = e.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{PaymentAccountType: "Main", Amount: 12}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TransferToFuturesAccount(t.Context(), &FundTransferToFuturesParam{ Amount: 60, Currency: currency.USDT, PaymentAccountType: SpotTradeType, @@ -1203,25 +1203,25 @@ func TestTransferToFuturesAccount(t *testing.T) { func TestGetFuturesTransferOutRequestRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesTransferOutRequestRecords(t.Context(), time.Time{}, time.Now(), "", "", currency.BTC, 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesTransferOutRequestRecords(t.Context(), time.Time{}, time.Now(), "", "", currency.BTC, 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestCreateDepositAddress(t *testing.T) { t.Parallel() - _, err := ku.CreateDepositAddress(t.Context(), &DepositAddressParams{}) + _, err := e.CreateDepositAddress(t.Context(), &DepositAddressParams{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CreateDepositAddress(t.Context(), &DepositAddressParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateDepositAddress(t.Context(), &DepositAddressParams{ Currency: currency.BTC, }) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.CreateDepositAddress(t.Context(), + result, err = e.CreateDepositAddress(t.Context(), &DepositAddressParams{ Currency: currency.USDT, Chain: "TRC20", @@ -1232,22 +1232,22 @@ func TestCreateDepositAddress(t *testing.T) { func TestGetDepositAddressV2(t *testing.T) { t.Parallel() - _, err := ku.GetDepositAddressesV2(t.Context(), currency.EMPTYCODE) + _, err := e.GetDepositAddressesV2(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetDepositAddressesV2(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositAddressesV2(t.Context(), currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetDepositAddressesV1(t *testing.T) { t.Parallel() - _, err := ku.GetDepositAddressV1(t.Context(), currency.EMPTYCODE, "") + _, err := e.GetDepositAddressV1(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetDepositAddressV1(t.Context(), currency.BTC, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositAddressV1(t.Context(), currency.BTC, "") assert.NoError(t, err) assert.NotNil(t, result) } @@ -1260,8 +1260,8 @@ func TestGetDepositList(t *testing.T) { err := json.Unmarshal([]byte(depositResponseJSON), &resp) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetDepositList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } @@ -1274,84 +1274,84 @@ func TestGetHistoricalDepositList(t *testing.T) { err := json.Unmarshal([]byte(historicalDepositResponseJSON), &resp) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHistoricalDepositList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHistoricalDepositList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetWithdrawalList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetHistoricalWithdrawalList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHistoricalWithdrawalList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHistoricalWithdrawalList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalQuotas(t *testing.T) { t.Parallel() - _, err := ku.GetWithdrawalQuotas(t.Context(), currency.EMPTYCODE, "") + _, err := e.GetWithdrawalQuotas(t.Context(), currency.EMPTYCODE, "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetWithdrawalQuotas(t.Context(), currency.BTC, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalQuotas(t.Context(), currency.BTC, "") assert.NoError(t, err) assert.NotNil(t, result) } func TestApplyWithdrawal(t *testing.T) { t.Parallel() - _, err := ku.ApplyWithdrawal(t.Context(), currency.EMPTYCODE, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 1) + _, err := e.ApplyWithdrawal(t.Context(), currency.EMPTYCODE, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 1) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.ApplyWithdrawal(t.Context(), currency.ETH, "", "", "", "", "", false, 1) + _, err = e.ApplyWithdrawal(t.Context(), currency.ETH, "", "", "", "", "", false, 1) require.ErrorIs(t, err, errAddressRequired) - _, err = ku.ApplyWithdrawal(t.Context(), currency.ETH, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 0) + _, err = e.ApplyWithdrawal(t.Context(), currency.ETH, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.ApplyWithdrawal(t.Context(), currency.ETH, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ApplyWithdrawal(t.Context(), currency.ETH, "0x597873884BC3a6C10cB6Eb7C69172028Fa85B25A", "", "", "", "", false, 1) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelWithdrawal(t *testing.T) { t.Parallel() - err := ku.CancelWithdrawal(t.Context(), "") + err := e.CancelWithdrawal(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - err = ku.CancelWithdrawal(t.Context(), "5bffb63303aa675e8bbe18f9") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.CancelWithdrawal(t.Context(), "5bffb63303aa675e8bbe18f9") assert.NoError(t, err) } func TestGetBasicFee(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetBasicFee(t.Context(), "1") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBasicFee(t.Context(), "1") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetTradingFee(t *testing.T) { t.Parallel() - _, err := ku.GetTradingFee(t.Context(), nil) + _, err := e.GetTradingFee(t.Context(), nil) require.ErrorIs(t, err, currency.ErrCurrencyPairsEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - avail, err := ku.GetAvailablePairs(asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + avail, err := e.GetAvailablePairs(asset.Spot) assert.NoError(t, err) assert.NotEmpty(t, avail) pairs := currency.Pairs{avail[0]} - btcusdTradingFee, err := ku.GetTradingFee(t.Context(), pairs) + btcusdTradingFee, err := e.GetTradingFee(t.Context(), pairs) assert.NoErrorf(t, err, "received %v, expected %v", err, nil) assert.Len(t, btcusdTradingFee, 1) @@ -1359,11 +1359,11 @@ func TestGetTradingFee(t *testing.T) { // the allowed pairs. If this does not error then this endpoint will allow // more items to be requested. pairs = append(pairs, avail[1:10]...) - result, err := ku.GetTradingFee(t.Context(), pairs) + result, err := e.GetTradingFee(t.Context(), pairs) assert.NoError(t, err) assert.NotNil(t, result) - got, err := ku.GetTradingFee(t.Context(), pairs[:10]) + got, err := e.GetTradingFee(t.Context(), pairs[:10]) assert.NoError(t, err) assert.Len(t, got, 10) } @@ -1371,27 +1371,27 @@ func TestGetTradingFee(t *testing.T) { // futures func TestGetFuturesOpenContracts(t *testing.T) { t.Parallel() - result, err := ku.GetFuturesOpenContracts(t.Context()) + result, err := e.GetFuturesOpenContracts(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesContract(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesContract(t.Context(), "") + _, err := e.GetFuturesContract(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesContract(t.Context(), "XBTUSDTM") + result, err := e.GetFuturesContract(t.Context(), "XBTUSDTM") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesTicker(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesTicker(t.Context(), "") + _, err := e.GetFuturesTicker(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - tick, err := ku.GetFuturesTicker(t.Context(), "XBTUSDTM") + tick, err := e.GetFuturesTicker(t.Context(), "XBTUSDTM") if assert.NoError(t, err) { assert.Positive(t, tick.Sequence, "Sequence should be positive") assert.Equal(t, "XBTUSDTM", tick.Symbol) @@ -1409,120 +1409,120 @@ func TestGetFuturesTicker(t *testing.T) { func TestGetFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesOrderbook(t.Context(), "") + _, err := e.GetFuturesOrderbook(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesOrderbook(t.Context(), futuresTradablePair.String()) + result, err := e.GetFuturesOrderbook(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPartOrderbook20(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPartOrderbook20(t.Context(), "") + _, err := e.GetFuturesPartOrderbook20(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesPartOrderbook20(t.Context(), "XBTUSDTM") + result, err := e.GetFuturesPartOrderbook20(t.Context(), "XBTUSDTM") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPartOrderbook100(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPartOrderbook100(t.Context(), "") + _, err := e.GetFuturesPartOrderbook100(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesPartOrderbook100(t.Context(), "XBTUSDTM") + result, err := e.GetFuturesPartOrderbook100(t.Context(), "XBTUSDTM") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesTradeHistory(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesTradeHistory(t.Context(), "") + _, err := e.GetFuturesTradeHistory(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesTradeHistory(t.Context(), "XBTUSDTM") + result, err := e.GetFuturesTradeHistory(t.Context(), "XBTUSDTM") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesInterestRate(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesInterestRate(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 0) + _, err := e.GetFuturesInterestRate(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 0) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesInterestRate(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 0) + result, err := e.GetFuturesInterestRate(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesIndexList(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesIndexList(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 10) + _, err := e.GetFuturesIndexList(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 10) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesIndexList(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 10) + result, err := e.GetFuturesIndexList(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesCurrentMarkPrice(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesCurrentMarkPrice(t.Context(), "") + _, err := e.GetFuturesCurrentMarkPrice(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesCurrentMarkPrice(t.Context(), futuresTradablePair.String()) + result, err := e.GetFuturesCurrentMarkPrice(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPremiumIndex(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPremiumIndex(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 0) + _, err := e.GetFuturesPremiumIndex(t.Context(), "", time.Time{}, time.Time{}, false, false, 0, 0) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesPremiumIndex(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 0) + result, err := e.GetFuturesPremiumIndex(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, false, false, 0, 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGet24HourFuturesTransactionVolume(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - resp, err := ku.Get24HourFuturesTransactionVolume(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + resp, err := e.Get24HourFuturesTransactionVolume(t.Context()) assert.NoError(t, err) assert.NotNil(t, resp) } func TestGetFuturesCurrentFundingRate(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesCurrentFundingRate(t.Context(), "") + _, err := e.GetFuturesCurrentFundingRate(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesCurrentFundingRate(t.Context(), futuresTradablePair.String()) + result, err := e.GetFuturesCurrentFundingRate(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicFundingRate(t *testing.T) { t.Parallel() - _, err := ku.GetPublicFundingRate(t.Context(), "", time.Now().Add(-time.Hour*24*30), time.Now().Add(-time.Hour*5)) + _, err := e.GetPublicFundingRate(t.Context(), "", time.Now().Add(-time.Hour*24*30), time.Now().Add(-time.Hour*5)) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetPublicFundingRate(t.Context(), futuresTradablePair.String(), time.Now().Add(-time.Hour*24*30), time.Now().Add(-time.Hour*5)) + result, err := e.GetPublicFundingRate(t.Context(), futuresTradablePair.String(), time.Now().Add(-time.Hour*24*30), time.Now().Add(-time.Hour*5)) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesServerTime(t *testing.T) { t.Parallel() - result, err := ku.GetFuturesServerTime(t.Context()) + result, err := e.GetFuturesServerTime(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesServiceStatus(t *testing.T) { t.Parallel() - result, err := ku.GetFuturesServiceStatus(t.Context()) + result, err := e.GetFuturesServiceStatus(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } @@ -1546,44 +1546,44 @@ func TestFuturesKlineUnmarshalJSON(t *testing.T) { func TestGetFuturesKline(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesKline(t.Context(), 0, "XBTUSDTM", time.Time{}, time.Time{}) + _, err := e.GetFuturesKline(t.Context(), 0, "XBTUSDTM", time.Time{}, time.Time{}) require.ErrorIs(t, err, kline.ErrInvalidInterval) - _, err = ku.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Seconds()), futuresTradablePair.String(), time.Time{}, time.Time{}) + _, err = e.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Seconds()), futuresTradablePair.String(), time.Time{}, time.Time{}) require.ErrorIs(t, err, kline.ErrUnsupportedInterval) - _, err = ku.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Minutes()), "", time.Time{}, time.Time{}) + _, err = e.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Minutes()), "", time.Time{}, time.Time{}) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - result, err := ku.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Minutes()), futuresTradablePair.String(), time.Time{}, time.Time{}) + result, err := e.GetFuturesKline(t.Context(), int64(kline.ThirtyMin.Duration().Minutes()), futuresTradablePair.String(), time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestPostFuturesOrder(t *testing.T) { t.Parallel() - _, err := ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy"}) + _, err := e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy"}) require.ErrorIs(t, err, errInvalidLeverage) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{Side: "buy", Leverage: 1}) + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{Side: "buy", Leverage: 1}) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Leverage: 1}) + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Leverage: 1}) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Leverage: 1}) + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Leverage: 1}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) // With Stop order configuration - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, errInvalidStopPriceType) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "TP", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "TP", StopPrice: 123456, TimeInForce: "", Size: 1, Price: 1000, Leverage: 1, VisibleSize: 0, }) @@ -1591,14 +1591,14 @@ func TestPostFuturesOrder(t *testing.T) { assert.NotNil(t, result) // Limit Orders - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Leverage: 1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Price: 1000, Leverage: 1, VisibleSize: 0}) + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Price: 1000, Leverage: 1, VisibleSize: 0}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - result, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + result, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Size: 1, Price: 1000, Leverage: 1, VisibleSize: 0, }) @@ -1606,18 +1606,18 @@ func TestPostFuturesOrder(t *testing.T) { assert.NotNil(t, result) // Market Orders - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "market", Remark: "10", Leverage: 1, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + _, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "market", Remark: "10", Size: 1, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - result, err = ku.PostFuturesOrder(t.Context(), &FuturesOrderParam{ + result, err = e.PostFuturesOrder(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, @@ -1638,61 +1638,61 @@ func TestPostFuturesOrder(t *testing.T) { func TestFillFuturesPostOrderArgumentFilter(t *testing.T) { t.Parallel() - err := ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy"}) + err := e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy"}) require.ErrorIs(t, err, errInvalidLeverage) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{Side: "buy", Leverage: 1}) + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{Side: "buy", Leverage: 1}) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Leverage: 1}) + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Leverage: 1}) require.ErrorIs(t, err, order.ErrSideIsInvalid) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Leverage: 1}) + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Leverage: 1}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) // With Stop order configuration - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, errInvalidStopPriceType) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "TP", TimeInForce: "", Size: 1, Price: 1000, StopPrice: 0, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Stop: "up", StopPriceType: "TP", StopPrice: 123456, TimeInForce: "", Size: 1, Price: 1000, Leverage: 1, VisibleSize: 0, }) assert.NoError(t, err) // Limit Orders - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Leverage: 1, }) require.ErrorIs(t, err, order.ErrPriceBelowMin) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Price: 1000, Leverage: 1, VisibleSize: 0}) + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Price: 1000, Leverage: 1, VisibleSize: 0}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "limit", Remark: "10", Size: 1, Price: 1000, Leverage: 1, VisibleSize: 0, }) assert.NoError(t, err) // Market Orders - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "market", Remark: "10", Leverage: 1, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, OrderType: "market", Remark: "10", Size: 0, Leverage: 1, VisibleSize: 0, }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - err = ku.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ + err = e.FillFuturesPostOrderArgumentFilter(&FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, @@ -1712,8 +1712,8 @@ func TestFillFuturesPostOrderArgumentFilter(t *testing.T) { func TestPostFuturesOrderTest(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - response, err := ku.PostFuturesOrderTest(t.Context(), &FuturesOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + response, err := e.PostFuturesOrderTest(t.Context(), &FuturesOrderParam{ ClientOrderID: "5bd6e9286d99522a52e458de", Side: "buy", Symbol: futuresTradablePair, @@ -1733,11 +1733,11 @@ func TestPostFuturesOrderTest(t *testing.T) { func TestPlaceMultipleFuturesOrders(t *testing.T) { t.Parallel() - _, err := ku.PlaceMultipleFuturesOrders(t.Context(), []FuturesOrderParam{}) + _, err := e.PlaceMultipleFuturesOrders(t.Context(), []FuturesOrderParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PlaceMultipleFuturesOrders(t.Context(), []FuturesOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceMultipleFuturesOrders(t.Context(), []FuturesOrderParam{ { ClientOrderID: "5c52e11203aa677f33e491", Side: "buy", @@ -1763,169 +1763,169 @@ func TestPlaceMultipleFuturesOrders(t *testing.T) { func TestCancelFuturesOrder(t *testing.T) { t.Parallel() - _, err := ku.CancelFuturesOrderByOrderID(t.Context(), "") + _, err := e.CancelFuturesOrderByOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelFuturesOrderByOrderID(t.Context(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelFuturesOrderByOrderID(t.Context(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelFuturesOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelFuturesOrderByClientOrderID(t.Context(), "", "") + _, err := e.CancelFuturesOrderByClientOrderID(t.Context(), "", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.CancelFuturesOrderByClientOrderID(t.Context(), futuresTradablePair.String(), "") + _, err = e.CancelFuturesOrderByClientOrderID(t.Context(), futuresTradablePair.String(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelFuturesOrderByClientOrderID(t.Context(), futuresTradablePair.String(), "5bd6e9286d99522a52e458de") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelFuturesOrderByClientOrderID(t.Context(), futuresTradablePair.String(), "5bd6e9286d99522a52e458de") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllFuturesOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelMultipleFuturesLimitOrders(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMultipleFuturesLimitOrders(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllFuturesStopOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllFuturesStopOrders(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllFuturesStopOrders(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesOrders(t.Context(), "", "", "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesOrders(t.Context(), "", "", "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetUntriggeredFuturesStopOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetUntriggeredFuturesStopOrders(t.Context(), "", "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUntriggeredFuturesStopOrders(t.Context(), "", "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesRecentCompletedOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesRecentCompletedOrders(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesRecentCompletedOrders(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesOrderDetails(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesOrderDetails(t.Context(), "", "") + _, err := e.GetFuturesOrderDetails(t.Context(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesOrderDetails(t.Context(), "5cdfc138b21023a909e5ad55", "2212332") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesOrderDetails(t.Context(), "5cdfc138b21023a909e5ad55", "2212332") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesOrderDetailsByClientID(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesOrderDetailsByClientOrderID(t.Context(), "") + _, err := e.GetFuturesOrderDetailsByClientOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesOrderDetailsByClientOrderID(t.Context(), "eresc138b21023a909e5ad59") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesOrderDetailsByClientOrderID(t.Context(), "eresc138b21023a909e5ad59") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesFills(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesFills(t.Context(), "", "", "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesFills(t.Context(), "", "", "", "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesRecentFills(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesRecentFills(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesRecentFills(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesOpenOrderStats(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesOpenOrderStats(t.Context(), "") + _, err := e.GetFuturesOpenOrderStats(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesOpenOrderStats(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesOpenOrderStats(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPosition(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPosition(t.Context(), "") + _, err := e.GetFuturesPosition(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesPosition(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesPosition(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPositionList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesPositionList(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesPositionList(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestSetAutoDepositMargin(t *testing.T) { t.Parallel() - _, err := ku.SetAutoDepositMargin(t.Context(), "", true) + _, err := e.SetAutoDepositMargin(t.Context(), "", true) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SetAutoDepositMargin(t.Context(), futuresTradablePair.String(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetAutoDepositMargin(t.Context(), futuresTradablePair.String(), true) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMaxWithdrawMargin(t *testing.T) { t.Parallel() - _, err := ku.GetMaxWithdrawMargin(t.Context(), "") + _, err := e.GetMaxWithdrawMargin(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetMaxWithdrawMargin(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaxWithdrawMargin(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestRemoveMarginManually(t *testing.T) { t.Parallel() - _, err := ku.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{}) + _, err := e.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{ + _, err = e.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{ WithdrawAmount: 1, }) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.RemoveMarginManually(t.Context(), &WithdrawMarginResponse{ Symbol: "ADAUSDTM", WithdrawAmount: 1, }) @@ -1935,75 +1935,75 @@ func TestRemoveMarginManually(t *testing.T) { func TestAddMargin(t *testing.T) { t.Parallel() - _, err := ku.AddMargin(t.Context(), "", "6200c9b83aecfb000152dasfdee", 1) + _, err := e.AddMargin(t.Context(), "", "6200c9b83aecfb000152dasfdee", 1) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.AddMargin(t.Context(), futuresTradablePair.String(), "6200c9b83aecfb000152dasfdee", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AddMargin(t.Context(), futuresTradablePair.String(), "6200c9b83aecfb000152dasfdee", 1) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesRiskLimitLevel(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesRiskLimitLevel(t.Context(), "") + _, err := e.GetFuturesRiskLimitLevel(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesRiskLimitLevel(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesRiskLimitLevel(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestUpdateRiskLmitLevel(t *testing.T) { t.Parallel() - _, err := ku.FuturesUpdateRiskLmitLevel(t.Context(), "", 2) + _, err := e.FuturesUpdateRiskLmitLevel(t.Context(), "", 2) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.FuturesUpdateRiskLmitLevel(t.Context(), futuresTradablePair.String(), 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.FuturesUpdateRiskLmitLevel(t.Context(), futuresTradablePair.String(), 2) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesFundingHistory(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesFundingHistory(t.Context(), "", 0, 0, true, true, time.Time{}, time.Time{}) + _, err := e.GetFuturesFundingHistory(t.Context(), "", 0, 0, true, true, time.Time{}, time.Time{}) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesFundingHistory(t.Context(), futuresTradablePair.String(), 0, 0, true, true, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesFundingHistory(t.Context(), futuresTradablePair.String(), 0, 0, true, true, time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesAccountOverview(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesAccountOverview(t.Context(), "BTC") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesAccountOverview(t.Context(), "BTC") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesTransactionHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesTransactionHistory(t.Context(), currency.EMPTYCODE, "", 0, 0, true, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesTransactionHistory(t.Context(), currency.EMPTYCODE, "", 0, 0, true, time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestCreateFuturesSubAccountAPIKey(t *testing.T) { t.Parallel() - _, err := ku.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "", "subAccName") + _, err := e.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "", "subAccName") require.ErrorIs(t, err, errRemarkIsRequired) - _, err = ku.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "remark", "") + _, err = e.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "remark", "") require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ku.CreateFuturesSubAccountAPIKey(t.Context(), "", "", "", "remark", "subAccName") + _, err = e.CreateFuturesSubAccountAPIKey(t.Context(), "", "", "", "remark", "subAccName") require.ErrorIs(t, err, errInvalidPassPhraseInstance) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "remark", "subAccName") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateFuturesSubAccountAPIKey(t.Context(), "", "passphrase", "", "remark", "subAccName") assert.NoError(t, err) assert.NotNil(t, result) } @@ -2014,49 +2014,49 @@ func TestTransferFuturesFundsToMainAccount(t *testing.T) { err := json.Unmarshal([]byte(transferFuturesFundsResponseJSON), &resp) assert.NoError(t, err) - _, err = ku.TransferFuturesFundsToMainAccount(t.Context(), 0, currency.USDT, "MAIN") + _, err = e.TransferFuturesFundsToMainAccount(t.Context(), 0, currency.USDT, "MAIN") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.EMPTYCODE, "MAIN") + _, err = e.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.EMPTYCODE, "MAIN") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.ETH, "") + _, err = e.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.ETH, "") require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.USDT, "MAIN") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TransferFuturesFundsToMainAccount(t.Context(), 1, currency.USDT, "MAIN") assert.NoError(t, err) assert.NotNil(t, result) } func TestTransferFundsToFuturesAccount(t *testing.T) { t.Parallel() - err := ku.TransferFundsToFuturesAccount(t.Context(), 0, currency.USDT, "MAIN") + err := e.TransferFundsToFuturesAccount(t.Context(), 0, currency.USDT, "MAIN") require.ErrorIs(t, err, order.ErrAmountBelowMin) - err = ku.TransferFundsToFuturesAccount(t.Context(), 1, currency.EMPTYCODE, "MAIN") + err = e.TransferFundsToFuturesAccount(t.Context(), 1, currency.EMPTYCODE, "MAIN") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - err = ku.TransferFundsToFuturesAccount(t.Context(), 1, currency.USDT, "") + err = e.TransferFundsToFuturesAccount(t.Context(), 1, currency.USDT, "") require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - err = ku.TransferFundsToFuturesAccount(t.Context(), 1, currency.USDT, "MAIN") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.TransferFundsToFuturesAccount(t.Context(), 1, currency.USDT, "MAIN") assert.NoError(t, err) } func TestGetFuturesTransferOutList(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesTransferOutList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) + _, err := e.GetFuturesTransferOutList(t.Context(), currency.EMPTYCODE, "", time.Time{}, time.Time{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesTransferOutList(t.Context(), currency.USDT, "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesTransferOutList(t.Context(), currency.USDT, "", time.Time{}, time.Time{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestFetchTradablePairs(t *testing.T) { t.Parallel() - assetTypes := ku.GetAssetTypes(true) + assetTypes := e.GetAssetTypes(true) for _, assetType := range assetTypes { - result, err := ku.FetchTradablePairs(t.Context(), assetType) + result, err := e.FetchTradablePairs(t.Context(), assetType) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2067,7 +2067,7 @@ func TestUpdateOrderbook(t *testing.T) { var result *orderbook.Book var err error for assetType, tp := range assertToTradablePairMap { - result, err = ku.UpdateOrderbook(t.Context(), tp, assetType) + result, err = e.UpdateOrderbook(t.Context(), tp, assetType) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2075,20 +2075,20 @@ func TestUpdateOrderbook(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - for _, a := range ku.GetAssetTypes(true) { - err := ku.UpdateTickers(t.Context(), a) + for _, a := range e.GetAssetTypes(true) { + err := e.UpdateTickers(t.Context(), a) assert.NoError(t, err) - pairs, err := ku.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) assert.NoError(t, err) assert.NotEmpty(t, pairs) for _, p := range pairs { - tick, err := ticker.GetTicker(ku.Name, p, a) + tick, err := ticker.GetTicker(e.Name, p, a) if assert.NoError(t, err) { assert.Positivef(t, tick.Last, "%s %s Tick Last should be positive", a, p) assert.NotEmptyf(t, tick.Pair, "%s %s Tick Pair should not be empty", a, p) - assert.Equalf(t, ku.Name, tick.ExchangeName, "ExchangeName should be correct") + assert.Equalf(t, e.Name, tick.ExchangeName, "ExchangeName should be correct") assert.Equalf(t, a, tick.AssetType, "AssetType should be correct") assert.NotEmptyf(t, tick.LastUpdated, "%s %s Tick LastUpdated should not be empty", a, p) } @@ -2101,7 +2101,7 @@ func TestUpdateTicker(t *testing.T) { var result *ticker.Price var err error for assetType, tp := range assertToTradablePairMap { - result, err = ku.UpdateTicker(t.Context(), tp, assetType) + result, err = e.UpdateTicker(t.Context(), tp, assetType) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2113,7 +2113,7 @@ func TestGetHistoricCandles(t *testing.T) { var result *kline.Item var err error for assetType, tp := range assertToTradablePairMap { - result, err = ku.GetHistoricCandles(t.Context(), tp, assetType, kline.OneHour, startTime, endTime) + result, err = e.GetHistoricCandles(t.Context(), tp, assetType, kline.OneHour, startTime, endTime) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2122,15 +2122,15 @@ func TestGetHistoricCandles(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { startTime := time.Now().Add(-time.Hour * 48 * 10) endTime := time.Now().Add(-time.Hour * 1) - result, err := ku.GetHistoricCandlesExtended(t.Context(), futuresTradablePair, asset.Futures, kline.FifteenMin, startTime, endTime) + result, err := e.GetHistoricCandlesExtended(t.Context(), futuresTradablePair, asset.Futures, kline.FifteenMin, startTime, endTime) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetHistoricCandlesExtended(t.Context(), spotTradablePair, asset.Spot, kline.FifteenMin, startTime, endTime) + result, err = e.GetHistoricCandlesExtended(t.Context(), spotTradablePair, asset.Spot, kline.FifteenMin, startTime, endTime) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetHistoricCandlesExtended(t.Context(), marginTradablePair, asset.Margin, kline.FifteenMin, startTime, endTime) + result, err = e.GetHistoricCandlesExtended(t.Context(), marginTradablePair, asset.Margin, kline.FifteenMin, startTime, endTime) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2138,7 +2138,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() for _, a := range []asset.Item{asset.Spot, asset.Futures, asset.Margin} { - result, err := ku.GetServerTime(t.Context(), a) + result, err := e.GetServerTime(t.Context(), a) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2149,7 +2149,7 @@ func TestGetRecentTrades(t *testing.T) { var result []trade.Data var err error for assetType, tp := range assertToTradablePairMap { - result, err = ku.GetRecentTrades(t.Context(), tp, assetType) + result, err = e.GetRecentTrades(t.Context(), tp, assetType) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2163,52 +2163,52 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Binary, Side: order.AnySide, } - _, err := ku.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest.AssetType = asset.Futures - result, err := ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.AssetType = asset.Spot getOrdersRequest.Pairs = []currency.Pair{} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.Pairs = []currency.Pair{spotTradablePair} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.Type = order.OCO getOrdersRequest.Pairs = []currency.Pair{} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.Pairs = []currency.Pair{spotTradablePair} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.AssetType = asset.Margin getOrdersRequest.Type = order.Stop getOrdersRequest.Pairs = []currency.Pair{spotTradablePair} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.Pairs = []currency.Pair{} - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.Type = order.StopLimit getOrdersRequest.MarginType = margin.Multi - result, err = ku.GetOrderHistory(t.Context(), &getOrdersRequest) + result, err = e.GetOrderHistory(t.Context(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2217,7 +2217,7 @@ func TestGetActiveOrders(t *testing.T) { t.Parallel() var getOrdersRequest order.MultiOrderRequest - enabledPairs, err := ku.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) assert.NoError(t, err) getOrdersRequest = order.MultiOrderRequest{ Pairs: enabledPairs, @@ -2226,23 +2226,23 @@ func TestGetActiveOrders(t *testing.T) { } getOrdersRequest.Type = order.OptimalLimit - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) require.ErrorIs(t, err, order.ErrUnsupportedOrderType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest.Type = order.Limit - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Pairs = []currency.Pair{} - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.Market - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) - enabledPairs, err = ku.GetEnabledPairs(asset.Spot) + enabledPairs, err = e.GetEnabledPairs(asset.Spot) assert.NoError(t, err) getOrdersRequest = order.MultiOrderRequest{ @@ -2251,30 +2251,30 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Margin, Side: order.Buy, } - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Pairs = []currency.Pair{} - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.Market - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.OCO - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.StopMarket - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.Stop - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) - enabledPairs, err = ku.GetEnabledPairs(asset.Futures) + enabledPairs, err = e.GetEnabledPairs(asset.Futures) assert.NoError(t, err) getOrdersRequest = order.MultiOrderRequest{ @@ -2283,22 +2283,22 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Futures, Side: order.Buy, } - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Pairs = []currency.Pair{} - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) getOrdersRequest.Type = order.StopLimit - _, err = ku.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err = e.GetActiveOrders(t.Context(), &getOrdersRequest) assert.NoError(t, err) } func TestGetFeeByType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFeeByType(t.Context(), &exchange.FeeBuilder{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFeeByType(t.Context(), &exchange.FeeBuilder{ Amount: 1, FeeType: exchange.CryptocurrencyTradeFee, Pair: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), currency.DashDelimiter), @@ -2312,32 +2312,32 @@ func TestGetFeeByType(t *testing.T) { func TestValidateCredentials(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - assetTypes := ku.CurrencyPairs.GetAssetTypes(true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + assetTypes := e.CurrencyPairs.GetAssetTypes(true) for _, at := range assetTypes { - err := ku.ValidateCredentials(t.Context(), at) + err := e.ValidateCredentials(t.Context(), at) assert.NoError(t, err) } } func TestGetInstanceServers(t *testing.T) { t.Parallel() - result, err := ku.GetInstanceServers(t.Context()) + result, err := e.GetInstanceServers(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAuthenticatedServersInstances(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAuthenticatedInstanceServers(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAuthenticatedInstanceServers(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestPushData(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) ku.SetCredentials("mock", "test", "test", "", "", "") ku.API.AuthenticatedSupport = true ku.API.AuthenticatedWebsocketSupport = true @@ -2347,7 +2347,7 @@ func TestPushData(t *testing.T) { func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) // Pairs overlap for spot/margin tests: // Only in Spot: BTC-USDT, ETH-USDT @@ -2410,7 +2410,7 @@ func TestGenerateSubscriptions(t *testing.T) { func TestGenerateTickerAllSub(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) avail, err := ku.GetAvailablePairs(asset.Spot) require.NoError(t, err, "GetAvailablePairs must not error") err = ku.CurrencyPairs.StorePairs(asset.Spot, avail[:11], true) @@ -2429,7 +2429,7 @@ func TestGenerateTickerAllSub(t *testing.T) { func TestGenerateOtherSubscriptions(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) subs := subscription.List{ {Channel: subscription.CandlesChannel, Asset: asset.Spot, Interval: kline.FourHour}, @@ -2452,7 +2452,7 @@ func TestGenerateOtherSubscriptions(t *testing.T) { func TestGenerateMarginSubscriptions(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) avail, err := ku.GetAvailablePairs(asset.Spot) require.NoError(t, err, "GetAvailablePairs must not error storing spot pairs") @@ -2489,7 +2489,7 @@ func TestGenerateMarginSubscriptions(t *testing.T) { func TestCheckSubscriptions(t *testing.T) { t.Parallel() - ku := &Kucoin{ //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := &Exchange{ Base: exchange.Base{ Config: &config.Exchange{ Features: &config.FeaturesConfig{ @@ -2520,70 +2520,70 @@ func TestCheckSubscriptions(t *testing.T) { func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAvailableTransferChains(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAvailableTransferChains(t.Context(), currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - _, err := ku.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Options) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Options) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Futures) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Futures) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + result, err = e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) var result *order.Detail var err error - result, err = ku.GetOrderInfo(t.Context(), "54541241349183409134134133", futuresTradablePair, asset.Futures) + result, err = e.GetOrderInfo(t.Context(), "54541241349183409134134133", futuresTradablePair, asset.Futures) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetOrderInfo(t.Context(), "54541241349183409134134133", spotTradablePair, asset.Spot) + result, err = e.GetOrderInfo(t.Context(), "54541241349183409134134133", spotTradablePair, asset.Spot) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.GetOrderInfo(t.Context(), "54541241349183409134134133", marginTradablePair, asset.Margin) + result, err = e.GetOrderInfo(t.Context(), "54541241349183409134134133", marginTradablePair, asset.Margin) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err := ku.GetDepositAddress(t.Context(), currency.BTC, "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") assert.Truef(t, err == nil || errors.Is(err, errNoDepositAddress), "GetDepositAddress should not error: %s", err) } func TestWithdrawCryptocurrencyFunds(t *testing.T) { t.Parallel() - _, err := ku.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: ku.Name, + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Amount: 0.00000000001, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, }, }) assert.ErrorContains(t, err, withdraw.ErrStrNoCurrencySet) - _, err = ku.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: ku.Name, + _, err = e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Amount: 0.00000000001, Currency: currency.BTC, Crypto: withdraw.CryptoRequest{}, }) assert.ErrorContains(t, err, "address cannot be empty") - _, err = ku.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: ku.Name, + _, err = e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Currency: currency.BTC, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, @@ -2591,9 +2591,9 @@ func TestWithdrawCryptocurrencyFunds(t *testing.T) { }) assert.ErrorContains(t, err, withdraw.ErrStrAmountMustBeGreaterThanZero) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ - Exchange: ku.Name, + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdraw.Request{ + Exchange: e.Name, Amount: 0.00000000001, Currency: currency.BTC, Crypto: withdraw.CryptoRequest{ @@ -2608,7 +2608,7 @@ func TestSubmitOrder(t *testing.T) { t.Parallel() orderSubmission := &order.Submit{ Pair: futuresTradablePair, - Exchange: ku.Name, + Exchange: e.Name, Side: order.Bid, Type: order.Limit, Price: 1, @@ -2616,20 +2616,20 @@ func TestSubmitOrder(t *testing.T) { ClientOrderID: "myOrder", AssetType: asset.Options, } - _, err := ku.SubmitOrder(t.Context(), orderSubmission) + _, err := e.SubmitOrder(t.Context(), orderSubmission) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderSubmission.AssetType = asset.Futures orderSubmission.Pair = futuresTradablePair - result, err := ku.SubmitOrder(t.Context(), orderSubmission) + result, err := e.SubmitOrder(t.Context(), orderSubmission) assert.NoError(t, err) assert.NotNil(t, result) orderSubmission.Type = order.OCO orderSubmission.TriggerPrice = 50000 orderSubmission.TriggerPriceType = order.LastPrice - _, err = ku.SubmitOrder(t.Context(), orderSubmission) + _, err = e.SubmitOrder(t.Context(), orderSubmission) require.ErrorIs(t, err, order.ErrUnsupportedOrderType) // Spot order creation tests @@ -2642,7 +2642,7 @@ func TestSubmitOrder(t *testing.T) { Amount: 100000, ClientOrderID: "myOrder", } - result, err = ku.SubmitOrder(t.Context(), spotOrderSubmission) + result, err = e.SubmitOrder(t.Context(), spotOrderSubmission) assert.NoError(t, err) assert.NotNil(t, result) @@ -2654,7 +2654,7 @@ func TestSubmitOrder(t *testing.T) { TriggerPriceType: order.LastPrice, }, } - result, err = ku.SubmitOrder(t.Context(), spotOrderSubmission) + result, err = e.SubmitOrder(t.Context(), spotOrderSubmission) assert.NoError(t, err) assert.NotNil(t, result) @@ -2670,12 +2670,12 @@ func TestSubmitOrder(t *testing.T) { Price: 1234, TriggerPriceType: order.LastPrice, } - result, err = ku.SubmitOrder(t.Context(), spotOrderSubmission) + result, err = e.SubmitOrder(t.Context(), spotOrderSubmission) assert.NoError(t, err) assert.NotNil(t, result) spotOrderSubmission.Type = order.ConditionalStop - _, err = ku.SubmitOrder(t.Context(), spotOrderSubmission) + _, err = e.SubmitOrder(t.Context(), spotOrderSubmission) require.ErrorIs(t, err, order.ErrUnsupportedOrderType) // Margin order creation tests @@ -2688,111 +2688,111 @@ func TestSubmitOrder(t *testing.T) { Amount: 100000, ClientOrderID: "myOrder", } - result, err = ku.SubmitOrder(t.Context(), marginOrderSubmission) + result, err = e.SubmitOrder(t.Context(), marginOrderSubmission) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellation := &order.Cancel{ OrderID: "1", AccountID: "1", Pair: futuresTradablePair, AssetType: asset.Options, } - err := ku.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) require.ErrorIs(t, err, asset.ErrNotSupported) orderCancellation.AssetType = asset.Futures - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.OrderID = "" orderCancellation.ClientOrderID = "12345" - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.Pair = currency.EMPTYPAIR - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) orderCancellation.AssetType = asset.Spot orderCancellation.Pair = spotTradablePair - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.Type = order.OCO - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.OrderID = "12345" orderCancellation.ClientOrderID = "" - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.Type = order.Stop - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.OrderID = "" orderCancellation.ClientOrderID = "12345" - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.Type = order.Limit orderCancellation.AssetType = asset.Margin - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.ClientOrderID = "" orderCancellation.OrderID = "12345" - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.AssetType = asset.Margin - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) orderCancellation.ClientOrderID = "" orderCancellation.OrderID = "12345" orderCancellation.AssetType = asset.Margin - err = ku.CancelOrder(t.Context(), orderCancellation) + err = e.CancelOrder(t.Context(), orderCancellation) assert.NoError(t, err) } func TestCancelAllOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllOrders(t.Context(), &order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllOrders(t.Context(), &order.Cancel{ AssetType: asset.Futures, MarginType: margin.Isolated, }) assert.NoError(t, err) assert.NotNil(t, result) - _, err = ku.CancelAllOrders(t.Context(), &order.Cancel{ + _, err = e.CancelAllOrders(t.Context(), &order.Cancel{ AssetType: asset.Margin, MarginType: margin.Isolated, }) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - result, err = ku.CancelAllOrders(t.Context(), &order.Cancel{ + result, err = e.CancelAllOrders(t.Context(), &order.Cancel{ AssetType: asset.Spot, Type: order.OCO, }) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.CancelAllOrders(t.Context(), &order.Cancel{ + result, err = e.CancelAllOrders(t.Context(), &order.Cancel{ AssetType: asset.Spot, Type: order.Stop, }) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.CancelAllOrders(t.Context(), &order.Cancel{ + result, err = e.CancelAllOrders(t.Context(), &order.Cancel{ AssetType: asset.Spot, Type: order.StopLimit, }) @@ -2811,51 +2811,51 @@ func TestCreateSubUser(t *testing.T) { var resp *SubAccount err := json.Unmarshal([]byte(subUserResponseJSON), &resp) assert.NoError(t, err) - _, err = ku.CreateSubUser(t.Context(), "", "Subaccount-1", "", "") + _, err = e.CreateSubUser(t.Context(), "", "Subaccount-1", "", "") require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ku.CreateSubUser(t.Context(), "Subaccount-2", "", "", "") + _, err = e.CreateSubUser(t.Context(), "Subaccount-2", "", "", "") require.ErrorIs(t, err, errInvalidPassPhraseInstance) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CreateSubUser(t.Context(), "Subaccount-2", "Subaccount-1", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateSubUser(t.Context(), "Subaccount-2", "Subaccount-1", "", "") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetSubAccountSpotAPIList(t *testing.T) { t.Parallel() - _, err := ku.GetSubAccountSpotAPIList(t.Context(), "", "") + _, err := e.GetSubAccountSpotAPIList(t.Context(), "", "") require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetSubAccountSpotAPIList(t.Context(), "Sam", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccountSpotAPIList(t.Context(), "Sam", "") assert.NoError(t, err) assert.NotNil(t, result) } func TestCreateSpotAPIsForSubAccount(t *testing.T) { t.Parallel() - _, err := ku.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ + _, err := e.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "", Passphrase: "mysecretPassphrase123", Remark: "the-remark", }) require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ku.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ + _, err = e.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "gocryptoTrader1", Passphrase: "", Remark: "the-remark", }) require.ErrorIs(t, err, errInvalidPassPhraseInstance) - _, err = ku.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ + _, err = e.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "gocryptoTrader1", Passphrase: "mysecretPassphrase123", Remark: "", }) require.ErrorIs(t, err, errRemarkIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateSpotAPIsForSubAccount(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "gocryptoTrader1", Passphrase: "mysecretPassphrase123", Remark: "the-remark", @@ -2869,21 +2869,21 @@ func TestModifySubAccountSpotAPIs(t *testing.T) { var resp SpotAPISubAccount err := json.Unmarshal([]byte(modifySubAccountSpotAPIs), &resp) assert.NoError(t, err) - _, err = ku.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ + _, err = e.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ APIKey: "65e7f22077172b0001f9ee41", SubAccountName: "", Passphrase: "mysecretPassphrase123", }) require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ku.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ + _, err = e.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "gocryptoTrader1", Passphrase: "mysecretPassphrase123", }) require.ErrorIs(t, err, errAPIKeyRequired) - _, err = ku.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ + _, err = e.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ APIKey: "65e7f22077172b0001f9ee41", SubAccountName: "gocryptoTrader1", Passphrase: "", }) require.ErrorIs(t, err, errInvalidPassPhraseInstance) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ModifySubAccountSpotAPIs(t.Context(), &SpotAPISubAccountParams{ SubAccountName: "gocryptoTrader1", Passphrase: "mysecretPassphrase123", APIKey: apiKey, @@ -2894,58 +2894,58 @@ func TestModifySubAccountSpotAPIs(t *testing.T) { func TestDeleteSubAccountSpotAPI(t *testing.T) { t.Parallel() - _, err := ku.DeleteSubAccountSpotAPI(t.Context(), "65e7f22077172b0001f9ee41", "", "the-passphrase") + _, err := e.DeleteSubAccountSpotAPI(t.Context(), "65e7f22077172b0001f9ee41", "", "the-passphrase") require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ku.DeleteSubAccountSpotAPI(t.Context(), "", "gocryptoTrader1", "the-passphrase") + _, err = e.DeleteSubAccountSpotAPI(t.Context(), "", "gocryptoTrader1", "the-passphrase") require.ErrorIs(t, err, errAPIKeyRequired) - _, err = ku.DeleteSubAccountSpotAPI(t.Context(), "65e7f22077172b0001f9ee41", "gocryptoTrader1", "") + _, err = e.DeleteSubAccountSpotAPI(t.Context(), "65e7f22077172b0001f9ee41", "gocryptoTrader1", "") require.ErrorIs(t, err, errInvalidPassPhraseInstance) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.DeleteSubAccountSpotAPI(t.Context(), apiKey, "gocryptoTrader1", "the-passphrase") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.DeleteSubAccountSpotAPI(t.Context(), apiKey, "gocryptoTrader1", "the-passphrase") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetUserInfoOfAllSubAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetUserInfoOfAllSubAccounts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserInfoOfAllSubAccounts(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetPaginatedListOfSubAccounts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetPaginatedListOfSubAccounts(t.Context(), 1, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPaginatedListOfSubAccounts(t.Context(), 1, 100) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAccountFundingHistory(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountFundingHistory(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func getFirstTradablePairOfAssets(ctx context.Context) { - if err := ku.UpdateTradablePairs(ctx, true); err != nil { + if err := e.UpdateTradablePairs(ctx, true); err != nil { log.Fatalf("Kucoin error while updating tradable pairs. %v", err) } - enabledPairs, err := ku.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Spot) } spotTradablePair = enabledPairs[0] - enabledPairs, err = ku.GetEnabledPairs(asset.Margin) + enabledPairs, err = e.GetEnabledPairs(asset.Margin) if err != nil { log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Margin) } marginTradablePair = enabledPairs[0] - enabledPairs, err = ku.GetEnabledPairs(asset.Futures) + enabledPairs, err = e.GetEnabledPairs(asset.Futures) if err != nil { log.Fatalf("Kucoin %v, trying to get %v enabled pairs error", err, asset.Futures) } @@ -2955,10 +2955,10 @@ func getFirstTradablePairOfAssets(ctx context.Context) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - assetTypes := ku.GetAssetTypes(true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + assetTypes := e.GetAssetTypes(true) for _, assetType := range assetTypes { - result, err := ku.UpdateAccountInfo(t.Context(), assetType) + result, err := e.UpdateAccountInfo(t.Context(), assetType) assert.NoError(t, err) assert.NotNil(t, result) } @@ -2974,21 +2974,21 @@ func TestProcessOrderbook(t *testing.T) { response := &WsOrderbook{} err := json.Unmarshal([]byte(wsOrderbookData), &response) assert.NoError(t, err) - ku.setupOrderbookManager(t.Context()) - result, err := ku.updateLocalBuffer(response, asset.Spot) + e.setupOrderbookManager(t.Context()) + result, err := e.updateLocalBuffer(response, asset.Spot) assert.NoError(t, err) assert.NotNil(t, result) - err = ku.processOrderbook([]byte(orderbookLevel5PushData), "BTC-USDT", "") + err = e.processOrderbook([]byte(orderbookLevel5PushData), "BTC-USDT", "") assert.NoError(t, err) assert.NotNil(t, result) - err = ku.wsHandleData(t.Context(), []byte(orderbookLevel5PushData)) + err = e.wsHandleData(t.Context(), []byte(orderbookLevel5PushData)) assert.NoError(t, err) assert.NotNil(t, result) } func TestProcessMarketSnapshot(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) testexch.FixtureToDataHandler(t, "testdata/wsMarketSnapshot.json", ku.wsHandleData) close(ku.Websocket.DataHandler) assert.Len(t, ku.Websocket.DataHandler, 4, "Should see 4 tickers") @@ -3039,7 +3039,7 @@ func TestProcessMarketSnapshot(t *testing.T) { func TestSubscribeBatches(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) ku.Features.Subscriptions = subscription.List{} testexch.SetupWs(t, ku) @@ -3066,7 +3066,7 @@ func TestSubscribeBatchLimit(t *testing.T) { const expectedLimit = 400 - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) ku.Features.Subscriptions = subscription.List{} testexch.SetupWs(t, ku) @@ -3103,7 +3103,7 @@ func TestSubscribeBatchLimit(t *testing.T) { func TestSubscribeTickerAll(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) ku.Features.Subscriptions = subscription.List{} testexch.SetupWs(t, ku) @@ -3126,40 +3126,40 @@ func TestSubscribeTickerAll(t *testing.T) { func TestSeedLocalCache(t *testing.T) { t.Parallel() - err := ku.SeedLocalCache(t.Context(), marginTradablePair, asset.Margin) + err := e.SeedLocalCache(t.Context(), marginTradablePair, asset.Margin) assert.NoError(t, err) } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesContractDetails(t.Context(), asset.Spot) + _, err := e.GetFuturesContractDetails(t.Context(), asset.Spot) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = ku.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures) require.ErrorIs(t, err, asset.ErrNotSupported) - result, err := ku.GetFuturesContractDetails(t.Context(), asset.Futures) + result, err := e.GetFuturesContractDetails(t.Context(), asset.Futures) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetLatestFundingRates(t *testing.T) { t.Parallel() - _, err := ku.GetLatestFundingRates(t.Context(), nil) + _, err := e.GetLatestFundingRates(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) req := &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: currency.NewBTCUSD(), } - _, err = ku.GetLatestFundingRates(t.Context(), req) + _, err = e.GetLatestFundingRates(t.Context(), req) require.ErrorIs(t, err, futures.ErrNotPerpetualFuture) req = &fundingrate.LatestRateRequest{ Asset: asset.Futures, Pair: currency.NewPair(currency.XBT, currency.USDTM), } - resp, err := ku.GetLatestFundingRates(t.Context(), req) + resp, err := e.GetLatestFundingRates(t.Context(), req) assert.NoError(t, err) assert.Len(t, resp, 1) @@ -3167,129 +3167,129 @@ func TestGetLatestFundingRates(t *testing.T) { Asset: asset.Futures, Pair: currency.EMPTYPAIR, } - resp, err = ku.GetLatestFundingRates(t.Context(), req) + resp, err = e.GetLatestFundingRates(t.Context(), req) assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := ku.IsPerpetualFutureCurrency(asset.Spot, currency.EMPTYPAIR) + is, err := e.IsPerpetualFutureCurrency(asset.Spot, currency.EMPTYPAIR) assert.NoError(t, err) assert.False(t, is) - is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.EMPTYPAIR) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, currency.EMPTYPAIR) assert.NoError(t, err) assert.False(t, is) - is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.EOS)) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.EOS)) assert.NoError(t, err) assert.False(t, is) - is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDTM)) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDTM)) assert.NoError(t, err) assert.True(t, is) - is, err = ku.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDM)) + is, err = e.IsPerpetualFutureCurrency(asset.Futures, currency.NewPair(currency.XBT, currency.USDM)) assert.NoError(t, err) assert.True(t, is) } func TestChangePositionMargin(t *testing.T) { t.Parallel() - _, err := ku.ChangePositionMargin(t.Context(), nil) + _, err := e.ChangePositionMargin(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) req := &margin.PositionChangeRequest{} - _, err = ku.ChangePositionMargin(t.Context(), req) + _, err = e.ChangePositionMargin(t.Context(), req) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) req.Asset = asset.Futures - _, err = ku.ChangePositionMargin(t.Context(), req) + _, err = e.ChangePositionMargin(t.Context(), req) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) req.Pair = currency.NewPair(currency.XBT, currency.USDTM) - _, err = ku.ChangePositionMargin(t.Context(), req) + _, err = e.ChangePositionMargin(t.Context(), req) require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req.MarginType = margin.Isolated - result, err := ku.ChangePositionMargin(t.Context(), req) + result, err := e.ChangePositionMargin(t.Context(), req) assert.NoError(t, err) assert.NotNil(t, result) req.NewAllocatedMargin = 1337 - result, err = ku.ChangePositionMargin(t.Context(), req) + result, err = e.ChangePositionMargin(t.Context(), req) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPositionSummary(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPositionSummary(t.Context(), nil) + _, err := e.GetFuturesPositionSummary(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) req := &futures.PositionSummaryRequest{} - _, err = ku.GetFuturesPositionSummary(t.Context(), req) + _, err = e.GetFuturesPositionSummary(t.Context(), req) require.ErrorIs(t, err, futures.ErrNotPerpetualFuture) req.Asset = asset.Futures - _, err = ku.GetFuturesPositionSummary(t.Context(), req) + _, err = e.GetFuturesPositionSummary(t.Context(), req) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req.Pair = currency.NewPair(currency.XBT, currency.USDTM) - result, err := ku.GetFuturesPositionSummary(t.Context(), req) + result, err := e.GetFuturesPositionSummary(t.Context(), req) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesPositionOrders(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesPositionOrders(t.Context(), nil) + _, err := e.GetFuturesPositionOrders(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) req := &futures.PositionsRequest{} - _, err = ku.GetFuturesPositionOrders(t.Context(), req) + _, err = e.GetFuturesPositionOrders(t.Context(), req) require.ErrorIs(t, err, futures.ErrNotPerpetualFuture) req.Asset = asset.Futures - _, err = ku.GetFuturesPositionOrders(t.Context(), req) + _, err = e.GetFuturesPositionOrders(t.Context(), req) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) req.Pairs = currency.Pairs{ currency.NewPair(currency.XBT, currency.USDTM), } - _, err = ku.GetFuturesPositionOrders(t.Context(), req) + _, err = e.GetFuturesPositionOrders(t.Context(), req) require.ErrorIs(t, err, common.ErrDateUnset) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) req.EndDate = time.Now() req.StartDate = req.EndDate.Add(-time.Hour * 24 * 7) - _, err = ku.GetFuturesPositionOrders(t.Context(), req) + _, err = e.GetFuturesPositionOrders(t.Context(), req) assert.NoError(t, err) req.StartDate = req.EndDate.Add(-time.Hour * 24 * 30) - _, err = ku.GetFuturesPositionOrders(t.Context(), req) + _, err = e.GetFuturesPositionOrders(t.Context(), req) require.ErrorIs(t, err, futures.ErrOrderHistoryTooLarge) req.RespectOrderHistoryLimits = true - result, err := ku.GetFuturesPositionOrders(t.Context(), req) + result, err := e.GetFuturesPositionOrders(t.Context(), req) assert.NoError(t, err) assert.NotNil(t, result) } func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := ku.UpdateOrderExecutionLimits(t.Context(), asset.Binary) + err := e.UpdateOrderExecutionLimits(t.Context(), asset.Binary) require.ErrorIs(t, err, asset.ErrNotSupported) assets := []asset.Item{asset.Spot, asset.Futures, asset.Margin} for x := range assets { - err = ku.UpdateOrderExecutionLimits(t.Context(), assets[x]) + err = e.UpdateOrderExecutionLimits(t.Context(), assets[x]) assert.NoError(t, err) - enabled, err := ku.GetEnabledPairs(assets[x]) + enabled, err := e.GetEnabledPairs(assets[x]) assert.NoError(t, err) for y := range enabled { - lim, err := ku.GetOrderExecutionLimits(assets[x], enabled[y]) + lim, err := e.GetOrderExecutionLimits(assets[x], enabled[y]) assert.NoErrorf(t, err, "%v %s %v", err, enabled[y], assets[x]) assert.NotEmptyf(t, lim, "limit cannot be empty") } @@ -3306,7 +3306,7 @@ func BenchmarkIntervalToString(b *testing.B) { func TestGetOpenInterest(t *testing.T) { t.Parallel() - ku := testInstance(t) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes + ku := testInstance(t) _, err := ku.GetOpenInterest(t.Context(), key.PairAsset{ Base: currency.ETH.Item, Quote: currency.USDT.Item, @@ -3373,11 +3373,11 @@ func TestValidatePlaceOrderParams(t *testing.T) { func TestSpotHFPlaceOrder(t *testing.T) { t.Parallel() - _, err := ku.HFSpotPlaceOrder(t.Context(), &PlaceHFParam{}) + _, err := e.HFSpotPlaceOrder(t.Context(), &PlaceHFParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.HFSpotPlaceOrder(t.Context(), &PlaceHFParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.HFSpotPlaceOrder(t.Context(), &PlaceHFParam{ TimeInForce: "GTT", Symbol: spotTradablePair, OrderType: "limit", @@ -3391,11 +3391,11 @@ func TestSpotHFPlaceOrder(t *testing.T) { func TestSpotPlaceHFOrderTest(t *testing.T) { t.Parallel() - _, err := ku.SpotPlaceHFOrderTest(t.Context(), &PlaceHFParam{}) + _, err := e.SpotPlaceHFOrderTest(t.Context(), &PlaceHFParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SpotPlaceHFOrderTest(t.Context(), &PlaceHFParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SpotPlaceHFOrderTest(t.Context(), &PlaceHFParam{ TimeInForce: "GTT", Symbol: spotTradablePair, OrderType: "limit", @@ -3409,11 +3409,11 @@ func TestSpotPlaceHFOrderTest(t *testing.T) { func TestSyncPlaceHFOrder(t *testing.T) { t.Parallel() - _, err := ku.SyncPlaceHFOrder(t.Context(), &PlaceHFParam{}) + _, err := e.SyncPlaceHFOrder(t.Context(), &PlaceHFParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SyncPlaceHFOrder(t.Context(), &PlaceHFParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SyncPlaceHFOrder(t.Context(), &PlaceHFParam{ TimeInForce: "GTT", Symbol: currency.Pair{Base: currency.ETH, Delimiter: "-", Quote: currency.BTC}, OrderType: "limit", @@ -3427,8 +3427,8 @@ func TestSyncPlaceHFOrder(t *testing.T) { func TestPlaceMultipleOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PlaceMultipleOrders(t.Context(), []PlaceHFParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceMultipleOrders(t.Context(), []PlaceHFParam{ { TimeInForce: "GTT", Symbol: spotTradablePair, @@ -3460,8 +3460,8 @@ func TestPlaceMultipleOrders(t *testing.T) { func TestSyncPlaceMultipleHFOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SyncPlaceMultipleHFOrders(t.Context(), []PlaceHFParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SyncPlaceMultipleHFOrders(t.Context(), []PlaceHFParam{ { TimeInForce: "GTT", Symbol: spotTradablePair, @@ -3493,14 +3493,14 @@ func TestSyncPlaceMultipleHFOrders(t *testing.T) { func TestModifyHFOrder(t *testing.T) { t.Parallel() - _, err := ku.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{}) + _, err := e.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ku.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{OrderID: "1234"}) + _, err = e.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{OrderID: "1234"}) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ModifyHFOrder(t.Context(), &ModifyHFOrderParam{ Symbol: spotTradablePair, ClientOrderID: "4314oiu5345u2y554x", OrderID: "4314oiu5345u2y554x", @@ -3513,215 +3513,215 @@ func TestModifyHFOrder(t *testing.T) { func TestCancelHFOrder(t *testing.T) { t.Parallel() - _, err := ku.CancelHFOrder(t.Context(), "", spotTradablePair.String()) + _, err := e.CancelHFOrder(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.CancelHFOrder(t.Context(), "630625dbd9180300014c8d52", "") + _, err = e.CancelHFOrder(t.Context(), "630625dbd9180300014c8d52", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelHFOrder(t.Context(), "630625dbd9180300014c8d52", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelHFOrder(t.Context(), "630625dbd9180300014c8d52", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestSyncCancelHFOrder(t *testing.T) { t.Parallel() - _, err := ku.SyncCancelHFOrder(t.Context(), "", spotTradablePair.String()) + _, err := e.SyncCancelHFOrder(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.SyncCancelHFOrder(t.Context(), "12312312", "") + _, err = e.SyncCancelHFOrder(t.Context(), "12312312", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SyncCancelHFOrder(t.Context(), "641d67ea162d47000160bfb8", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SyncCancelHFOrder(t.Context(), "641d67ea162d47000160bfb8", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestSyncCancelHFOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.SyncCancelHFOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) + _, err := e.SyncCancelHFOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.SyncCancelHFOrderByClientOrderID(t.Context(), "cliend-order-id", "") + _, err = e.SyncCancelHFOrderByClientOrderID(t.Context(), "cliend-order-id", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SyncCancelHFOrderByClientOrderID(t.Context(), "client-order-id", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SyncCancelHFOrderByClientOrderID(t.Context(), "client-order-id", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelHFOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelHFOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) + _, err := e.CancelHFOrderByClientOrderID(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - _, err = ku.CancelHFOrderByClientOrderID(t.Context(), "cliend-order-id", "") + _, err = e.CancelHFOrderByClientOrderID(t.Context(), "cliend-order-id", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelHFOrderByClientOrderID(t.Context(), "client-order-id", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelHFOrderByClientOrderID(t.Context(), "client-order-id", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelSpecifiedNumberHFOrdersByOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "", spotTradablePair.String(), 10.0) + _, err := e.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "", spotTradablePair.String(), 10.0) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", "", 10.0) + _, err = e.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", "", 10.0) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", spotTradablePair.String(), 0) + _, err = e.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", spotTradablePair.String(), 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", spotTradablePair.String(), 10.0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelSpecifiedNumberHFOrdersByOrderID(t.Context(), "1", spotTradablePair.String(), 10.0) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllHFOrdersBySymbol(t *testing.T) { t.Parallel() - _, err := ku.CancelAllHFOrdersBySymbol(t.Context(), "") + _, err := e.CancelAllHFOrdersBySymbol(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllHFOrdersBySymbol(t.Context(), spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllHFOrdersBySymbol(t.Context(), spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllHFOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllHFOrders(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllHFOrders(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetActiveHFOrders(t *testing.T) { t.Parallel() - _, err := ku.GetActiveHFOrders(t.Context(), "") + _, err := e.GetActiveHFOrders(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.GetActiveHFOrders(t.Context(), "") + _, err = e.GetActiveHFOrders(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetActiveHFOrders(t.Context(), spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetActiveHFOrders(t.Context(), spotTradablePair.String()) assert.NoError(t, err) } func TestGetSymbolsWithActiveHFOrderList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err := ku.GetSymbolsWithActiveHFOrderList(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetSymbolsWithActiveHFOrderList(t.Context()) assert.NoError(t, err) } func TestGetHFCompletedOrderList(t *testing.T) { t.Parallel() - _, err := ku.GetHFCompletedOrderList(t.Context(), "", "sell", "limit", "", time.Time{}, time.Now(), 0) + _, err := e.GetHFCompletedOrderList(t.Context(), "", "sell", "limit", "", time.Time{}, time.Now(), 0) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHFCompletedOrderList(t.Context(), spotTradablePair.String(), "sell", "limit", "", time.Time{}, time.Now(), 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHFCompletedOrderList(t.Context(), spotTradablePair.String(), "sell", "limit", "", time.Time{}, time.Now(), 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetHFOrderDetailsByOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetHFOrderDetailsByOrderID(t.Context(), "", spotTradablePair.String()) + _, err := e.GetHFOrderDetailsByOrderID(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.GetHFOrderDetailsByOrderID(t.Context(), "1234567", "") + _, err = e.GetHFOrderDetailsByOrderID(t.Context(), "1234567", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHFOrderDetailsByOrderID(t.Context(), "1234567", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHFOrderDetailsByOrderID(t.Context(), "1234567", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetHFOrderDetailsByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetHFOrderDetailsByClientOrderID(t.Context(), "", spotTradablePair.String()) + _, err := e.GetHFOrderDetailsByClientOrderID(t.Context(), "", spotTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.GetHFOrderDetailsByClientOrderID(t.Context(), "1234567", "") + _, err = e.GetHFOrderDetailsByClientOrderID(t.Context(), "1234567", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHFOrderDetailsByClientOrderID(t.Context(), "6d539dc614db312", spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHFOrderDetailsByClientOrderID(t.Context(), "6d539dc614db312", spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestAutoCancelHFOrderSetting(t *testing.T) { t.Parallel() - _, err := ku.AutoCancelHFOrderSetting(t.Context(), 0, []string{}) + _, err := e.AutoCancelHFOrderSetting(t.Context(), 0, []string{}) require.ErrorIs(t, err, errTimeoutRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.AutoCancelHFOrderSetting(t.Context(), 450, []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AutoCancelHFOrderSetting(t.Context(), 450, []string{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestAutoCancelHFOrderSettingQuery(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.AutoCancelHFOrderSettingQuery(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.AutoCancelHFOrderSettingQuery(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetHFFilledList(t *testing.T) { t.Parallel() - _, err := ku.GetHFFilledList(t.Context(), "", "", "sell", "market", "", time.Time{}, time.Now(), 0) + _, err := e.GetHFFilledList(t.Context(), "", "", "sell", "market", "", time.Time{}, time.Now(), 0) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetHFFilledList(t.Context(), "", spotTradablePair.String(), "sell", "market", "", time.Time{}, time.Now(), 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHFFilledList(t.Context(), "", spotTradablePair.String(), "sell", "market", "", time.Time{}, time.Now(), 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestPlaceOCOOrder(t *testing.T) { t.Parallel() - _, err := ku.PlaceOCOOrder(t.Context(), &OCOOrderParams{}) + _, err := e.PlaceOCOOrder(t.Context(), &OCOOrderParams{}) require.ErrorIs(t, err, common.ErrNilPointer) arg := &OCOOrderParams{Remark: "oco-new-order"} - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Symbol = spotTradablePair - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "Sell" - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.Price = 1000 - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Size = .1 - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.StopPrice = .1 - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.LimitPrice = .1 - _, err = ku.PlaceOCOOrder(t.Context(), arg) + _, err = e.PlaceOCOOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - cpDetail, err := ku.GetTicker(t.Context(), spotTradablePair.String()) + cpDetail, err := e.GetTicker(t.Context(), spotTradablePair.String()) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.PlaceOCOOrder(t.Context(), &OCOOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceOCOOrder(t.Context(), &OCOOrderParams{ Symbol: spotTradablePair, Side: order.Buy.String(), Price: cpDetail.Price - 3, @@ -3737,112 +3737,112 @@ func TestPlaceOCOOrder(t *testing.T) { func TestCancelOrderByOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelOCOOrderByOrderID(t.Context(), "") + _, err := e.CancelOCOOrderByOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelOCOOrderByOrderID(t.Context(), "6572fdd65723280007deb5e0") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelOCOOrderByOrderID(t.Context(), "6572fdd65723280007deb5e0") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelOCOOrderByClientOrderID(t.Context(), "") + _, err := e.CancelOCOOrderByClientOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrClientOrderIDMustBeSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelOCOOrderByClientOrderID(t.Context(), "6572fdd65723280007deb5e0") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelOCOOrderByClientOrderID(t.Context(), "6572fdd65723280007deb5e0") assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelMultipleOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelOCOMultipleOrders(t.Context(), []string{}, spotTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelOCOMultipleOrders(t.Context(), []string{}, spotTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderInfoByOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetOCOOrderInfoByOrderID(t.Context(), "") + _, err := e.GetOCOOrderInfoByOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetOCOOrderInfoByOrderID(t.Context(), "order-id-here") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOCOOrderInfoByOrderID(t.Context(), "order-id-here") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderInfoByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetOCOOrderInfoByClientOrderID(t.Context(), "") + _, err := e.GetOCOOrderInfoByClientOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetOCOOrderInfoByClientOrderID(t.Context(), "client-order-id-here") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetOCOOrderInfoByClientOrderID(t.Context(), "client-order-id-here") assert.NoError(t, err) } func TestGetOrderDetailsByOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetOCOOrderDetailsByOrderID(t.Context(), "") + _, err := e.GetOCOOrderDetailsByOrderID(t.Context(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetOCOOrderDetailsByOrderID(t.Context(), "order-id-here") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOCOOrderDetailsByOrderID(t.Context(), "order-id-here") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetOCOOrderList(t *testing.T) { t.Parallel() - _, err := ku.GetOCOOrderList(t.Context(), 9, 0, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) + _, err := e.GetOCOOrderList(t.Context(), 9, 0, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) require.ErrorIs(t, err, errPageSizeRequired) - _, err = ku.GetOCOOrderList(t.Context(), 10, 0, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) + _, err = e.GetOCOOrderList(t.Context(), 10, 0, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) require.ErrorIs(t, err, errCurrentPageRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetOCOOrderList(t.Context(), 10, 2, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOCOOrderList(t.Context(), 10, 2, spotTradablePair.String(), time.Time{}, time.Now(), []string{}) assert.NoError(t, err) assert.NotNil(t, result) } func TestSendPlaceMarginHFOrder(t *testing.T) { t.Parallel() - _, err := ku.SendPlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{}, "") + _, err := e.SendPlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{}, "") require.ErrorIs(t, err, common.ErrNilPointer) arg := &PlaceMarginHFOrderParam{PostOnly: true} - _, err = ku.SendPlaceMarginHFOrder(t.Context(), arg, "") + _, err = e.SendPlaceMarginHFOrder(t.Context(), arg, "") require.ErrorIs(t, err, order.ErrClientOrderIDNotSupported) arg.ClientOrderID = "first-order" - _, err = ku.SendPlaceMarginHFOrder(t.Context(), arg, "") + _, err = e.SendPlaceMarginHFOrder(t.Context(), arg, "") require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "Sell" - _, err = ku.SendPlaceMarginHFOrder(t.Context(), arg, "") + _, err = e.SendPlaceMarginHFOrder(t.Context(), arg, "") require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Symbol = marginTradablePair - _, err = ku.SendPlaceMarginHFOrder(t.Context(), arg, "") + _, err = e.SendPlaceMarginHFOrder(t.Context(), arg, "") require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.Price = 1000 - _, err = ku.SendPlaceMarginHFOrder(t.Context(), arg, "") + _, err = e.SendPlaceMarginHFOrder(t.Context(), arg, "") require.ErrorIs(t, err, order.ErrAmountBelowMin) } func TestPlaceMarginHFOrder(t *testing.T) { t.Parallel() - _, err := ku.PlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{}) + _, err := e.PlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.PlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.PlaceMarginHFOrder(t.Context(), &PlaceMarginHFOrderParam{ ClientOrderID: "first-order", Side: "sell", Symbol: marginTradablePair, @@ -3857,11 +3857,11 @@ func TestPlaceMarginHFOrder(t *testing.T) { func TestPlaceMarginHFOrderTest(t *testing.T) { t.Parallel() - _, err := ku.PlaceMarginHFOrderTest(t.Context(), &PlaceMarginHFOrderParam{}) + _, err := e.PlaceMarginHFOrderTest(t.Context(), &PlaceMarginHFOrderParam{}) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.PlaceMarginHFOrderTest(t.Context(), &PlaceMarginHFOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.PlaceMarginHFOrderTest(t.Context(), &PlaceMarginHFOrderParam{ ClientOrderID: "first-order", Side: "sell", Symbol: marginTradablePair, @@ -3876,209 +3876,209 @@ func TestPlaceMarginHFOrderTest(t *testing.T) { func TestCancelMarginHFOrderByOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelMarginHFOrderByOrderID(t.Context(), "", marginTradablePair.String()) + _, err := e.CancelMarginHFOrderByOrderID(t.Context(), "", marginTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.CancelMarginHFOrderByOrderID(t.Context(), "order-id-here", "") + _, err = e.CancelMarginHFOrderByOrderID(t.Context(), "order-id-here", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelMarginHFOrderByOrderID(t.Context(), "order-id-here", marginTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMarginHFOrderByOrderID(t.Context(), "order-id-here", marginTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelMarginHFOrderByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.CancelMarginHFOrderByClientOrderID(t.Context(), "", marginTradablePair.String()) + _, err := e.CancelMarginHFOrderByClientOrderID(t.Context(), "", marginTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.CancelMarginHFOrderByClientOrderID(t.Context(), "order-id-here", "") + _, err = e.CancelMarginHFOrderByClientOrderID(t.Context(), "order-id-here", "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelMarginHFOrderByClientOrderID(t.Context(), "order-id-here", marginTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMarginHFOrderByClientOrderID(t.Context(), "order-id-here", marginTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllMarginHFOrdersBySymbol(t *testing.T) { t.Parallel() - _, err := ku.CancelAllMarginHFOrdersBySymbol(t.Context(), "", "MARGIN_TRADE") + _, err := e.CancelAllMarginHFOrdersBySymbol(t.Context(), "", "MARGIN_TRADE") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "") + _, err = e.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "") require.ErrorIs(t, err, errTradeTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "MARGIN_TRADE") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "MARGIN_TRADE") assert.NoError(t, err) assert.NotNil(t, result) - result, err = ku.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "MARGIN_ISOLATED_TRADE") + result, err = e.CancelAllMarginHFOrdersBySymbol(t.Context(), marginTradablePair.String(), "MARGIN_ISOLATED_TRADE") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetActiveMarginHFOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetActiveMarginHFOrders(t.Context(), marginTradablePair.String(), "MARGIN_TRADE") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetActiveMarginHFOrders(t.Context(), marginTradablePair.String(), "MARGIN_TRADE") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFilledHFMarginOrders(t *testing.T) { t.Parallel() - _, err := ku.GetFilledHFMarginOrders(t.Context(), spotTradablePair.String(), "", "sell", "limit", time.Time{}, time.Now(), 0, 20) + _, err := e.GetFilledHFMarginOrders(t.Context(), spotTradablePair.String(), "", "sell", "limit", time.Time{}, time.Now(), 0, 20) require.ErrorIs(t, err, errTradeTypeMissing) - _, err = ku.GetFilledHFMarginOrders(t.Context(), "", "MARGIN_TRADE", "sell", "limit", time.Time{}, time.Now(), 0, 20) + _, err = e.GetFilledHFMarginOrders(t.Context(), "", "MARGIN_TRADE", "sell", "limit", time.Time{}, time.Now(), 0, 20) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetFilledHFMarginOrders(t.Context(), marginTradablePair.String(), "MARGIN_TRADE", "sell", "limit", time.Time{}, time.Now(), 0, 20) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetFilledHFMarginOrders(t.Context(), marginTradablePair.String(), "MARGIN_TRADE", "sell", "limit", time.Time{}, time.Now(), 0, 20) assert.NoError(t, err) } func TestGetMarginHFOrderDetailByOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetMarginHFOrderDetailByOrderID(t.Context(), "", marginTradablePair.String()) + _, err := e.GetMarginHFOrderDetailByOrderID(t.Context(), "", marginTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetMarginHFOrderDetailByOrderID(t.Context(), "243432432423the-order-id", marginTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetMarginHFOrderDetailByOrderID(t.Context(), "243432432423the-order-id", marginTradablePair.String()) assert.Truef(t, errors.Is(err, order.ErrOrderNotFound) || err == nil, "GetMarginHFOrderDetailByOrderID should not error: %s", err) } func TestGetMarginHFOrderDetailByClientOrderID(t *testing.T) { t.Parallel() - _, err := ku.GetMarginHFOrderDetailByClientOrderID(t.Context(), "", marginTradablePair.String()) + _, err := e.GetMarginHFOrderDetailByClientOrderID(t.Context(), "", marginTradablePair.String()) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetMarginHFOrderDetailByClientOrderID(t.Context(), "the-client-order-id", marginTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMarginHFOrderDetailByClientOrderID(t.Context(), "the-client-order-id", marginTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarginHFTradeFills(t *testing.T) { t.Parallel() - _, err := ku.GetMarginHFTradeFills(t.Context(), "", marginTradablePair.String(), "", "sell", "", time.Time{}, time.Now(), 0, 30) + _, err := e.GetMarginHFTradeFills(t.Context(), "", marginTradablePair.String(), "", "sell", "", time.Time{}, time.Now(), 0, 30) require.ErrorIs(t, err, errTradeTypeMissing) - _, err = ku.GetMarginHFTradeFills(t.Context(), "", "", "MARGIN_TRADE", "sell", "", time.Time{}, time.Now(), 0, 30) + _, err = e.GetMarginHFTradeFills(t.Context(), "", "", "MARGIN_TRADE", "sell", "", time.Time{}, time.Now(), 0, 30) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetMarginHFTradeFills(t.Context(), "12312312", marginTradablePair.String(), "MARGIN_TRADE", "sell", "market", time.Time{}, time.Now(), 0, 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetMarginHFTradeFills(t.Context(), "12312312", marginTradablePair.String(), "MARGIN_TRADE", "sell", "market", time.Time{}, time.Now(), 0, 30) assert.NoError(t, err) } func TestGetLendingCurrencyInformation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetLendingCurrencyInformation(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLendingCurrencyInformation(t.Context(), currency.ETH) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetInterestRate(t *testing.T) { t.Parallel() - _, err := ku.GetInterestRate(t.Context(), currency.EMPTYCODE) + _, err := e.GetInterestRate(t.Context(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetInterestRate(t.Context(), currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInterestRate(t.Context(), currency.ETH) assert.NoError(t, err) assert.NotNil(t, result) } func TestMarginLendingSubscription(t *testing.T) { t.Parallel() - _, err := ku.MarginLendingSubscription(t.Context(), currency.EMPTYCODE, 1, 0.22) + _, err := e.MarginLendingSubscription(t.Context(), currency.EMPTYCODE, 1, 0.22) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.MarginLendingSubscription(t.Context(), currency.ETH, 0, 0.22) + _, err = e.MarginLendingSubscription(t.Context(), currency.ETH, 0, 0.22) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.MarginLendingSubscription(t.Context(), currency.ETH, 1, 0) + _, err = e.MarginLendingSubscription(t.Context(), currency.ETH, 1, 0) require.ErrorIs(t, err, errMissingInterestRate) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.MarginLendingSubscription(t.Context(), currency.ETH, 1, 0.22) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.MarginLendingSubscription(t.Context(), currency.ETH, 1, 0.22) assert.NoError(t, err) assert.NotNil(t, result) } func TestRedemption(t *testing.T) { t.Parallel() - _, err := ku.Redemption(t.Context(), currency.EMPTYCODE, 1, "1245") + _, err := e.Redemption(t.Context(), currency.EMPTYCODE, 1, "1245") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.Redemption(t.Context(), currency.ETH, 0, "1245") + _, err = e.Redemption(t.Context(), currency.ETH, 0, "1245") require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.Redemption(t.Context(), currency.ETH, 1, "") + _, err = e.Redemption(t.Context(), currency.ETH, 1, "") require.ErrorIs(t, err, errMissingPurchaseOrderNumber) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.Redemption(t.Context(), currency.ETH, 1, "1245") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.Redemption(t.Context(), currency.ETH, 1, "1245") assert.NoError(t, err) assert.NotNil(t, result) } func TestModifySubscriptionOrder(t *testing.T) { t.Parallel() - _, err := ku.ModifySubscriptionOrder(t.Context(), currency.EMPTYCODE, "12345", 1.23) + _, err := e.ModifySubscriptionOrder(t.Context(), currency.EMPTYCODE, "12345", 1.23) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.ModifySubscriptionOrder(t.Context(), currency.ETH, "12345", 0) + _, err = e.ModifySubscriptionOrder(t.Context(), currency.ETH, "12345", 0) require.ErrorIs(t, err, errMissingInterestRate) - _, err = ku.ModifySubscriptionOrder(t.Context(), currency.ETH, "", 1.23) + _, err = e.ModifySubscriptionOrder(t.Context(), currency.ETH, "", 1.23) require.ErrorIs(t, err, errMissingPurchaseOrderNumber) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.ModifySubscriptionOrder(t.Context(), currency.ETH, "12345", 1.23) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ModifySubscriptionOrder(t.Context(), currency.ETH, "12345", 1.23) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetRedemptionOrders(t *testing.T) { t.Parallel() - _, err := ku.GetRedemptionOrders(t.Context(), currency.EMPTYCODE, "DONE", "2234", 0, 20) + _, err := e.GetRedemptionOrders(t.Context(), currency.EMPTYCODE, "DONE", "2234", 0, 20) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.GetRedemptionOrders(t.Context(), currency.ETH, "", "", 0, 20) + _, err = e.GetRedemptionOrders(t.Context(), currency.ETH, "", "", 0, 20) require.ErrorIs(t, err, errStatusMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetRedemptionOrders(t.Context(), currency.BTC, "2234", "PENDING", 0, 20) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRedemptionOrders(t.Context(), currency.BTC, "2234", "PENDING", 0, 20) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetSubscriptionOrders(t *testing.T) { t.Parallel() - _, err := ku.GetSubscriptionOrders(t.Context(), currency.EMPTYCODE, "2234", "DONE", 0, 20) + _, err := e.GetSubscriptionOrders(t.Context(), currency.EMPTYCODE, "2234", "DONE", 0, 20) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ku.GetSubscriptionOrders(t.Context(), currency.ETH, "", "", 0, 20) + _, err = e.GetSubscriptionOrders(t.Context(), currency.ETH, "", "", 0, 20) require.ErrorIs(t, err, errStatusMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetSubscriptionOrders(t.Context(), currency.BTC, "2234", "DONE", 0, 20) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubscriptionOrders(t.Context(), currency.BTC, "2234", "DONE", 0, 20) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ku) - for _, a := range ku.GetAssetTypes(false) { - pairs, err := ku.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) assert.NoErrorf(t, err, "cannot get pairs for %s", a) assert.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := ku.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) assert.NoError(t, err) assert.NotEmpty(t, resp) } } // testInstance returns a local Kucoin for isolated testing -func testInstance(tb testing.TB) *Kucoin { +func testInstance(tb testing.TB) *Exchange { tb.Helper() - kucoin := new(Kucoin) + kucoin := new(Exchange) require.NoError(tb, testexch.Setup(kucoin), "Test instance Setup must not error") kucoin.obm = &orderbookManager{ state: make(map[currency.Code]map[currency.Code]map[asset.Item]*update), @@ -4089,193 +4089,193 @@ func testInstance(tb testing.TB) *Kucoin { func TestGetTradingPairActualFees(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetTradingPairActualFees(t.Context(), []string{spotTradablePair.String()}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTradingPairActualFees(t.Context(), []string{spotTradablePair.String()}) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesTradingPairsActualFees(t *testing.T) { t.Parallel() - _, err := ku.GetFuturesTradingPairsActualFees(t.Context(), "") + _, err := e.GetFuturesTradingPairsActualFees(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetFuturesTradingPairsActualFees(t.Context(), futuresTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesTradingPairsActualFees(t.Context(), futuresTradablePair.String()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetPositionHistory(t *testing.T) { t.Parallel() - _, err := ku.GetPositionHistory(t.Context(), futuresTradablePair.String(), time.Now(), time.Now().Add(-time.Hour*5), 0, 10) + _, err := e.GetPositionHistory(t.Context(), futuresTradablePair.String(), time.Now(), time.Now().Add(-time.Hour*5), 0, 10) require.ErrorIs(t, err, common.ErrStartAfterEnd) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetPositionHistory(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPositionHistory(t.Context(), futuresTradablePair.String(), time.Time{}, time.Time{}, 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMaximumOpenPositionSize(t *testing.T) { t.Parallel() - _, err := ku.GetMaximumOpenPositionSize(t.Context(), "", 1, 1) + _, err := e.GetMaximumOpenPositionSize(t.Context(), "", 1, 1) require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - _, err = ku.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 0., 1) + _, err = e.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 0., 1) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ku.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 1, 0) + _, err = e.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 1, 0) require.ErrorIs(t, err, errInvalidLeverage) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 1, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaximumOpenPositionSize(t.Context(), futuresTradablePair.String(), 1, 1) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetLatestTickersForAllContracts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetLatestTickersForAllContracts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLatestTickersForAllContracts(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestSubscribeToEarnFixedIncomeProduct(t *testing.T) { t.Parallel() - _, err := ku.SubscribeToEarnFixedIncomeProduct(t.Context(), "", "MAIN", 12.2) + _, err := e.SubscribeToEarnFixedIncomeProduct(t.Context(), "", "MAIN", 12.2) require.ErrorIs(t, err, errProductIDMissing) - _, err = ku.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "MAIN", 0) + _, err = e.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "MAIN", 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ku.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "", 12.2) + _, err = e.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "", 12.2) require.ErrorIs(t, err, errAccountTypeMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "MAIN", 12.2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SubscribeToEarnFixedIncomeProduct(t.Context(), "1232412", "MAIN", 12.2) assert.NoError(t, err) assert.NotNil(t, result) } func TestRedeemByEarnHoldingID(t *testing.T) { t.Parallel() - _, err := ku.RedeemByEarnHoldingID(t.Context(), "", SpotTradeType, "1", 1) + _, err := e.RedeemByEarnHoldingID(t.Context(), "", SpotTradeType, "1", 1) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ku.RedeemByEarnHoldingID(t.Context(), "123231", "Main", "1", 0) + _, err = e.RedeemByEarnHoldingID(t.Context(), "123231", "Main", "1", 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - result, err := ku.RedeemByEarnHoldingID(t.Context(), "123231", SpotTradeType, "1", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.RedeemByEarnHoldingID(t.Context(), "123231", SpotTradeType, "1", 1) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnRedeemPreviewByHoldingID(t *testing.T) { t.Parallel() - _, err := ku.GetEarnRedeemPreviewByHoldingID(t.Context(), "", "MAIN") + _, err := e.GetEarnRedeemPreviewByHoldingID(t.Context(), "", "MAIN") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnRedeemPreviewByHoldingID(t.Context(), "12345", "MAIN") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnRedeemPreviewByHoldingID(t.Context(), "12345", "MAIN") assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnSavingsProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnSavingsProducts(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnSavingsProducts(t.Context(), currency.EMPTYCODE) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnFixedIncomeCurrentHoldings(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnFixedIncomeCurrentHoldings(t.Context(), "12312", "", currency.EMPTYCODE, 0, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnFixedIncomeCurrentHoldings(t.Context(), "12312", "", currency.EMPTYCODE, 0, 10) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetLimitedTimePromotionProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetLimitedTimePromotionProducts(t.Context(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLimitedTimePromotionProducts(t.Context(), currency.BTC) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnKCSStakingProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnKCSStakingProducts(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnKCSStakingProducts(t.Context(), currency.EMPTYCODE) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnStakingProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnStakingProducts(t.Context(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnStakingProducts(t.Context(), currency.EMPTYCODE) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetEarnETHStakingProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetEarnETHStakingProducts(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnETHStakingProducts(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetInformationOnOffExchangeFundingAndLoans(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetInformationOnOffExchangeFundingAndLoans(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInformationOnOffExchangeFundingAndLoans(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetInformationOnAccountInvolvedInOffExchangeLoans(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetInformationOnAccountInvolvedInOffExchangeLoans(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInformationOnAccountInvolvedInOffExchangeLoans(t.Context()) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetAffilateUserRebateInformation(t *testing.T) { t.Parallel() - _, err := ku.GetAffilateUserRebateInformation(t.Context(), time.Time{}, "1234", 0) + _, err := e.GetAffilateUserRebateInformation(t.Context(), time.Time{}, "1234", 0) require.ErrorIs(t, err, errQueryDateIsRequired) - _, err = ku.GetAffilateUserRebateInformation(t.Context(), time.Now(), "", 0) + _, err = e.GetAffilateUserRebateInformation(t.Context(), time.Now(), "", 0) require.ErrorIs(t, err, errOffsetIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetAffilateUserRebateInformation(t.Context(), time.Now(), "1234", 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAffilateUserRebateInformation(t.Context(), time.Now(), "1234", 0) assert.NoError(t, err) assert.NotNil(t, result) } func TestGetMarginPairsConfigurations(t *testing.T) { t.Parallel() - _, err := ku.GetMarginPairsConfigurations(t.Context(), "") + _, err := e.GetMarginPairsConfigurations(t.Context(), "") require.ErrorIs(t, err, currency.ErrSymbolStringEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - _, err = ku.GetMarginPairsConfigurations(t.Context(), marginTradablePair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err = e.GetMarginPairsConfigurations(t.Context(), marginTradablePair.String()) assert.NoError(t, err) } func TestModifyLeverageMultiplier(t *testing.T) { - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku, canManipulateRealOrders) - err := ku.ModifyLeverageMultiplier(t.Context(), spotTradablePair.String(), 1, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err := e.ModifyLeverageMultiplier(t.Context(), spotTradablePair.String(), 1, true) assert.NoError(t, err) } func TestGetActiveHFOrderSymbols(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ku) - result, err := ku.GetActiveHFOrderSymbols(t.Context(), "MARGIN_TRADE") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetActiveHFOrderSymbols(t.Context(), "MARGIN_TRADE") assert.NoError(t, err) assert.NotNil(t, result) } @@ -4297,7 +4297,7 @@ func TestOrderSideString(t *testing.T) { var err error var sideString string for a := range sideErrInput { - sideString, err = ku.OrderSideString(sideErrInput[a].Side) + sideString, err = e.OrderSideString(sideErrInput[a].Side) require.ErrorIs(t, err, sideErrInput[a].Err) assert.Equal(t, sideString, sideErrInput[a].Result) } @@ -4355,7 +4355,7 @@ func TestAccountToTradeTypeString(t *testing.T) { {AccountType: asset.Futures, MarginMode: "isolated", Result: ""}, } for a := range accountToTradeTypeResults { - result := ku.AccountToTradeTypeString(accountToTradeTypeResults[a].AccountType, accountToTradeTypeResults[a].MarginMode) + result := e.AccountToTradeTypeString(accountToTradeTypeResults[a].AccountType, accountToTradeTypeResults[a].MarginMode) assert.Equal(t, result, accountToTradeTypeResults[a].Result) } } @@ -4375,7 +4375,7 @@ func TestStringToOrderStatus(t *testing.T) { {Input: "something", Result: order.UnknownStatus, HasErr: true}, } for a := range orderStatusResults { - result, err := ku.StringToOrderStatus(orderStatusResults[a].Input) + result, err := e.StringToOrderStatus(orderStatusResults[a].Input) if !orderStatusResults[a].HasErr { assert.NoError(t, err) } @@ -4410,16 +4410,16 @@ func TestGetHistoricalFundingRates(t *testing.T) { StartDate: time.Now().Add(-time.Hour * 24 * 2), EndDate: time.Now(), } - _, err := ku.GetHistoricalFundingRates(t.Context(), r) + _, err := e.GetHistoricalFundingRates(t.Context(), r) require.ErrorIs(t, err, asset.ErrNotSupported) r.Pair = currency.EMPTYPAIR - _, err = ku.GetHistoricalFundingRates(t.Context(), r) + _, err = e.GetHistoricalFundingRates(t.Context(), r) require.ErrorIs(t, err, asset.ErrNotSupported) r.Asset = asset.Futures r.Pair = futuresTradablePair - result, err := ku.GetHistoricalFundingRates(t.Context(), r) + result, err := e.GetHistoricalFundingRates(t.Context(), r) assert.NoError(t, err) assert.NotNil(t, result) } @@ -4427,36 +4427,36 @@ func TestGetHistoricalFundingRates(t *testing.T) { func TestProcessFuturesKline(t *testing.T) { t.Parallel() data := fmt.Sprintf(`{"symbol":%q,"candles":["1714964400","63815.1","63890.8","63928.5","63797.8","17553.0","17553"],"time":1714964823722}`, futuresTradablePair.String()) - err := ku.processFuturesKline([]byte(data), "1hour") + err := e.processFuturesKline([]byte(data), "1hour") assert.NoError(t, err) } func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() withdrawFiatRequest := withdraw.Request{} - _, err := ku.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) assert.ErrorIs(t, common.ErrFunctionNotSupported, err) } func TestWithdrawFiatFunds(t *testing.T) { t.Parallel() - _, err := ku.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) + _, err := e.WithdrawFiatFunds(t.Context(), &withdraw.Request{}) assert.ErrorIs(t, common.ErrFunctionNotSupported, err) } func TestModifyOrder(t *testing.T) { - _, err := ku.ModifyOrder(t.Context(), &order.Modify{}) + _, err := e.ModifyOrder(t.Context(), &order.Modify{}) assert.ErrorIs(t, common.ErrFunctionNotSupported, err) } func TestGetHistoricTrades(t *testing.T) { - _, err := ku.GetHistoricTrades(t.Context(), currency.EMPTYPAIR, asset.Spot, time.Time{}, time.Time{}) + _, err := e.GetHistoricTrades(t.Context(), currency.EMPTYPAIR, asset.Spot, time.Time{}, time.Time{}) assert.ErrorIs(t, common.ErrFunctionNotSupported, err) } func TestCancelBatchOrders(t *testing.T) { - _, err := ku.CancelBatchOrders(t.Context(), nil) + _, err := e.CancelBatchOrders(t.Context(), nil) assert.ErrorIs(t, common.ErrFunctionNotSupported, err) } diff --git a/exchanges/kucoin/kucoin_websocket.go b/exchanges/kucoin/kucoin_websocket.go index ca4a5b7351e..b420cd4845a 100644 --- a/exchanges/kucoin/kucoin_websocket.go +++ b/exchanges/kucoin/kucoin_websocket.go @@ -117,31 +117,31 @@ var defaultSubscriptions = subscription.List{ } // WsConnect creates a new websocket connection. -func (ku *Kucoin) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !ku.Websocket.IsEnabled() || !ku.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } fetchedFuturesOrderbookMutex.Lock() fetchedFuturesOrderbook = map[string]bool{} fetchedFuturesOrderbookMutex.Unlock() var dialer gws.Dialer - dialer.HandshakeTimeout = ku.Config.HTTPTimeout + dialer.HandshakeTimeout = e.Config.HTTPTimeout dialer.Proxy = http.ProxyFromEnvironment var instances *WSInstanceServers - _, err := ku.GetCredentials(ctx) + _, err := e.GetCredentials(ctx) if err != nil { - ku.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } - if ku.Websocket.CanUseAuthenticatedEndpoints() { - instances, err = ku.GetAuthenticatedInstanceServers(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + instances, err = e.GetAuthenticatedInstanceServers(ctx) if err != nil { - ku.Websocket.DataHandler <- err - ku.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.DataHandler <- err + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } if instances == nil { - instances, err = ku.GetInstanceServers(ctx) + instances, err = e.GetInstanceServers(ctx) if err != nil { return err } @@ -149,31 +149,31 @@ func (ku *Kucoin) WsConnect() error { if len(instances.InstanceServers) == 0 { return errors.New("no websocket instance server found") } - ku.Websocket.Conn.SetURL(instances.InstanceServers[0].Endpoint + "?token=" + instances.Token) - err = ku.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + e.Websocket.Conn.SetURL(instances.InstanceServers[0].Endpoint + "?token=" + instances.Token) + err = e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { - return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", ku.Name, err) + return fmt.Errorf("%v - Unable to connect to Websocket. Error: %s", e.Name, err) } - ku.Websocket.Wg.Add(1) - go ku.wsReadData(ctx) - ku.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx) + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ Delay: time.Millisecond * time.Duration(instances.InstanceServers[0].PingTimeout), Message: []byte(`{"type":"ping"}`), MessageType: gws.TextMessage, }) - ku.setupOrderbookManager(ctx) + e.setupOrderbookManager(ctx) return nil } // GetInstanceServers retrieves the server list and temporary public token -func (ku *Kucoin) GetInstanceServers(ctx context.Context) (*WSInstanceServers, error) { +func (e *Exchange) GetInstanceServers(ctx context.Context) (*WSInstanceServers, error) { response := struct { Data WSInstanceServers `json:"data"` Error }{} - return &(response.Data), ku.SendPayload(ctx, request.Unset, func() (*request.Item, error) { - endpointPath, err := ku.API.Endpoints.GetURL(exchange.RestSpot) + return &(response.Data), e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + endpointPath, err := e.API.Endpoints.GetURL(exchange.RestSpot) if err != nil { return nil, err } @@ -181,43 +181,43 @@ func (ku *Kucoin) GetInstanceServers(ctx context.Context) (*WSInstanceServers, e Method: http.MethodPost, Path: endpointPath + publicBullets, Result: &response, - Verbose: ku.Verbose, - HTTPDebugging: ku.HTTPDebugging, - HTTPRecording: ku.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.UnauthenticatedRequest) } // GetAuthenticatedInstanceServers retrieves server instances for authenticated users. -func (ku *Kucoin) GetAuthenticatedInstanceServers(ctx context.Context) (*WSInstanceServers, error) { +func (e *Exchange) GetAuthenticatedInstanceServers(ctx context.Context) (*WSInstanceServers, error) { response := struct { Data *WSInstanceServers `json:"data"` Error }{} - err := ku.SendAuthHTTPRequest(ctx, exchange.RestSpot, spotAuthenticationEPL, http.MethodPost, privateBullets, nil, &response) + err := e.SendAuthHTTPRequest(ctx, exchange.RestSpot, spotAuthenticationEPL, http.MethodPost, privateBullets, nil, &response) if err != nil && strings.Contains(err.Error(), "400003") { - return response.Data, ku.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAuthenticationEPL, http.MethodPost, privateBullets, nil, &response) + return response.Data, e.SendAuthHTTPRequest(ctx, exchange.RestFutures, futuresAuthenticationEPL, http.MethodPost, privateBullets, nil, &response) } return response.Data, err } // wsReadData receives and passes on websocket messages for processing -func (ku *Kucoin) wsReadData(ctx context.Context) { - defer ku.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context) { + defer e.Websocket.Wg.Done() for { - resp := ku.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := ku.wsHandleData(ctx, resp.Raw) + err := e.wsHandleData(ctx, resp.Raw) if err != nil { - ku.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } } // wsHandleData processes a websocket incoming data. -func (ku *Kucoin) wsHandleData(ctx context.Context, respData []byte) error { +func (e *Exchange) wsHandleData(ctx context.Context, respData []byte) error { resp := WsPushData{} if err := json.Unmarshal(respData, &resp); err != nil { return err @@ -226,7 +226,7 @@ func (ku *Kucoin) wsHandleData(ctx context.Context, respData []byte) error { return nil } if resp.ID != "" { - return ku.Websocket.Match.RequireMatchWithData("msgID:"+resp.ID, respData) + return e.Websocket.Match.RequireMatchWithData("msgID:"+resp.ID, respData) } topicInfo := strings.Split(resp.Topic, ":") switch topicInfo[0] { @@ -237,107 +237,107 @@ func (ku *Kucoin) wsHandleData(ctx context.Context, respData []byte) error { } else { instruments = topicInfo[1] } - return ku.processTicker(resp.Data, instruments, topicInfo[0]) + return e.processTicker(resp.Data, instruments, topicInfo[0]) case marketSnapshotChannel: - return ku.processMarketSnapshot(resp.Data, topicInfo[0]) + return e.processMarketSnapshot(resp.Data, topicInfo[0]) case marketOrderbookChannel: - return ku.processOrderbookWithDepth(respData, topicInfo[1], topicInfo[0]) + return e.processOrderbookWithDepth(respData, topicInfo[1], topicInfo[0]) case marketOrderbookDepth5Channel, marketOrderbookDepth50Channel: - return ku.processOrderbook(resp.Data, topicInfo[1], topicInfo[0]) + return e.processOrderbook(resp.Data, topicInfo[1], topicInfo[0]) case marketCandlesChannel: symbolAndInterval := strings.Split(topicInfo[1], currency.UnderscoreDelimiter) if len(symbolAndInterval) != 2 { return errMalformedData } - return ku.processCandlesticks(resp.Data, symbolAndInterval[0], symbolAndInterval[1], topicInfo[0]) + return e.processCandlesticks(resp.Data, symbolAndInterval[0], symbolAndInterval[1], topicInfo[0]) case marketMatchChannel: - return ku.processTradeData(resp.Data, topicInfo[1], topicInfo[0]) + return e.processTradeData(resp.Data, topicInfo[1], topicInfo[0]) case indexPriceIndicatorChannel, markPriceIndicatorChannel: var response WsPriceIndicator - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) case privateSpotTradeOrders: - return ku.processOrderChangeEvent(resp.Data, topicInfo[0]) + return e.processOrderChangeEvent(resp.Data, topicInfo[0]) case accountBalanceChannel: - return ku.processAccountBalanceChange(ctx, resp.Data) + return e.processAccountBalanceChange(ctx, resp.Data) case marginPositionChannel: if resp.Subject == "debt.ratio" { var response WsDebtRatioChange - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) } var response WsPositionStatus - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) case marginLoanChannel: if resp.Subject == "order.done" { var response WsMarginTradeOrderDoneEvent - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) } - return ku.processMarginLendingTradeOrderEvent(resp.Data) + return e.processMarginLendingTradeOrderEvent(resp.Data) case spotMarketAdvancedChannel: - return ku.processStopOrderEvent(resp.Data) + return e.processStopOrderEvent(resp.Data) case futuresTickerChannel: - return ku.processFuturesTickerV2(resp.Data) + return e.processFuturesTickerV2(resp.Data) case futuresExecutionDataChannel: var response WsFuturesExecutionData - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) case futuresOrderbookChannel: - if err := ku.ensureFuturesOrderbookSnapshotLoaded(ctx, topicInfo[1]); err != nil { + if err := e.ensureFuturesOrderbookSnapshotLoaded(ctx, topicInfo[1]); err != nil { return err } - return ku.processFuturesOrderbookLevel2(ctx, resp.Data, topicInfo[1]) + return e.processFuturesOrderbookLevel2(ctx, resp.Data, topicInfo[1]) case futuresOrderbookDepth5Channel, futuresOrderbookDepth50Channel: - if err := ku.ensureFuturesOrderbookSnapshotLoaded(ctx, topicInfo[1]); err != nil { + if err := e.ensureFuturesOrderbookSnapshotLoaded(ctx, topicInfo[1]); err != nil { return err } - return ku.processFuturesOrderbookSnapshot(resp.Data, topicInfo[1]) + return e.processFuturesOrderbookSnapshot(resp.Data, topicInfo[1]) case futuresContractMarketDataChannel: switch resp.Subject { case "mark.index.price": - return ku.processFuturesMarkPriceAndIndexPrice(resp.Data, topicInfo[1]) + return e.processFuturesMarkPriceAndIndexPrice(resp.Data, topicInfo[1]) case "funding.rate": - return ku.processFuturesFundingData(resp.Data, topicInfo[1]) + return e.processFuturesFundingData(resp.Data, topicInfo[1]) } case futuresSystemAnnouncementChannel: - return ku.processFuturesSystemAnnouncement(resp.Data, resp.Subject) + return e.processFuturesSystemAnnouncement(resp.Data, resp.Subject) case futuresTransactionStatisticsTimerEventChannel: - return ku.processFuturesTransactionStatistics(resp.Data, topicInfo[1]) + return e.processFuturesTransactionStatistics(resp.Data, topicInfo[1]) case futuresTradeOrderChannel: - return ku.processFuturesPrivateTradeOrders(resp.Data) + return e.processFuturesPrivateTradeOrders(resp.Data) case futuresStopOrdersLifecycleEventChannel: - return ku.processFuturesStopOrderLifecycleEvent(resp.Data) + return e.processFuturesStopOrderLifecycleEvent(resp.Data) case futuresAccountBalanceEventChannel: switch resp.Subject { case "orderMargin.change": var response WsFuturesOrderMarginEvent - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) case "availableBalance.change": - return ku.processFuturesAccountBalanceEvent(ctx, resp.Data) + return e.processFuturesAccountBalanceEvent(ctx, resp.Data) case "withdrawHold.change": var response WsFuturesWithdrawalAmountAndTransferOutAmountEvent - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) } case futuresPositionChangeEventChannel: switch resp.Subject { case "position.change": if resp.ChannelType == "private" { var response WsFuturesPosition - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) } var response WsFuturesMarkPricePositionChanges - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) case "position.settlement": var response WsFuturesPositionFundingSettlement - return ku.processData(resp.Data, &response) + return e.processData(resp.Data, &response) } case futuresLimitCandles: instrumentInfos := strings.Split(topicInfo[1], "_") if len(instrumentInfos) != 2 { return errors.New("invalid instrument information") } - return ku.processFuturesKline(resp.Data, instrumentInfos[1]) + return e.processFuturesKline(resp.Data, instrumentInfos[1]) default: - ku.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: ku.Name + websocket.UnhandledMessage + string(respData), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respData), } return errors.New("push data not handled") } @@ -345,21 +345,21 @@ func (ku *Kucoin) wsHandleData(ctx context.Context, respData []byte) error { } // processData used to deserialize and forward the data to DataHandler. -func (ku *Kucoin) processData(respData []byte, resp any) error { +func (e *Exchange) processData(respData []byte, resp any) error { if err := json.Unmarshal(respData, &resp); err != nil { return err } - ku.Websocket.DataHandler <- resp + e.Websocket.DataHandler <- resp return nil } // processFuturesAccountBalanceEvent used to process futures account balance change incoming data. -func (ku *Kucoin) processFuturesAccountBalanceEvent(ctx context.Context, respData []byte) error { +func (e *Exchange) processFuturesAccountBalanceEvent(ctx context.Context, respData []byte) error { resp := WsFuturesAvailableBalance{} if err := json.Unmarshal(respData, &resp); err != nil { return err } - creds, err := ku.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -375,19 +375,19 @@ func (ku *Kucoin) processFuturesAccountBalanceEvent(ctx context.Context, respDat }, }, } - ku.Websocket.DataHandler <- changes - return account.ProcessChange(ku.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } // processFuturesStopOrderLifecycleEvent processes futures stop orders lifecycle events. -func (ku *Kucoin) processFuturesStopOrderLifecycleEvent(respData []byte) error { +func (e *Exchange) processFuturesStopOrderLifecycleEvent(respData []byte) error { resp := WsStopOrderLifecycleEvent{} err := json.Unmarshal(respData, &resp) if err != nil { return err } var enabledPairs currency.Pairs - enabledPairs, err = ku.GetEnabledPairs(asset.Futures) + enabledPairs, err = e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -403,11 +403,11 @@ func (ku *Kucoin) processFuturesStopOrderLifecycleEvent(respData []byte) error { if err != nil { return err } - ku.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: resp.OrderPrice, TriggerPrice: resp.StopPrice, Amount: resp.Size, - Exchange: ku.Name, + Exchange: e.Name, OrderID: resp.OrderID, Type: oType, Side: side, @@ -420,7 +420,7 @@ func (ku *Kucoin) processFuturesStopOrderLifecycleEvent(respData []byte) error { } // processFuturesPrivateTradeOrders processes futures private trade orders updates. -func (ku *Kucoin) processFuturesPrivateTradeOrders(respData []byte) error { +func (e *Exchange) processFuturesPrivateTradeOrders(respData []byte) error { resp := WsFuturesTradeOrder{} if err := json.Unmarshal(respData, &resp); err != nil { return err @@ -429,12 +429,12 @@ func (ku *Kucoin) processFuturesPrivateTradeOrders(respData []byte) error { if err != nil { return err } - oStatus, err := ku.StringToOrderStatus(resp.Status) + oStatus, err := e.StringToOrderStatus(resp.Status) if err != nil { return err } var enabledPairs currency.Pairs - enabledPairs, err = ku.GetEnabledPairs(asset.Futures) + enabledPairs, err = e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -446,14 +446,14 @@ func (ku *Kucoin) processFuturesPrivateTradeOrders(respData []byte) error { if err != nil { return err } - ku.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Type: oType, Status: oStatus, Pair: pair, Side: side, Amount: resp.OrderSize, Price: resp.OrderPrice, - Exchange: ku.Name, + Exchange: e.Name, ExecutedAmount: resp.FilledSize, RemainingAmount: resp.RemainSize, ClientOrderID: resp.ClientOid, @@ -465,7 +465,7 @@ func (ku *Kucoin) processFuturesPrivateTradeOrders(respData []byte) error { } // processFuturesTransactionStatistics processes a futures transaction statistics -func (ku *Kucoin) processFuturesTransactionStatistics(respData []byte, instrument string) error { +func (e *Exchange) processFuturesTransactionStatistics(respData []byte, instrument string) error { resp := WsFuturesTransactionStatisticsTimeEvent{} if err := json.Unmarshal(respData, &resp); err != nil { return err @@ -475,47 +475,47 @@ func (ku *Kucoin) processFuturesTransactionStatistics(respData []byte, instrumen } // processFuturesSystemAnnouncement processes a system announcement. -func (ku *Kucoin) processFuturesSystemAnnouncement(respData []byte, subject string) error { +func (e *Exchange) processFuturesSystemAnnouncement(respData []byte, subject string) error { resp := WsFuturesFundingBegin{} if err := json.Unmarshal(respData, &resp); err != nil { return err } resp.Subject = subject - ku.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } // processFuturesFundingData processes a futures account funding data. -func (ku *Kucoin) processFuturesFundingData(respData []byte, instrument string) error { +func (e *Exchange) processFuturesFundingData(respData []byte, instrument string) error { resp := WsFundingRate{} if err := json.Unmarshal(respData, &resp); err != nil { return err } resp.Symbol = instrument - ku.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } // processFuturesMarkPriceAndIndexPrice processes a futures account mark price and index price changes. -func (ku *Kucoin) processFuturesMarkPriceAndIndexPrice(respData []byte, instrument string) error { +func (e *Exchange) processFuturesMarkPriceAndIndexPrice(respData []byte, instrument string) error { resp := WsFuturesMarkPriceAndIndexPrice{} if err := json.Unmarshal(respData, &resp); err != nil { return err } resp.Symbol = instrument - ku.Websocket.DataHandler <- &resp + e.Websocket.DataHandler <- &resp return nil } // ensureFuturesOrderbookSnapshotLoaded makes sure an initial futures orderbook snapshot is loaded -func (ku *Kucoin) ensureFuturesOrderbookSnapshotLoaded(ctx context.Context, symbol string) error { +func (e *Exchange) ensureFuturesOrderbookSnapshotLoaded(ctx context.Context, symbol string) error { fetchedFuturesOrderbookMutex.Lock() defer fetchedFuturesOrderbookMutex.Unlock() if fetchedFuturesOrderbook[symbol] { return nil } fetchedFuturesOrderbook[symbol] = true - enabledPairs, err := ku.GetEnabledPairs(asset.Futures) + enabledPairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -523,21 +523,21 @@ func (ku *Kucoin) ensureFuturesOrderbookSnapshotLoaded(ctx context.Context, symb if err != nil { return err } - orderbooks, err := ku.UpdateOrderbook(ctx, cp, asset.Futures) + orderbooks, err := e.UpdateOrderbook(ctx, cp, asset.Futures) if err != nil { return err } - return ku.Websocket.Orderbook.LoadSnapshot(orderbooks) + return e.Websocket.Orderbook.LoadSnapshot(orderbooks) } // processFuturesOrderbookSnapshot processes a futures account orderbook websocket update. -func (ku *Kucoin) processFuturesOrderbookSnapshot(respData []byte, instrument string) error { +func (e *Exchange) processFuturesOrderbookSnapshot(respData []byte, instrument string) error { response := WsOrderbookLevel5Response{} if err := json.Unmarshal(respData, &response); err != nil { return err } resp := response.ExtractOrderbookItems() - enabledPairs, err := ku.GetEnabledPairs(asset.Futures) + enabledPairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -545,7 +545,7 @@ func (ku *Kucoin) processFuturesOrderbookSnapshot(respData []byte, instrument st if err != nil { return err } - return ku.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ UpdateID: resp.Sequence, UpdateTime: resp.Timestamp.Time(), Asset: asset.Futures, @@ -557,16 +557,16 @@ func (ku *Kucoin) processFuturesOrderbookSnapshot(respData []byte, instrument st } // ProcessFuturesOrderbookLevel2 processes a V2 futures account orderbook data. -func (ku *Kucoin) processFuturesOrderbookLevel2(ctx context.Context, respData []byte, instrument string) error { +func (e *Exchange) processFuturesOrderbookLevel2(ctx context.Context, respData []byte, instrument string) error { resp := WsFuturesOrderbookInfo{} if err := json.Unmarshal(respData, &resp); err != nil { return err } - detail, err := ku.GetFuturesPartOrderbook100(ctx, instrument) + detail, err := e.GetFuturesPartOrderbook100(ctx, instrument) if err != nil { return err } - enabledPairs, err := ku.GetEnabledPairs(asset.Futures) + enabledPairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -581,16 +581,16 @@ func (ku *Kucoin) processFuturesOrderbookLevel2(ctx context.Context, respData [] Asks: detail.Asks, Bids: detail.Bids, } - return ku.Websocket.Orderbook.Update(&base) + return e.Websocket.Orderbook.Update(&base) } // processFuturesTickerV2 processes a futures account ticker data. -func (ku *Kucoin) processFuturesTickerV2(respData []byte) error { +func (e *Exchange) processFuturesTickerV2(respData []byte) error { resp := WsFuturesTicker{} if err := json.Unmarshal(respData, &resp); err != nil { return err } - enabledPairs, err := ku.GetEnabledPairs(asset.Futures) + enabledPairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -598,12 +598,12 @@ func (ku *Kucoin) processFuturesTickerV2(respData []byte) error { if err != nil { return err } - ku.Websocket.DataHandler <- &ticker.Price{ + e.Websocket.DataHandler <- &ticker.Price{ AssetType: asset.Futures, Last: resp.FilledPrice.Float64(), Volume: resp.FilledSize.Float64(), LastUpdated: resp.FilledTime.Time(), - ExchangeName: ku.Name, + ExchangeName: e.Name, Pair: pair, Ask: resp.BestAskPrice.Float64(), Bid: resp.BestBidPrice.Float64(), @@ -614,7 +614,7 @@ func (ku *Kucoin) processFuturesTickerV2(respData []byte) error { } // processFuturesKline represents a futures instrument kline data update. -func (ku *Kucoin) processFuturesKline(respData []byte, intervalStr string) error { +func (e *Exchange) processFuturesKline(respData []byte, intervalStr string) error { resp := WsFuturesKline{} err := json.Unmarshal(respData, &resp) if err != nil { @@ -625,10 +625,10 @@ func (ku *Kucoin) processFuturesKline(respData []byte, intervalStr string) error if err != nil { return err } - ku.Websocket.DataHandler <- &websocket.KlineData{ + e.Websocket.DataHandler <- &websocket.KlineData{ Timestamp: resp.Time.Time(), AssetType: asset.Futures, - Exchange: ku.Name, + Exchange: e.Name, StartTime: time.Unix(resp.Candles[0].Int64(), 0), Interval: intervalStr, OpenPrice: resp.Candles[1].Float64(), @@ -642,7 +642,7 @@ func (ku *Kucoin) processFuturesKline(respData []byte, intervalStr string) error } // processStopOrderEvent represents a stop order update event. -func (ku *Kucoin) processStopOrderEvent(respData []byte) error { +func (e *Exchange) processStopOrderEvent(respData []byte) error { resp := WsStopOrder{} err := json.Unmarshal(respData, &resp) if err != nil { @@ -661,11 +661,11 @@ func (ku *Kucoin) processStopOrderEvent(respData []byte) error { if err != nil { return err } - ku.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: resp.OrderPrice, TriggerPrice: resp.StopPrice, Amount: resp.Size, - Exchange: ku.Name, + Exchange: e.Name, OrderID: resp.OrderID, Type: oType, Side: side, @@ -678,23 +678,23 @@ func (ku *Kucoin) processStopOrderEvent(respData []byte) error { } // processMarginLendingTradeOrderEvent represents a margin lending trade order event. -func (ku *Kucoin) processMarginLendingTradeOrderEvent(respData []byte) error { +func (e *Exchange) processMarginLendingTradeOrderEvent(respData []byte) error { resp := WsMarginTradeOrderEntersEvent{} if err := json.Unmarshal(respData, &resp); err != nil { return err } - ku.Websocket.DataHandler <- resp + e.Websocket.DataHandler <- resp return nil } // processAccountBalanceChange processes an account balance change -func (ku *Kucoin) processAccountBalanceChange(ctx context.Context, respData []byte) error { +func (e *Exchange) processAccountBalanceChange(ctx context.Context, respData []byte) error { response := WsAccountBalance{} err := json.Unmarshal(respData, &response) if err != nil { return err } - creds, err := ku.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -710,12 +710,12 @@ func (ku *Kucoin) processAccountBalanceChange(ctx context.Context, respData []by }, }, } - ku.Websocket.DataHandler <- changes - return account.ProcessChange(ku.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } // processOrderChangeEvent processes order update events. -func (ku *Kucoin) processOrderChangeEvent(respData []byte, topic string) error { +func (e *Exchange) processOrderChangeEvent(respData []byte, topic string) error { response := WsTradeOrder{} err := json.Unmarshal(respData, &response) if err != nil { @@ -725,7 +725,7 @@ func (ku *Kucoin) processOrderChangeEvent(respData []byte, topic string) error { if err != nil { return err } - oStatus, err := ku.StringToOrderStatus(response.Status) + oStatus, err := e.StringToOrderStatus(response.Status) if err != nil { return err } @@ -738,17 +738,17 @@ func (ku *Kucoin) processOrderChangeEvent(respData []byte, topic string) error { return err } // TODO: should amend this function as we need to know the order asset type when we call it - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { - ku.Websocket.DataHandler <- &order.Detail{ + e.Websocket.DataHandler <- &order.Detail{ Price: response.Price, Amount: response.Size, ExecutedAmount: response.FilledSize, RemainingAmount: response.RemainSize, - Exchange: ku.Name, + Exchange: e.Name, OrderID: response.OrderID, ClientOrderID: response.ClientOid, Type: oType, @@ -764,15 +764,15 @@ func (ku *Kucoin) processOrderChangeEvent(respData []byte, topic string) error { } // processTradeData processes a websocket trade data and instruments. -func (ku *Kucoin) processTradeData(respData []byte, instrument, topic string) error { +func (e *Exchange) processTradeData(respData []byte, instrument, topic string) error { response := WsTrade{} err := json.Unmarshal(respData, &response) if err != nil { return err } - saveTradeData := ku.IsSaveTradeDataEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() if !saveTradeData && - !ku.IsTradeFeedEnabled() { + !e.IsTradeFeedEnabled() { return nil } pair, err := currency.NewPairFromString(instrument) @@ -783,18 +783,18 @@ func (ku *Kucoin) processTradeData(respData []byte, instrument, topic string) er if err != nil { return err } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { - err = ku.Websocket.Trade.Update(saveTradeData, trade.Data{ + err = e.Websocket.Trade.Update(saveTradeData, trade.Data{ CurrencyPair: pair, Timestamp: response.Time.Time(), Price: response.Price, Amount: response.Size, Side: side, - Exchange: ku.Name, + Exchange: e.Name, TID: response.TradeID, AssetType: assets[x], }) @@ -806,7 +806,7 @@ func (ku *Kucoin) processTradeData(respData []byte, instrument, topic string) er } // processTicker processes a ticker data for an instrument. -func (ku *Kucoin) processTicker(respData []byte, instrument, topic string) error { +func (e *Exchange) processTicker(respData []byte, instrument, topic string) error { response := WsTicker{} err := json.Unmarshal(respData, &response) if err != nil { @@ -816,19 +816,19 @@ func (ku *Kucoin) processTicker(respData []byte, instrument, topic string) error if err != nil { return err } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { - if !ku.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { + if !e.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { continue } - ku.Websocket.DataHandler <- &ticker.Price{ + e.Websocket.DataHandler <- &ticker.Price{ AssetType: assets[x], Last: response.Price, LastUpdated: response.Timestamp.Time(), - ExchangeName: ku.Name, + ExchangeName: e.Name, Pair: pair, Ask: response.BestAsk, Bid: response.BestBid, @@ -841,7 +841,7 @@ func (ku *Kucoin) processTicker(respData []byte, instrument, topic string) error } // processCandlesticks processes a candlestick data for an instrument with a particular interval -func (ku *Kucoin) processCandlesticks(respData []byte, instrument, intervalString, topic string) error { +func (e *Exchange) processCandlesticks(respData []byte, instrument, intervalString, topic string) error { pair, err := currency.NewPairFromString(instrument) if err != nil { return err @@ -850,19 +850,19 @@ func (ku *Kucoin) processCandlesticks(respData []byte, instrument, intervalStrin if err := json.Unmarshal(respData, &resp); err != nil { return err } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { - if !ku.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { + if !e.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { continue } - ku.Websocket.DataHandler <- &websocket.KlineData{ + e.Websocket.DataHandler <- &websocket.KlineData{ Timestamp: resp.Time.Time(), Pair: pair, AssetType: assets[x], - Exchange: ku.Name, + Exchange: e.Name, StartTime: resp.Candles.StartTime.Time(), Interval: intervalString, OpenPrice: resp.Candles.OpenPrice.Float64(), @@ -876,7 +876,7 @@ func (ku *Kucoin) processCandlesticks(respData []byte, instrument, intervalStrin } // processOrderbookWithDepth processes order book data with a specified depth for a particular symbol. -func (ku *Kucoin) processOrderbookWithDepth(respData []byte, instrument, topic string) error { +func (e *Exchange) processOrderbookWithDepth(respData []byte, instrument, topic string) error { pair, err := currency.NewPairFromString(instrument) if err != nil { return err @@ -888,18 +888,18 @@ func (ku *Kucoin) processOrderbookWithDepth(respData []byte, instrument, topic s if err != nil { return err } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { var init bool - init, err = ku.updateLocalBuffer(result.Result, assets[x]) + init, err = e.updateLocalBuffer(result.Result, assets[x]) if err != nil { if init { return nil } - return fmt.Errorf("%v - UpdateLocalCache for asset type: %v error: %s", ku.Name, assets[x], err) + return fmt.Errorf("%v - UpdateLocalCache for asset type: %v error: %s", e.Name, assets[x], err) } } return nil @@ -907,13 +907,13 @@ func (ku *Kucoin) processOrderbookWithDepth(respData []byte, instrument, topic s // updateLocalBuffer updates orderbook buffer and checks status if the book is Initial Sync being via the REST // protocol. -func (ku *Kucoin) updateLocalBuffer(wsdp *WsOrderbook, assetType asset.Item) (bool, error) { - enabledPairs, err := ku.GetEnabledPairs(assetType) +func (e *Exchange) updateLocalBuffer(wsdp *WsOrderbook, assetType asset.Item) (bool, error) { + enabledPairs, err := e.GetEnabledPairs(assetType) if err != nil { return false, err } - format, err := ku.GetPairFormat(assetType, true) + format, err := e.GetPairFormat(assetType, true) if err != nil { return false, err } @@ -922,25 +922,25 @@ func (ku *Kucoin) updateLocalBuffer(wsdp *WsOrderbook, assetType asset.Item) (bo if err != nil { return false, err } - err = ku.obm.StageWsUpdate(wsdp, currencyPair, assetType) + err = e.obm.StageWsUpdate(wsdp, currencyPair, assetType) if err != nil { - init, err2 := ku.obm.CheckIsInitialSync(currencyPair, assetType) + init, err2 := e.obm.CheckIsInitialSync(currencyPair, assetType) if err2 != nil { return false, err2 } return init, err } - err = ku.applyBufferUpdate(currencyPair, assetType) + err = e.applyBufferUpdate(currencyPair, assetType) if err != nil { - ku.invalidateAndCleanupOrderbook(currencyPair, assetType) + e.invalidateAndCleanupOrderbook(currencyPair, assetType) } return false, err } // processOrderbook processes orderbook data for a specific symbol. -func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error { +func (e *Exchange) processOrderbook(respData []byte, symbol, topic string) error { var response Level2Depth5Or20 err := json.Unmarshal(respData, &response) if err != nil { @@ -964,7 +964,7 @@ func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error bids[x].Amount = response.Bids[x][1].Float64() } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } @@ -974,8 +974,8 @@ func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error lastUpdatedTime = time.Now() } for x := range assets { - err = ku.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ - Exchange: ku.Name, + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + Exchange: e.Name, Asks: asks, Bids: bids, Pair: pair, @@ -990,7 +990,7 @@ func (ku *Kucoin) processOrderbook(respData []byte, symbol, topic string) error } // processMarketSnapshot processes a price ticker information for a symbol. -func (ku *Kucoin) processMarketSnapshot(respData []byte, topic string) error { +func (e *Exchange) processMarketSnapshot(respData []byte, topic string) error { response := WsSnapshot{} err := json.Unmarshal(respData, &response) if err != nil { @@ -1000,16 +1000,16 @@ func (ku *Kucoin) processMarketSnapshot(respData []byte, topic string) error { if err != nil { return err } - assets, err := ku.CalculateAssets(topic, pair) + assets, err := e.CalculateAssets(topic, pair) if err != nil { return err } for x := range assets { - if !ku.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { + if !e.AssetWebsocketSupport.IsAssetWebsocketSupported(assets[x]) { continue } - ku.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: ku.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, AssetType: assets[x], Last: response.Data.LastTradedPrice, Pair: pair, @@ -1026,21 +1026,21 @@ func (ku *Kucoin) processMarketSnapshot(respData []byte, topic string) error { } // Subscribe sends a websocket message to receive data from the channel -func (ku *Kucoin) Subscribe(subscriptions subscription.List) error { +func (e *Exchange) Subscribe(subscriptions subscription.List) error { ctx := context.TODO() - return ku.manageSubscriptions(ctx, subscriptions, "subscribe") + return e.manageSubscriptions(ctx, subscriptions, "subscribe") } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (ku *Kucoin) Unsubscribe(subscriptions subscription.List) error { +func (e *Exchange) Unsubscribe(subscriptions subscription.List) error { ctx := context.TODO() - return ku.manageSubscriptions(ctx, subscriptions, "unsubscribe") + return e.manageSubscriptions(ctx, subscriptions, "unsubscribe") } -func (ku *Kucoin) manageSubscriptions(ctx context.Context, subs subscription.List, operation string) error { +func (e *Exchange) manageSubscriptions(ctx context.Context, subs subscription.List, operation string) error { var errs error for _, s := range subs { - msgID := strconv.FormatInt(ku.Websocket.Conn.GenerateMessageID(false), 10) + msgID := strconv.FormatInt(e.Websocket.Conn.GenerateMessageID(false), 10) req := WsSubscriptionInput{ ID: msgID, Type: operation, @@ -1048,7 +1048,7 @@ func (ku *Kucoin) manageSubscriptions(ctx context.Context, subs subscription.Lis PrivateChannel: s.Authenticated, Response: true, } - if respRaw, err := ku.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "msgID:"+msgID, req); err != nil { + if respRaw, err := e.Websocket.Conn.SendMessageReturnResponse(ctx, request.Unset, "msgID:"+msgID, req); err != nil { errs = common.AppendError(errs, err) } else { rType, err := jsonparser.GetUnsafeString(respRaw, "type") @@ -1066,11 +1066,11 @@ func (ku *Kucoin) manageSubscriptions(ctx context.Context, subs subscription.Lis errs = common.AppendError(errs, fmt.Errorf("%w: %s from %s", errInvalidMsgType, rType, respRaw)) default: if operation == "unsubscribe" { - err = ku.Websocket.RemoveSubscriptions(ku.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } else { - err = ku.Websocket.AddSuccessfulSubscriptions(ku.Websocket.Conn, s) - if ku.Verbose { - log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s", ku.Name, s.Channel) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s Subscribed to Channel: %s", e.Name, s.Channel) } } if err != nil { @@ -1083,16 +1083,16 @@ func (ku *Kucoin) manageSubscriptions(ctx context.Context, subs subscription.Lis } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (ku *Kucoin) generateSubscriptions() (subscription.List, error) { - return ku.Features.Subscriptions.ExpandTemplates(ku) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (ku *Kucoin) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl"). Funcs(template.FuncMap{ "channelName": channelName, - "mergeMarginPairs": ku.mergeMarginPairs, + "mergeMarginPairs": e.mergeMarginPairs, "isCurrencyChannel": isCurrencyChannel, "isSymbolChannel": isSymbolChannel, "channelInterval": channelInterval, @@ -1128,18 +1128,18 @@ type job struct { } // setupOrderbookManager sets up the orderbook manager for websocket orderbook data handling. -func (ku *Kucoin) setupOrderbookManager(ctx context.Context) { +func (e *Exchange) setupOrderbookManager(ctx context.Context) { locker.Lock() defer locker.Unlock() - if ku.obm == nil { - ku.obm = &orderbookManager{ + if e.obm == nil { + e.obm = &orderbookManager{ state: make(map[currency.Code]map[currency.Code]map[asset.Item]*update), jobs: make(chan job, maxWSOrderbookJobs), } } else { // Change state on reconnect for initial sync. - ku.obm.Mutex.Lock() - for _, m1 := range ku.obm.state { + e.obm.Mutex.Lock() + for _, m1 := range e.obm.state { for _, m2 := range m1 { for _, idk := range m2 { idk.initialSync = true @@ -1148,16 +1148,16 @@ func (ku *Kucoin) setupOrderbookManager(ctx context.Context) { } } } - ku.obm.Mutex.Unlock() + e.obm.Mutex.Unlock() } for range maxWSOrderbookWorkers { // 10 workers for synchronising book - ku.SynchroniseWebsocketOrderbook(ctx) + e.SynchroniseWebsocketOrderbook(ctx) } } // processOrderbookUpdate processes the websocket orderbook update -func (ku *Kucoin) processOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WsOrderbook) error { +func (e *Exchange) processOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WsOrderbook) error { updateBid := make([]orderbook.Level, len(ws.Changes.Bids)) for i := range ws.Changes.Bids { var sequence int64 @@ -1175,7 +1175,7 @@ func (ku *Kucoin) processOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WsO updateAsk[i] = orderbook.Level{Price: ws.Changes.Asks[i][0].Float64(), Amount: ws.Changes.Asks[i][1].Float64(), ID: sequence} } - return ku.Websocket.Orderbook.Update(&orderbook.Update{ + return e.Websocket.Orderbook.Update(&orderbook.Update{ Bids: updateBid, Asks: updateAsk, Pair: cp, @@ -1188,8 +1188,8 @@ func (ku *Kucoin) processOrderbookUpdate(cp currency.Pair, a asset.Item, ws *WsO // applyBufferUpdate applies the buffer to the orderbook or initiates a new // orderbook sync by the REST protocol which is off handed to go routine. -func (ku *Kucoin) applyBufferUpdate(pair currency.Pair, assetType asset.Item) error { - fetching, needsFetching, err := ku.obm.HandleFetchingBook(pair, assetType) +func (e *Exchange) applyBufferUpdate(pair currency.Pair, assetType asset.Item) error { + fetching, needsFetching, err := e.obm.HandleFetchingBook(pair, assetType) if err != nil { return err } @@ -1197,30 +1197,30 @@ func (ku *Kucoin) applyBufferUpdate(pair currency.Pair, assetType asset.Item) er return nil } if needsFetching { - if ku.Verbose { - log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", ku.Name) + if e.Verbose { + log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", e.Name) } - return ku.obm.FetchBookViaREST(pair, assetType) + return e.obm.FetchBookViaREST(pair, assetType) } - recent, err := ku.Websocket.Orderbook.GetOrderbook(pair, assetType) + recent, err := e.Websocket.Orderbook.GetOrderbook(pair, assetType) if err != nil { log.Errorf( log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", - ku.Name, + e.Name, err) } if recent != nil { - err = ku.obm.checkAndProcessOrderbookUpdate(ku.processOrderbookUpdate, pair, assetType, recent) + err = e.obm.checkAndProcessOrderbookUpdate(e.processOrderbookUpdate, pair, assetType, recent) if err != nil { log.Errorf( log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", - ku.Name, + e.Name, err) - err = ku.obm.setNeedsFetchingBook(pair, assetType) + err = e.obm.setNeedsFetchingBook(pair, assetType) if err != nil { return err } @@ -1246,26 +1246,26 @@ func (o *orderbookManager) setNeedsFetchingBook(pair currency.Pair, assetType as // SynchroniseWebsocketOrderbook synchronises full orderbook for currency pair // asset -func (ku *Kucoin) SynchroniseWebsocketOrderbook(ctx context.Context) { - ku.Websocket.Wg.Add(1) +func (e *Exchange) SynchroniseWebsocketOrderbook(ctx context.Context) { + e.Websocket.Wg.Add(1) go func() { - defer ku.Websocket.Wg.Done() + defer e.Websocket.Wg.Done() for { select { - case <-ku.Websocket.ShutdownC: + case <-e.Websocket.ShutdownC: for { select { - case <-ku.obm.jobs: + case <-e.obm.jobs: default: return } } - case j := <-ku.obm.jobs: - err := ku.processJob(ctx, j.Pair, j.AssetType) + case j := <-e.obm.jobs: + err := e.processJob(ctx, j.Pair, j.AssetType) if err != nil { log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", - ku.Name, err) + e.Name, err) } } } @@ -1273,28 +1273,28 @@ func (ku *Kucoin) SynchroniseWebsocketOrderbook(ctx context.Context) { } // SeedLocalCache seeds depth data -func (ku *Kucoin) SeedLocalCache(ctx context.Context, p currency.Pair, assetType asset.Item) error { +func (e *Exchange) SeedLocalCache(ctx context.Context, p currency.Pair, assetType asset.Item) error { var ob *Orderbook var err error - ob, err = ku.GetPartOrderbook100(ctx, p.String()) + ob, err = e.GetPartOrderbook100(ctx, p.String()) if err != nil { return err } if ob.Sequence <= 0 { return fmt.Errorf("%w p", errMissingOrderbookSequence) } - return ku.SeedLocalCacheWithBook(p, ob, assetType) + return e.SeedLocalCacheWithBook(p, ob, assetType) } // SeedLocalCacheWithBook seeds the local orderbook cache -func (ku *Kucoin) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *Orderbook, assetType asset.Item) error { +func (e *Exchange) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *Orderbook, assetType asset.Item) error { newOrderBook := orderbook.Book{ Pair: p, Asset: assetType, - Exchange: ku.Name, + Exchange: e.Name, LastUpdated: time.Now(), LastUpdateID: orderbookNew.Sequence, - ValidateOrderbook: ku.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Bids: make(orderbook.Levels, len(orderbookNew.Bids)), Asks: make(orderbook.Levels, len(orderbookNew.Asks)), } @@ -1310,14 +1310,14 @@ func (ku *Kucoin) SeedLocalCacheWithBook(p currency.Pair, orderbookNew *Orderboo Price: orderbookNew.Asks[i].Price, } } - return ku.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + return e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) } // processJob fetches and processes orderbook updates -func (ku *Kucoin) processJob(ctx context.Context, p currency.Pair, assetType asset.Item) error { - err := ku.SeedLocalCache(ctx, p, assetType) +func (e *Exchange) processJob(ctx context.Context, p currency.Pair, assetType asset.Item) error { + err := e.SeedLocalCache(ctx, p, assetType) if err != nil { - err = ku.obm.StopFetchingBook(p, assetType) + err = e.obm.StopFetchingBook(p, assetType) if err != nil { return err } @@ -1325,28 +1325,28 @@ func (ku *Kucoin) processJob(ctx context.Context, p currency.Pair, assetType ass p, assetType, err) } - err = ku.obm.StopFetchingBook(p, assetType) + err = e.obm.StopFetchingBook(p, assetType) if err != nil { return err } // Immediately apply the buffer updates so we don't wait for a // new update to initiate this. - err = ku.applyBufferUpdate(p, assetType) + err = e.applyBufferUpdate(p, assetType) if err != nil { - ku.invalidateAndCleanupOrderbook(p, assetType) + e.invalidateAndCleanupOrderbook(p, assetType) return err } return nil } // invalidateAndCleanupOrderbook invalidates orderbook and cleans local cache -func (ku *Kucoin) invalidateAndCleanupOrderbook(p currency.Pair, assetType asset.Item) { - if err := ku.Websocket.Orderbook.InvalidateOrderbook(p, assetType); err != nil { - log.Errorf(log.WebsocketMgr, "%s invalidate websocket error: %v", ku.Name, err) +func (e *Exchange) invalidateAndCleanupOrderbook(p currency.Pair, assetType asset.Item) { + if err := e.Websocket.Orderbook.InvalidateOrderbook(p, assetType); err != nil { + log.Errorf(log.WebsocketMgr, "%s invalidate websocket error: %v", e.Name, err) } - if err := ku.obm.Cleanup(p, assetType); err != nil { - log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", ku.Name, err) + if err := e.obm.Cleanup(p, assetType); err != nil { + log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", e.Name, err) } } @@ -1604,10 +1604,10 @@ func (o *orderbookManager) StopNeedsFetchingBook(pair currency.Pair, assetType a } // CalculateAssets returns the available asset types for a currency pair -func (ku *Kucoin) CalculateAssets(topic string, cp currency.Pair) ([]asset.Item, error) { +func (e *Exchange) CalculateAssets(topic string, cp currency.Pair) ([]asset.Item, error) { switch { case cp.Quote.Equal(currency.USDTM), strings.HasPrefix(topic, "/contract"): - if err := ku.CurrencyPairs.IsAssetEnabled(asset.Futures); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(asset.Futures); err != nil { if !errors.Is(err, asset.ErrNotSupported) { return nil, err } @@ -1615,7 +1615,7 @@ func (ku *Kucoin) CalculateAssets(topic string, cp currency.Pair) ([]asset.Item, } return []asset.Item{asset.Futures}, nil case strings.HasPrefix(topic, "/margin"), strings.HasPrefix(topic, "/index"): - if err := ku.CurrencyPairs.IsAssetEnabled(asset.Margin); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(asset.Margin); err != nil { if !errors.Is(err, asset.ErrNotSupported) { return nil, err } @@ -1624,14 +1624,14 @@ func (ku *Kucoin) CalculateAssets(topic string, cp currency.Pair) ([]asset.Item, return []asset.Item{asset.Margin}, nil default: resp := make([]asset.Item, 0, 2) - spotEnabled, err := ku.IsPairEnabled(cp, asset.Spot) + spotEnabled, err := e.IsPairEnabled(cp, asset.Spot) if err != nil && !errors.Is(err, currency.ErrCurrencyNotFound) { return nil, err } if spotEnabled { resp = append(resp, asset.Spot) } - marginEnabled, err := ku.IsPairEnabled(cp, asset.Margin) + marginEnabled, err := e.IsPairEnabled(cp, asset.Margin) if err != nil && !errors.Is(err, currency.ErrCurrencyNotFound) { return nil, err } @@ -1644,9 +1644,9 @@ func (ku *Kucoin) CalculateAssets(topic string, cp currency.Pair) ([]asset.Item, // checkSubscriptions looks for any backwards incompatibilities with missing assets // This should be unnecessary and removable by 2025 -func (ku *Kucoin) checkSubscriptions() { +func (e *Exchange) checkSubscriptions() { upgraded := false - for _, s := range ku.Config.Features.Subscriptions { + for _, s := range e.Config.Features.Subscriptions { if s.Asset != asset.Empty { continue } @@ -1658,7 +1658,7 @@ func (ku *Kucoin) checkSubscriptions() { case subscription.AllTradesChannel: for _, d := range defaultSubscriptions { if d.Channel == s.Channel { - ku.Config.Features.Subscriptions = append(ku.Config.Features.Subscriptions, d) + e.Config.Features.Subscriptions = append(e.Config.Features.Subscriptions, d) } } case futuresTradeOrderChannel, futuresStopOrdersLifecycleEventChannel, futuresAccountBalanceEventChannel: @@ -1667,7 +1667,7 @@ func (ku *Kucoin) checkSubscriptions() { s.Asset = asset.Margin } } - ku.Config.Features.Subscriptions = slices.DeleteFunc(ku.Config.Features.Subscriptions, func(s *subscription.Subscription) bool { + e.Config.Features.Subscriptions = slices.DeleteFunc(e.Config.Features.Subscriptions, func(s *subscription.Subscription) bool { switch s.Channel { case "/contractMarket/level2Depth50", // Replaced by subsctiption.Orderbook for asset.All "/contractMarket/tickerV2", // Replaced by subscription.Ticker for asset.All @@ -1679,7 +1679,7 @@ func (ku *Kucoin) checkSubscriptions() { return false }) if upgraded { - ku.Features.Subscriptions = ku.Config.Features.Subscriptions.Enabled() + e.Features.Subscriptions = e.Config.Features.Subscriptions.Enabled() } } @@ -1700,7 +1700,7 @@ func channelName(s *subscription.Subscription, a asset.Item) string { // mergeMarginPairs merges margin pairs into spot pairs for shared subs (ticker, orderbook, etc) if Spot asset and sub are enabled, // because Kucoin errors on duplicate pairs in separate subs, and doesn't have separate subs for spot and margin -func (ku *Kucoin) mergeMarginPairs(s *subscription.Subscription, ap map[asset.Item]currency.Pairs) string { +func (e *Exchange) mergeMarginPairs(s *subscription.Subscription, ap map[asset.Item]currency.Pairs) string { if strings.HasPrefix(s.Channel, "/margin") { return "" } @@ -1710,25 +1710,25 @@ func (ku *Kucoin) mergeMarginPairs(s *subscription.Subscription, ap map[asset.It _, marginEnabled := ap[asset.Margin] _, spotEnabled := ap[asset.Spot] if marginEnabled && spotEnabled { - marginPairs, _ := ku.GetEnabledPairs(asset.Margin) + marginPairs, _ := e.GetEnabledPairs(asset.Margin) ap[asset.Spot] = common.SortStrings(ap[asset.Spot].Add(marginPairs...)) ap[asset.Margin] = currency.Pairs{} } case asset.Spot: // If there's a margin sub then we should merge the pairs into spot - hasMarginSub := slices.ContainsFunc(ku.Features.Subscriptions, func(sB *subscription.Subscription) bool { + hasMarginSub := slices.ContainsFunc(e.Features.Subscriptions, func(sB *subscription.Subscription) bool { if sB.Asset != asset.Margin && sB.Asset != asset.All { return false } return wantKey.Match(&subscription.IgnoringAssetKey{Subscription: sB}) }) if hasMarginSub { - marginPairs, _ := ku.GetEnabledPairs(asset.Margin) + marginPairs, _ := e.GetEnabledPairs(asset.Margin) ap[asset.Spot] = common.SortStrings(ap[asset.Spot].Add(marginPairs...)) } case asset.Margin: // If there's a spot sub, all margin pairs are already merged, so empty the margin pairs - hasSpotSub := slices.ContainsFunc(ku.Features.Subscriptions, func(sB *subscription.Subscription) bool { + hasSpotSub := slices.ContainsFunc(e.Features.Subscriptions, func(sB *subscription.Subscription) bool { if sB.Asset != asset.Spot && sB.Asset != asset.All { return false } diff --git a/exchanges/kucoin/kucoin_wrapper.go b/exchanges/kucoin/kucoin_wrapper.go index bb95ea630aa..903d1714e50 100644 --- a/exchanges/kucoin/kucoin_wrapper.go +++ b/exchanges/kucoin/kucoin_wrapper.go @@ -35,14 +35,14 @@ import ( ) // SetDefaults sets the basic defaults for Kucoin -func (ku *Kucoin) SetDefaults() { - ku.Name = "Kucoin" - ku.Enabled = true - ku.Verbose = false +func (e *Exchange) SetDefaults() { + e.Name = "Kucoin" + e.Enabled = true + e.Verbose = false - ku.API.CredentialsValidator.RequiresKey = true - ku.API.CredentialsValidator.RequiresSecret = true - ku.API.CredentialsValidator.RequiresClientID = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresClientID = true for _, a := range []asset.Item{asset.Spot, asset.Margin, asset.Futures} { ps := currency.PairStore{ @@ -54,12 +54,12 @@ func (ku *Kucoin) SetDefaults() { ps.RequestFormat.Delimiter = "" ps.ConfigFormat.Delimiter = currency.UnderscoreDelimiter } - if err := ku.SetAssetPairStore(a, ps); err != nil { - log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", ku.Name, a, err) + if err := e.SetAssetPairStore(a, ps); err != nil { + log.Errorf(log.ExchangeSys, "%s error storing %q default asset formats: %s", e.Name, a, err) } } - ku.Features = exchange.Features{ + e.Features = exchange.Features{ CurrencyTranslations: currency.NewTranslations(map[currency.Code]currency.Code{ currency.XBT: currency.BTC, currency.USDTM: currency.USDT, @@ -148,15 +148,15 @@ func (ku *Kucoin) SetDefaults() { } var err error - ku.Requester, err = request.New(ku.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - ku.API.Endpoints = ku.NewEndpoints() - err = ku.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: kucoinAPIURL, exchange.RestFutures: kucoinFuturesAPIURL, exchange.WebsocketSpot: kucoinWebsocketURL, @@ -164,53 +164,53 @@ func (ku *Kucoin) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - ku.Websocket = websocket.NewManager() - ku.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - ku.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - ku.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (ku *Kucoin) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - ku.SetEnabled(false) + e.SetEnabled(false) return nil } - err = ku.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - ku.checkSubscriptions() + e.checkSubscriptions() - wsRunningEndpoint, err := ku.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = ku.Websocket.Setup( + err = e.Websocket.Setup( &websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: kucoinWebsocketURL, RunningURL: wsRunningEndpoint, - Connector: ku.WsConnect, - Subscriber: ku.Subscribe, - Unsubscriber: ku.Unsubscribe, - GenerateSubscriptions: ku.generateSubscriptions, - Features: &ku.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, }, - TradeFeed: ku.Features.Enabled.TradeFeed, + TradeFeed: e.Features.Enabled.TradeFeed, }) if err != nil { return err } - return ku.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, RateLimit: request.NewRateLimitWithWeight(time.Second, 2, 1), @@ -218,11 +218,11 @@ func (ku *Kucoin) Setup(exch *config.Exchange) error { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (ku *Kucoin) FetchTradablePairs(ctx context.Context, assetType asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, assetType asset.Item) (currency.Pairs, error) { var cp currency.Pair switch assetType { case asset.Futures: - myPairs, err := ku.GetFuturesOpenContracts(ctx) + myPairs, err := e.GetFuturesOpenContracts(ctx) if err != nil { return nil, err } @@ -237,13 +237,13 @@ func (ku *Kucoin) FetchTradablePairs(ctx context.Context, assetType asset.Item) } pairs = pairs.Add(cp) } - configFormat, err := ku.GetPairFormat(asset.Futures, false) + configFormat, err := e.GetPairFormat(asset.Futures, false) if err != nil { return nil, err } return pairs.Format(configFormat), nil case asset.Spot, asset.Margin: - myPairs, err := ku.GetSymbols(ctx, "") + myPairs, err := e.GetSymbols(ctx, "") if err != nil { return nil, err } @@ -268,17 +268,17 @@ func (ku *Kucoin) FetchTradablePairs(ctx context.Context, assetType asset.Item) // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (ku *Kucoin) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assets := ku.GetAssetTypes(true) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assets := e.GetAssetTypes(true) for a := range assets { - pairs, err := ku.FetchTradablePairs(ctx, assets[a]) + pairs, err := e.FetchTradablePairs(ctx, assets[a]) if err != nil { return err } if len(pairs) == 0 { return fmt.Errorf("%v; no tradable pairs", currency.ErrCurrencyPairsEmpty) } - err = ku.UpdatePairs(pairs, assets[a], false, forceUpdate) + err = e.UpdatePairs(pairs, assets[a], false, forceUpdate) if err != nil { return err } @@ -287,27 +287,27 @@ func (ku *Kucoin) UpdateTradablePairs(ctx context.Context, forceUpdate bool) err } // UpdateTicker updates and returns the ticker for a currency pair -func (ku *Kucoin) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { - p, err := ku.FormatExchangeCurrency(p, assetType) +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - if err := ku.UpdateTickers(ctx, assetType); err != nil { + if err := e.UpdateTickers(ctx, assetType); err != nil { return nil, err } - return ticker.GetTicker(ku.Name, p, assetType) + return ticker.GetTicker(e.Name, p, assetType) } // UpdateTickers updates all currency pairs of a given asset type -func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, assetType asset.Item) error { var errs error switch assetType { case asset.Futures: - ticks, err := ku.GetFuturesOpenContracts(ctx) + ticks, err := e.GetFuturesOpenContracts(ctx) if err != nil { return err } - pairs, err := ku.GetEnabledPairs(asset.Futures) + pairs, err := e.GetEnabledPairs(asset.Futures) if err != nil { return err } @@ -327,7 +327,7 @@ func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error Volume: ticks[x].VolumeOf24h, OpenInterest: ticks[x].OpenInterest.Float64(), Pair: pair, - ExchangeName: ku.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { @@ -335,12 +335,12 @@ func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error } } case asset.Spot, asset.Margin: - ticks, err := ku.GetTickers(ctx) + ticks, err := e.GetTickers(ctx) if err != nil { return err } for t := range ticks.Tickers { - pair, enabled, err := ku.MatchSymbolCheckEnabled(ticks.Tickers[t].Symbol, assetType, true) + pair, enabled, err := e.MatchSymbolCheckEnabled(ticks.Tickers[t].Symbol, assetType, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return err } @@ -356,7 +356,7 @@ func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error Ask: ticks.Tickers[t].Sell, Bid: ticks.Tickers[t].Buy, Pair: pair, - ExchangeName: ku.Name, + ExchangeName: e.Name, AssetType: assetType, LastUpdated: ticks.Time.Time(), }) @@ -371,21 +371,21 @@ func (ku *Kucoin) UpdateTickers(ctx context.Context, assetType asset.Item) error } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { - err := ku.CurrencyPairs.IsAssetEnabled(assetType) +func (e *Exchange) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { + err := e.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return nil, err } - pair, err = ku.FormatExchangeCurrency(pair, assetType) + pair, err = e.FormatExchangeCurrency(pair, assetType) if err != nil { return nil, err } var ordBook *Orderbook switch assetType { case asset.Futures: - ordBook, err = ku.GetFuturesOrderbook(ctx, pair.String()) + ordBook, err = e.GetFuturesOrderbook(ctx, pair.String()) case asset.Spot, asset.Margin: - ordBook, err = ku.GetPartOrderbook100(ctx, pair.String()) + ordBook, err = e.GetPartOrderbook100(ctx, pair.String()) default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } @@ -394,10 +394,10 @@ func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, asset } book := &orderbook.Book{ - Exchange: ku.Name, + Exchange: e.Name, Pair: pair, Asset: assetType, - ValidateOrderbook: ku.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Asks: ordBook.Asks, Bids: ordBook.Bids, } @@ -405,13 +405,13 @@ func (ku *Kucoin) UpdateOrderbook(ctx context.Context, pair currency.Pair, asset if err != nil { return book, err } - return orderbook.Get(ku.Name, pair, assetType) + return orderbook.Get(e.Name, pair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies -func (ku *Kucoin) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { - holding := account.Holdings{Exchange: ku.Name} - err := ku.CurrencyPairs.IsAssetEnabled(assetType) +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { + holding := account.Holdings{Exchange: e.Name} + err := e.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return holding, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } @@ -419,7 +419,7 @@ func (ku *Kucoin) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( case asset.Futures: balances := make([]account.Balance, 2) for i, settlement := range []string{"XBT", "USDT"} { - accountH, err := ku.GetFuturesAccountOverview(ctx, settlement) + accountH, err := e.GetFuturesAccountOverview(ctx, settlement) if err != nil { return account.Holdings{}, err } @@ -436,7 +436,7 @@ func (ku *Kucoin) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( Currencies: balances, }) case asset.Spot, asset.Margin: - accountH, err := ku.GetAllAccounts(ctx, currency.EMPTYCODE, "") + accountH, err := e.GetAllAccounts(ctx, currency.EMPTYCODE, "") if err != nil { return account.Holdings{}, err } @@ -466,12 +466,12 @@ func (ku *Kucoin) UpdateAccountInfo(ctx context.Context, assetType asset.Item) ( // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (ku *Kucoin) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { - withdrawalsData, err := ku.GetWithdrawalList(ctx, currency.EMPTYCODE, "", time.Time{}, time.Time{}) +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { + withdrawalsData, err := e.GetWithdrawalList(ctx, currency.EMPTYCODE, "", time.Time{}, time.Time{}) if err != nil { return nil, err } - depositsData, err := ku.GetHistoricalDepositList(ctx, currency.EMPTYCODE, "", time.Time{}, time.Time{}) + depositsData, err := e.GetHistoricalDepositList(ctx, currency.EMPTYCODE, "", time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -479,7 +479,7 @@ func (ku *Kucoin) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund for x := range depositsData.Items { fundingData[x] = exchange.FundingHistory{ Timestamp: depositsData.Items[x].CreatedAt.Time(), - ExchangeName: ku.Name, + ExchangeName: e.Name, TransferType: "deposit", CryptoTxID: depositsData.Items[x].WalletTxID, Status: depositsData.Items[x].Status, @@ -492,7 +492,7 @@ func (ku *Kucoin) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund fundingData[length+x] = exchange.FundingHistory{ Fee: withdrawalsData.Items[x].Fee, Timestamp: withdrawalsData.Items[x].UpdatedAt.Time(), - ExchangeName: ku.Name, + ExchangeName: e.Name, TransferType: "withdrawal", CryptoToAddress: withdrawalsData.Items[x].Address, CryptoTxID: withdrawalsData.Items[x].WalletTxID, @@ -506,12 +506,12 @@ func (ku *Kucoin) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fund } // GetWithdrawalsHistory returns previous withdrawals data -func (ku *Kucoin) GetWithdrawalsHistory(ctx context.Context, c currency.Code, assetType asset.Item) ([]exchange.WithdrawalHistory, error) { - if !ku.SupportsAsset(assetType) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, assetType asset.Item) ([]exchange.WithdrawalHistory, error) { + if !e.SupportsAsset(assetType) { return nil, asset.ErrNotSupported } var withdrawals *HistoricalDepositWithdrawalResponse - withdrawals, err := ku.GetHistoricalWithdrawalList(ctx, c.Upper(), "", time.Time{}, time.Time{}) + withdrawals, err := e.GetHistoricalWithdrawalList(ctx, c.Upper(), "", time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -530,15 +530,15 @@ func (ku *Kucoin) GetWithdrawalsHistory(ctx context.Context, c currency.Code, as } // GetRecentTrades returns the most recent trades for a currency and asset -func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - p, err := ku.FormatExchangeCurrency(p, assetType) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + p, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var resp []trade.Data switch assetType { case asset.Futures: - tradeData, err := ku.GetFuturesTradeHistory(ctx, p.String()) + tradeData, err := e.GetFuturesTradeHistory(ctx, p.String()) if err != nil { return nil, err } @@ -550,7 +550,7 @@ func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } resp = append(resp, trade.Data{ TID: tradeData[i].TradeID, - Exchange: ku.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Price: tradeData[i].Price, @@ -560,7 +560,7 @@ func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp }) } case asset.Spot, asset.Margin: - tradeData, err := ku.GetTradeHistory(ctx, p.String()) + tradeData, err := e.GetTradeHistory(ctx, p.String()) if err != nil { return nil, err } @@ -572,7 +572,7 @@ func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } resp = append(resp, trade.Data{ TID: tradeData[i].Sequence, - Exchange: ku.Name, + Exchange: e.Name, CurrencyPair: p, Side: side, AssetType: assetType, @@ -584,7 +584,7 @@ func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - if ku.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err := trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -595,19 +595,19 @@ func (ku *Kucoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp } // GetHistoricTrades returns historic trade data within the timeframe provided -func (ku *Kucoin) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // For OCO (One Cancels the Other) orders, the StopLoss parameters under the order submission argument field RiskManagementModes are treated as stop values, // and the TakeProfit parameters are treated as limit order. -func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - sideString, err := ku.OrderSideString(s.Side) +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + sideString, err := e.OrderSideString(s.Side) if err != nil { return nil, err } - s.Pair, err = ku.FormatExchangeCurrency(s.Pair, s.AssetType) + s.Pair, err = e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } @@ -655,7 +655,7 @@ func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm default: return nil, order.ErrUnsupportedOrderType } - o, err = ku.PostFuturesOrder(ctx, &FuturesOrderParam{ + o, err = e.PostFuturesOrder(ctx, &FuturesOrderParam{ ClientOrderID: s.ClientOrderID, Side: sideString, Symbol: s.Pair, @@ -709,7 +709,7 @@ func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm } var o string if stopType != "" { - o, err = ku.PostStopOrder(ctx, + o, err = e.PostStopOrder(ctx, s.ClientOrderID, sideString, s.Pair.String(), @@ -721,7 +721,7 @@ func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm } return s.DeriveSubmitResponse(o) } - o, err = ku.PostOrder(ctx, &SpotOrderParam{ + o, err = e.PostOrder(ctx, &SpotOrderParam{ ClientOrderID: s.ClientOrderID, Side: sideString, Symbol: s.Pair, @@ -761,7 +761,7 @@ func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm stopPrice := s.RiskManagementModes.StopLoss.Price var o string - o, err = ku.PlaceOCOOrder(ctx, &OCOOrderParams{ + o, err = e.PlaceOCOOrder(ctx, &OCOOrderParams{ Symbol: s.Pair, Side: sideString, Price: s.Price, @@ -778,7 +778,7 @@ func (ku *Kucoin) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm return nil, order.ErrUnsupportedOrderType } case asset.Margin: - o, err := ku.PostMarginOrder(ctx, + o, err := e.PostMarginOrder(ctx, &MarginOrderParam{ ClientOrderID: s.ClientOrderID, Side: sideString, @@ -823,20 +823,20 @@ func MarginModeToString(mType margin.Type) string { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (ku *Kucoin) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (ku *Kucoin) CancelOrder(ctx context.Context, ord *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, ord *order.Cancel) error { if ord == nil { return common.ErrNilPointer } - err := ku.CurrencyPairs.IsAssetEnabled(ord.AssetType) + err := e.CurrencyPairs.IsAssetEnabled(ord.AssetType) if err != nil { return err } - pairFormat, err := ku.GetPairFormat(ord.AssetType, true) + pairFormat, err := e.GetPairFormat(ord.AssetType, true) if err != nil { return err } @@ -849,21 +849,21 @@ func (ku *Kucoin) CancelOrder(ctx context.Context, ord *order.Cancel) error { switch ord.Type { case order.OCO: if ord.OrderID != "" { - _, err = ku.CancelOCOOrderByOrderID(ctx, ord.OrderID) + _, err = e.CancelOCOOrderByOrderID(ctx, ord.OrderID) } else if ord.ClientOrderID != "" { - _, err = ku.CancelOCOOrderByClientOrderID(ctx, ord.ClientOrderID) + _, err = e.CancelOCOOrderByClientOrderID(ctx, ord.ClientOrderID) } case order.Stop, order.StopLimit: if ord.OrderID != "" { - _, err = ku.CancelStopOrder(ctx, ord.OrderID) + _, err = e.CancelStopOrder(ctx, ord.OrderID) } else { - _, err = ku.CancelStopOrderByClientOrderID(ctx, ord.ClientOrderID, ord.Pair.String()) + _, err = e.CancelStopOrderByClientOrderID(ctx, ord.ClientOrderID, ord.Pair.String()) } default: if ord.OrderID != "" { - _, err = ku.CancelSingleOrder(ctx, ord.OrderID) + _, err = e.CancelSingleOrder(ctx, ord.OrderID) } else { - _, err = ku.CancelOrderByClientOID(ctx, ord.ClientOrderID) + _, err = e.CancelOrderByClientOID(ctx, ord.ClientOrderID) } } return err @@ -875,9 +875,9 @@ func (ku *Kucoin) CancelOrder(ctx context.Context, ord *order.Cancel) error { if ord.Pair.IsEmpty() { return fmt.Errorf("%w, symbol information is required", currency.ErrCurrencyPairEmpty) } - _, err = ku.CancelFuturesOrderByClientOrderID(ctx, ord.Pair.String(), ord.ClientOrderID) + _, err = e.CancelFuturesOrderByClientOrderID(ctx, ord.Pair.String(), ord.ClientOrderID) } else { - _, err = ku.CancelFuturesOrderByOrderID(ctx, ord.OrderID) + _, err = e.CancelFuturesOrderByOrderID(ctx, ord.OrderID) } if err != nil { return err @@ -889,16 +889,16 @@ func (ku *Kucoin) CancelOrder(ctx context.Context, ord *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func (ku *Kucoin) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (ku *Kucoin) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if orderCancellation == nil { return order.CancelAllResponse{}, common.ErrNilPointer } - err := ku.CurrencyPairs.IsAssetEnabled(orderCancellation.AssetType) + err := e.CurrencyPairs.IsAssetEnabled(orderCancellation.AssetType) if err != nil { return order.CancelAllResponse{}, err } @@ -909,7 +909,7 @@ func (ku *Kucoin) CancelAllOrders(ctx context.Context, orderCancellation *order. } var pairString string if !orderCancellation.Pair.IsEmpty() { - orderCancellation.Pair, err = ku.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) + orderCancellation.Pair, err = e.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) if err != nil { return result, err } @@ -928,32 +928,32 @@ func (ku *Kucoin) CancelAllOrders(ctx context.Context, orderCancellation *order. switch orderCancellation.Type { case order.OCO: var response *OCOOrderCancellationResponse - response, err = ku.CancelOCOMultipleOrders(ctx, orderIDs, orderCancellation.Pair.String()) + response, err = e.CancelOCOMultipleOrders(ctx, orderIDs, orderCancellation.Pair.String()) if err != nil { return order.CancelAllResponse{}, err } values = response.CancelledOrderIDs case order.Stop, order.StopLimit: - values, err = ku.CancelStopOrders(ctx, + values, err = e.CancelStopOrders(ctx, orderCancellation.Pair.String(), - ku.AccountToTradeTypeString(orderCancellation.AssetType, MarginModeToString(orderCancellation.MarginType)), + e.AccountToTradeTypeString(orderCancellation.AssetType, MarginModeToString(orderCancellation.MarginType)), orderIDs) if err != nil { return order.CancelAllResponse{}, err } default: - tradeType := ku.AccountToTradeTypeString(orderCancellation.AssetType, MarginModeToString(orderCancellation.MarginType)) - values, err = ku.CancelAllOpenOrders(ctx, pairString, tradeType) + tradeType := e.AccountToTradeTypeString(orderCancellation.AssetType, MarginModeToString(orderCancellation.MarginType)) + values, err = e.CancelAllOpenOrders(ctx, pairString, tradeType) if err != nil { return order.CancelAllResponse{}, err } } case asset.Futures: - values, err = ku.CancelMultipleFuturesLimitOrders(ctx, orderCancellation.Pair.String()) + values, err = e.CancelMultipleFuturesLimitOrders(ctx, orderCancellation.Pair.String()) if err != nil { return result, err } - stopOrders, err := ku.CancelAllFuturesStopOrders(ctx, orderCancellation.Pair.String()) + stopOrders, err := e.CancelAllFuturesStopOrders(ctx, orderCancellation.Pair.String()) if err != nil { return result, err } @@ -969,19 +969,19 @@ func (ku *Kucoin) CancelAllOrders(ctx context.Context, orderCancellation *order. } // GetOrderInfo returns order information based on order ID -func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { - err := ku.CurrencyPairs.IsAssetEnabled(assetType) +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { + err := e.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return nil, err } - pair, err = ku.FormatExchangeCurrency(pair, assetType) + pair, err = e.FormatExchangeCurrency(pair, assetType) if err != nil { return nil, err } switch assetType { case asset.Futures: var orderDetail *FuturesOrder - orderDetail, err = ku.GetFuturesOrderDetails(ctx, orderID, "") + orderDetail, err = e.GetFuturesOrderDetails(ctx, orderID, "") if err != nil { return nil, err } @@ -1016,7 +1016,7 @@ func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currenc oStatus = order.Closed } return &order.Detail{ - Exchange: ku.Name, + Exchange: e.Name, OrderID: orderDetail.ID, Pair: pair, Type: oType, @@ -1039,7 +1039,7 @@ func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currenc LastUpdated: orderDetail.UpdatedAt.Time(), }, nil case asset.Spot, asset.Margin: - orderDetail, err := ku.GetOrderByID(ctx, orderID) + orderDetail, err := e.GetOrderByID(ctx, orderID) if err != nil { return nil, err } @@ -1086,7 +1086,7 @@ func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currenc remainingSize = orderDetail.Size.Float64() - orderDetail.DealSize.Float64() } return &order.Detail{ - Exchange: ku.Name, + Exchange: e.Name, OrderID: orderDetail.ID, Pair: pair, Type: oType, @@ -1114,8 +1114,8 @@ func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currenc } // GetDepositAddress returns a deposit address for a specified currency -func (ku *Kucoin) GetDepositAddress(ctx context.Context, c currency.Code, _, chain string) (*deposit.Address, error) { - ad, err := ku.GetDepositAddressesV2(ctx, c.Upper()) +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, _, chain string) (*deposit.Address, error) { + ad, err := e.GetDepositAddressesV2(ctx, c.Upper()) if err != nil { return nil, err } @@ -1148,11 +1148,11 @@ func (ku *Kucoin) GetDepositAddress(ctx context.Context, c currency.Code, _, cha // submitted // The endpoint was deprecated for futures, please transfer assets from the FUTURES account to the MAIN account first, // and then withdraw from the MAIN account -func (ku *Kucoin) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - withdrawalID, err := ku.ApplyWithdrawal(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Description, withdrawRequest.Crypto.Chain, "INTERNAL", withdrawRequest.InternalTransfer, withdrawRequest.Amount) + withdrawalID, err := e.ApplyWithdrawal(ctx, withdrawRequest.Currency, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Description, withdrawRequest.Crypto.Chain, "INTERNAL", withdrawRequest.InternalTransfer, withdrawRequest.Amount) if err != nil { return nil, err } @@ -1162,13 +1162,13 @@ func (ku *Kucoin) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted -func (ku *Kucoin) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (ku *Kucoin) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } @@ -1191,18 +1191,18 @@ func OrderTypeToString(oType order.Type) (string, error) { } // GetActiveOrders retrieves any orders that are active/open -func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { if getOrdersRequest == nil { return nil, common.ErrNilPointer } - err := ku.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType) + err := e.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType) if err != nil { return nil, err } if err := getOrdersRequest.Validate(); err != nil { return nil, err } - format, err := ku.GetPairFormat(getOrdersRequest.AssetType, true) + format, err := e.GetPairFormat(getOrdersRequest.AssetType, true) if err != nil { return nil, err } @@ -1214,7 +1214,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if len(getOrdersRequest.Pairs) == 1 { pair = format.Format(getOrdersRequest.Pairs[0]) } - sideString, err := ku.OrderSideString(getOrdersRequest.Side) + sideString, err := e.OrderSideString(getOrdersRequest.Side) if err != nil { return nil, err } @@ -1222,7 +1222,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if err != nil { return nil, err } - futuresOrders, err := ku.GetFuturesOrders(ctx, "active", pair, sideString, oType, getOrdersRequest.StartTime, getOrdersRequest.EndTime) + futuresOrders, err := e.GetFuturesOrders(ctx, "active", pair, sideString, oType, getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, err } @@ -1232,7 +1232,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M } var dPair currency.Pair var enabled bool - dPair, enabled, err = ku.MatchSymbolCheckEnabled(futuresOrders.Items[x].Symbol, getOrdersRequest.AssetType, false) + dPair, enabled, err = e.MatchSymbolCheckEnabled(futuresOrders.Items[x].Symbol, getOrdersRequest.AssetType, false) if err != nil { return nil, err } @@ -1268,7 +1268,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M ContractAmount: futuresOrders.Items[x].Size, RemainingAmount: futuresOrders.Items[x].Size - futuresOrders.Items[x].FilledSize, ExecutedAmount: futuresOrders.Items[x].FilledSize, - Exchange: ku.Name, + Exchange: e.Name, Date: futuresOrders.Items[x].CreatedAt.Time(), LastUpdated: futuresOrders.Items[x].UpdatedAt.Time(), Price: futuresOrders.Items[x].Price, @@ -1291,7 +1291,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M } switch getOrdersRequest.Type { case order.OCO: - response, err := ku.GetOCOOrderList(ctx, 500, 1, singlePair.String(), getOrdersRequest.StartTime, getOrdersRequest.EndTime, []string{}) + response, err := e.GetOCOOrderList(ctx, 500, 1, singlePair.String(), getOrdersRequest.StartTime, getOrdersRequest.EndTime, []string{}) if err != nil { return nil, err } @@ -1313,7 +1313,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M orders = append(orders, order.Detail{ OrderID: response.Items[a].OrderID, ClientOrderID: response.Items[a].ClientOrderID, - Exchange: ku.Name, + Exchange: e.Name, LastUpdated: response.Items[a].OrderTime.Time(), Type: order.OCO, Pair: cp, @@ -1331,7 +1331,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M tradeType = IsolatedMarginTradeType } } - response, err := ku.ListStopOrders(ctx, singlePair.String(), getOrdersRequest.Side.Lower(), "", tradeType, []string{getOrdersRequest.FromOrderID}, getOrdersRequest.StartTime, getOrdersRequest.EndTime, 0, 0) + response, err := e.ListStopOrders(ctx, singlePair.String(), getOrdersRequest.Side.Lower(), "", tradeType, []string{getOrdersRequest.FromOrderID}, getOrdersRequest.StartTime, getOrdersRequest.EndTime, 0, 0) if err != nil { return nil, err } @@ -1341,7 +1341,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M } var dPair currency.Pair var enabled bool - dPair, enabled, err = ku.MatchSymbolCheckEnabled(response.Items[a].Symbol, getOrdersRequest.AssetType, false) + dPair, enabled, err = e.MatchSymbolCheckEnabled(response.Items[a].Symbol, getOrdersRequest.AssetType, false) if err != nil { return nil, err } @@ -1364,7 +1364,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M ClientOrderID: response.Items[a].ClientOID, Amount: response.Items[a].Size, ContractAmount: response.Items[a].Size, - Exchange: ku.Name, + Exchange: e.Name, Date: response.Items[a].CreatedAt.Time(), LastUpdated: response.Items[a].OrderTime.Time(), Price: response.Items[a].Price, @@ -1381,7 +1381,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if len(getOrdersRequest.Pairs) == 1 { pair = format.Format(getOrdersRequest.Pairs[0]) } - sideString, err := ku.OrderSideString(getOrdersRequest.Side) + sideString, err := e.OrderSideString(getOrdersRequest.Side) if err != nil { return nil, err } @@ -1389,7 +1389,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if err != nil { return nil, fmt.Errorf("asset type: %v order type: %v err: %w", getOrdersRequest.AssetType, getOrdersRequest.Type, err) } - spotOrders, err := ku.ListOrders(ctx, "active", pair, sideString, oType, "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) + spotOrders, err := e.ListOrders(ctx, "active", pair, sideString, oType, "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, err } @@ -1399,7 +1399,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M } var dPair currency.Pair var isEnabled bool - dPair, isEnabled, err = ku.MatchSymbolCheckEnabled(spotOrders.Items[x].Symbol, getOrdersRequest.AssetType, true) + dPair, isEnabled, err = e.MatchSymbolCheckEnabled(spotOrders.Items[x].Symbol, getOrdersRequest.AssetType, true) if err != nil { return nil, err } @@ -1422,7 +1422,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M Amount: spotOrders.Items[x].Size.Float64(), RemainingAmount: spotOrders.Items[x].Size.Float64() - spotOrders.Items[x].DealSize.Float64(), ExecutedAmount: spotOrders.Items[x].DealSize.Float64(), - Exchange: ku.Name, + Exchange: e.Name, Date: spotOrders.Items[x].CreatedAt.Time(), Price: spotOrders.Items[x].Price.Float64(), Side: side, @@ -1439,18 +1439,18 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { if getOrdersRequest == nil { return nil, common.ErrNilPointer } - if err := ku.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType); err != nil { return nil, err } if err := getOrdersRequest.Validate(); err != nil { return nil, err } - sideString, err := ku.OrderSideString(getOrdersRequest.Side) + sideString, err := e.OrderSideString(getOrdersRequest.Side) if err != nil { return nil, err } @@ -1465,17 +1465,17 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M var futuresOrders *FutureOrdersResponse var newOrders *FutureOrdersResponse if len(getOrdersRequest.Pairs) == 0 { - futuresOrders, err = ku.GetFuturesOrders(ctx, "", "", sideString, getOrdersRequest.Type.Lower(), getOrdersRequest.StartTime, getOrdersRequest.EndTime) + futuresOrders, err = e.GetFuturesOrders(ctx, "", "", sideString, getOrdersRequest.Type.Lower(), getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, err } } else { for x := range getOrdersRequest.Pairs { - getOrdersRequest.Pairs[x], err = ku.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) + getOrdersRequest.Pairs[x], err = e.FormatExchangeCurrency(getOrdersRequest.Pairs[x], getOrdersRequest.AssetType) if err != nil { return nil, err } - newOrders, err = ku.GetFuturesOrders(ctx, "", getOrdersRequest.Pairs[x].String(), sideString, getOrdersRequest.Type.Lower(), getOrdersRequest.StartTime, getOrdersRequest.EndTime) + newOrders, err = e.GetFuturesOrders(ctx, "", getOrdersRequest.Pairs[x].String(), sideString, getOrdersRequest.Type.Lower(), getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, fmt.Errorf("%w while fetching for symbol %s", err, getOrdersRequest.Pairs[x].String()) } @@ -1493,7 +1493,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M return nil, err } var isEnabled bool - pair, isEnabled, err = ku.MatchSymbolCheckEnabled(futuresOrders.Items[i].Symbol, getOrdersRequest.AssetType, true) + pair, isEnabled, err = e.MatchSymbolCheckEnabled(futuresOrders.Items[i].Symbol, getOrdersRequest.AssetType, true) if err != nil { return nil, err } @@ -1502,7 +1502,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } oType, err = order.StringToOrderType(futuresOrders.Items[i].OrderType) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", ku.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders = append(orders, order.Detail{ Price: futuresOrders.Items[i].Price, @@ -1510,7 +1510,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M ExecutedAmount: futuresOrders.Items[i].DealSize, RemainingAmount: futuresOrders.Items[i].Size - futuresOrders.Items[i].DealSize, Date: futuresOrders.Items[i].CreatedAt.Time(), - Exchange: ku.Name, + Exchange: e.Name, OrderID: futuresOrders.Items[i].ID, Side: orderSide, Status: orderStatus, @@ -1527,7 +1527,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M switch getOrdersRequest.Type { case order.OCO: var response *OCOOrders - response, err = ku.GetOCOOrderList(ctx, 500, 1, singlePair.String(), getOrdersRequest.StartTime, getOrdersRequest.EndTime, []string{}) + response, err = e.GetOCOOrderList(ctx, 500, 1, singlePair.String(), getOrdersRequest.StartTime, getOrdersRequest.EndTime, []string{}) if err != nil { return nil, err } @@ -1548,7 +1548,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M orders = append(orders, order.Detail{ OrderID: response.Items[a].OrderID, ClientOrderID: response.Items[a].ClientOrderID, - Exchange: ku.Name, + Exchange: e.Name, LastUpdated: response.Items[a].OrderTime.Time(), Type: order.OCO, Pair: cp, @@ -1567,14 +1567,14 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } } var response *StopOrderListResponse - response, err = ku.ListStopOrders(ctx, singlePair.String(), sideString, "", tradeType, []string{getOrdersRequest.FromOrderID}, getOrdersRequest.StartTime, getOrdersRequest.EndTime, 0, 0) + response, err = e.ListStopOrders(ctx, singlePair.String(), sideString, "", tradeType, []string{getOrdersRequest.FromOrderID}, getOrdersRequest.StartTime, getOrdersRequest.EndTime, 0, 0) if err != nil { return nil, err } for a := range response.Items { var dPair currency.Pair var enabled bool - dPair, enabled, err = ku.MatchSymbolCheckEnabled(response.Items[a].Symbol, getOrdersRequest.AssetType, false) + dPair, enabled, err = e.MatchSymbolCheckEnabled(response.Items[a].Symbol, getOrdersRequest.AssetType, false) if err != nil { return nil, err } @@ -1602,7 +1602,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M Amount: response.Items[a].Size, ContractAmount: response.Items[a].Size, TriggerPrice: response.Items[a].StopPrice, - Exchange: ku.Name, + Exchange: e.Name, Date: response.Items[a].CreatedAt.Time(), LastUpdated: response.Items[a].OrderTime.Time(), Price: response.Items[a].Price, @@ -1619,13 +1619,13 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M var responseOrders *OrdersListResponse var newOrders *OrdersListResponse if len(getOrdersRequest.Pairs) == 0 { - responseOrders, err = ku.ListOrders(ctx, "", "", sideString, getOrdersRequest.Type.Lower(), "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) + responseOrders, err = e.ListOrders(ctx, "", "", sideString, getOrdersRequest.Type.Lower(), "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, err } } else { for x := range getOrdersRequest.Pairs { - newOrders, err = ku.ListOrders(ctx, "", getOrdersRequest.Pairs[x].String(), sideString, getOrdersRequest.Type.Lower(), "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) + newOrders, err = e.ListOrders(ctx, "", getOrdersRequest.Pairs[x].String(), sideString, getOrdersRequest.Type.Lower(), "", getOrdersRequest.StartTime, getOrdersRequest.EndTime) if err != nil { return nil, fmt.Errorf("%w while fetching for symbol %s", err, getOrdersRequest.Pairs[x].String()) } @@ -1650,7 +1650,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M var oType order.Type oType, err = order.StringToOrderType(responseOrders.Items[i].Type) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", ku.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orders[i] = order.Detail{ Price: responseOrders.Items[i].Price.Float64(), @@ -1658,7 +1658,7 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M ExecutedAmount: responseOrders.Items[i].DealSize.Float64(), RemainingAmount: responseOrders.Items[i].Size.Float64() - responseOrders.Items[i].DealSize.Float64(), Date: responseOrders.Items[i].CreatedAt.Time(), - Exchange: ku.Name, + Exchange: e.Name, OrderID: responseOrders.Items[i].ID, Side: orderSide, Status: orderStatus, @@ -1669,15 +1669,15 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M } } } - return getOrdersRequest.Filter(ku.Name, orders), nil + return getOrdersRequest.Filter(e.Name, orders), nil } // GetFeeByType returns an estimate of fee based on the type of transaction -func (ku *Kucoin) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !ku.AreCredentialsValid(ctx) && + if !e.AreCredentialsValid(ctx) && feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } @@ -1687,7 +1687,7 @@ func (ku *Kucoin) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil switch feeBuilder.FeeType { case exchange.CryptocurrencyWithdrawalFee, exchange.CryptocurrencyTradeFee: - fee, err := ku.GetTradingFee(ctx, currency.Pairs{feeBuilder.Pair}) + fee, err := e.GetTradingFee(ctx, currency.Pairs{feeBuilder.Pair}) if err != nil { return 0, err } @@ -1701,7 +1701,7 @@ func (ku *Kucoin) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil return 0, nil default: if !feeBuilder.FiatCurrency.IsEmpty() { - fee, err := ku.GetBasicFee(ctx, "1") + fee, err := e.GetBasicFee(ctx, "1") if err != nil { return 0, err } @@ -1715,18 +1715,18 @@ func (ku *Kucoin) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil } // ValidateCredentials validates current credentials used for wrapper -func (ku *Kucoin) ValidateCredentials(ctx context.Context, assetType asset.Item) error { - err := ku.CurrencyPairs.IsAssetEnabled(assetType) +func (e *Exchange) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + err := e.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return err } - _, err = ku.UpdateAccountInfo(ctx, assetType) - return ku.CheckTransientError(err) + _, err = e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (ku *Kucoin) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := ku.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } @@ -1734,7 +1734,7 @@ func (ku *Kucoin) GetHistoricCandles(ctx context.Context, pair currency.Pair, a switch a { case asset.Futures: var candles []FuturesKline - candles, err := ku.GetFuturesKline(ctx, int64(interval.Duration().Minutes()), req.RequestFormatted.String(), req.Start, req.End) + candles, err := e.GetFuturesKline(ctx, int64(interval.Duration().Minutes()), req.RequestFormatted.String(), req.Start, req.End) if err != nil { return nil, err } @@ -1755,7 +1755,7 @@ func (ku *Kucoin) GetHistoricCandles(ctx context.Context, pair currency.Pair, a return nil, err } var candles []Kline - candles, err = ku.GetKlines(ctx, req.RequestFormatted.String(), intervalString, req.Start, req.End) + candles, err = e.GetKlines(ctx, req.RequestFormatted.String(), intervalString, req.Start, req.End) if err != nil { return nil, err } @@ -1777,8 +1777,8 @@ func (ku *Kucoin) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (ku *Kucoin) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := ku.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -1788,7 +1788,7 @@ func (ku *Kucoin) GetHistoricCandlesExtended(ctx context.Context, pair currency. case asset.Futures: for x := range req.RangeHolder.Ranges { var candles []FuturesKline - candles, err = ku.GetFuturesKline(ctx, int64(interval.Duration().Minutes()), req.RequestFormatted.String(), req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) + candles, err = e.GetFuturesKline(ctx, int64(interval.Duration().Minutes()), req.RequestFormatted.String(), req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) if err != nil { return nil, err } @@ -1813,7 +1813,7 @@ func (ku *Kucoin) GetHistoricCandlesExtended(ctx context.Context, pair currency. } var candles []Kline for x := range req.RangeHolder.Ranges { - candles, err = ku.GetKlines(ctx, req.RequestFormatted.String(), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) + candles, err = e.GetKlines(ctx, req.RequestFormatted.String(), intervalString, req.RangeHolder.Ranges[x].Start.Time, req.RangeHolder.Ranges[x].End.Time) if err != nil { return nil, err } @@ -1836,24 +1836,23 @@ func (ku *Kucoin) GetHistoricCandlesExtended(ctx context.Context, pair currency. } // GetServerTime returns the current exchange server time. -func (ku *Kucoin) GetServerTime(ctx context.Context, a asset.Item) (time.Time, error) { +func (e *Exchange) GetServerTime(ctx context.Context, a asset.Item) (time.Time, error) { switch a { case asset.Spot, asset.Margin: - return ku.GetCurrentServerTime(ctx) + return e.GetCurrentServerTime(ctx) case asset.Futures: - return ku.GetFuturesServerTime(ctx) + return e.GetFuturesServerTime(ctx) default: return time.Time{}, fmt.Errorf("%w %v", asset.ErrNotSupported, a) } } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (ku *Kucoin) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { if cryptocurrency.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } - currencyDetail, err := ku.GetCurrencyDetailV3(ctx, cryptocurrency, "") + currencyDetail, err := e.GetCurrencyDetailV3(ctx, cryptocurrency, "") if err != nil { return nil, err } @@ -1866,21 +1865,21 @@ func (ku *Kucoin) GetAvailableTransferChains(ctx context.Context, cryptocurrency // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (ku *Kucoin) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := ku.UpdateAccountInfo(ctx, assetType) - return ku.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetFuturesContractDetails returns details about futures contracts -func (ku *Kucoin) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } - if !ku.SupportsAsset(item) || item != asset.Futures { + if !e.SupportsAsset(item) || item != asset.Futures { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item) } - contracts, err := ku.GetFuturesOpenContracts(ctx) + contracts, err := e.GetFuturesOpenContracts(ctx) if err != nil { return nil, err } @@ -1908,15 +1907,15 @@ func (ku *Kucoin) GetFuturesContractDetails(ctx context.Context, item asset.Item contractSettlementType = futures.Inverse } var fri time.Duration - if len(ku.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { + if len(e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined - for k := range ku.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { + for k := range e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { fri = k.Duration() } } timeOfCurrentFundingRate := time.Now().Add((time.Duration(contracts[i].NextFundingRateTime) * time.Millisecond) - fri).Truncate(time.Hour).UTC() resp[i] = futures.Contract{ - Exchange: ku.Name, + Exchange: e.Name, Name: cp, Underlying: underlying, SettlementCurrencies: currency.Currencies{settleCurr}, @@ -1940,24 +1939,24 @@ func (ku *Kucoin) GetFuturesContractDetails(ctx context.Context, item asset.Item } // GetLatestFundingRates returns the latest funding rates data -func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } var fri time.Duration - if len(ku.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { + if len(e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined - for k := range ku.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { + for k := range e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { fri = k.Duration() } } if r.Pair.IsEmpty() { - contracts, err := ku.GetFuturesOpenContracts(ctx) + contracts, err := e.GetFuturesOpenContracts(ctx) if err != nil { return nil, err } if r.IncludePredictedRate { - log.Warnf(log.ExchangeSys, "%s predicted rate for all currencies requires an additional %v requests", ku.Name, len(contracts)) + log.Warnf(log.ExchangeSys, "%s predicted rate for all currencies requires an additional %v requests", e.Name, len(contracts)) } timeChecked := time.Now() resp := make([]fundingrate.LatestRateResponse, 0, len(contracts)) @@ -1969,7 +1968,7 @@ func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late return nil, err } var isPerp bool - isPerp, err = ku.IsPerpetualFutureCurrency(r.Asset, cp) + isPerp, err = e.IsPerpetualFutureCurrency(r.Asset, cp) if err != nil { return nil, err } @@ -1978,7 +1977,7 @@ func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } rate := fundingrate.LatestRateResponse{ - Exchange: ku.Name, + Exchange: e.Name, Asset: r.Asset, Pair: cp, LatestRate: fundingrate.Rate{ @@ -1990,7 +1989,7 @@ func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } if r.IncludePredictedRate { var fr *FuturesFundingRate - fr, err = ku.GetFuturesCurrentFundingRate(ctx, contracts[i].Symbol) + fr, err = e.GetFuturesCurrentFundingRate(ctx, contracts[i].Symbol) if err != nil { return nil, err } @@ -2004,24 +2003,24 @@ func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late return resp, nil } resp := make([]fundingrate.LatestRateResponse, 1) - is, err := ku.IsPerpetualFutureCurrency(r.Asset, r.Pair) + is, err := e.IsPerpetualFutureCurrency(r.Asset, r.Pair) if err != nil { return nil, err } if !is { return nil, fmt.Errorf("%w %s %v", futures.ErrNotPerpetualFuture, r.Asset, r.Pair) } - fPair, err := ku.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } var fr *FuturesFundingRate - fr, err = ku.GetFuturesCurrentFundingRate(ctx, fPair.String()) + fr, err = e.GetFuturesCurrentFundingRate(ctx, fPair.String()) if err != nil { return nil, err } rate := fundingrate.LatestRateResponse{ - Exchange: ku.Name, + Exchange: e.Name, Asset: r.Asset, Pair: r.Pair, LatestRate: fundingrate.Rate{ @@ -2042,12 +2041,12 @@ func (ku *Kucoin) GetLatestFundingRates(ctx context.Context, r *fundingrate.Late } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (ku *Kucoin) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, cp currency.Pair) (bool, error) { return a == asset.Futures && (cp.Quote.Equal(currency.USDTM) || cp.Quote.Equal(currency.USDM)), nil } // GetHistoricalFundingRates returns funding rates for a given asset and currency for a time period -func (ku *Kucoin) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { +func (e *Exchange) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -2066,12 +2065,12 @@ func (ku *Kucoin) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } } var err error - r.Pair, err = ku.FormatExchangeCurrency(r.Pair, r.Asset) + r.Pair, err = e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } - records, err := ku.GetPublicFundingRate(ctx, r.Pair.String(), r.StartDate, r.EndDate) + records, err := e.GetPublicFundingRate(ctx, r.Pair.String(), r.StartDate, r.EndDate) if err != nil { return nil, err } @@ -2097,7 +2096,7 @@ func (ku *Kucoin) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } return &fundingrate.HistoricalRates{ - Exchange: ku.Name, + Exchange: e.Name, Asset: r.Asset, Pair: r.Pair, FundingRates: fundingRates, @@ -2109,32 +2108,32 @@ func (ku *Kucoin) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. } // GetLeverage gets the account's initial leverage for the asset type and pair -func (ku *Kucoin) GetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ order.Side) (float64, error) { +func (e *Exchange) GetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ order.Side) (float64, error) { return -1, fmt.Errorf("%w leverage is set during order placement, view orders to view leverage", common.ErrFunctionNotSupported) } // SetLeverage sets the account's initial leverage for the asset type and pair -func (ku *Kucoin) SetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ float64, _ order.Side) error { +func (e *Exchange) SetLeverage(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type, _ float64, _ order.Side) error { return fmt.Errorf("%w leverage is set during order placement", common.ErrFunctionNotSupported) } // SetMarginType sets the default margin type for when opening a new position -func (ku *Kucoin) SetMarginType(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type) error { +func (e *Exchange) SetMarginType(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type) error { return fmt.Errorf("%w must be set via website", common.ErrFunctionNotSupported) } // SetCollateralMode sets the collateral type for your account -func (ku *Kucoin) SetCollateralMode(_ context.Context, _ asset.Item, _ collateral.Mode) error { +func (e *Exchange) SetCollateralMode(_ context.Context, _ asset.Item, _ collateral.Mode) error { return fmt.Errorf("%w must be set via website", common.ErrFunctionNotSupported) } // GetCollateralMode returns the collateral type for your account -func (ku *Kucoin) GetCollateralMode(_ context.Context, _ asset.Item) (collateral.Mode, error) { +func (e *Exchange) GetCollateralMode(_ context.Context, _ asset.Item) (collateral.Mode, error) { return collateral.UnknownMode, fmt.Errorf("%w only via website", common.ErrFunctionNotSupported) } // ChangePositionMargin will modify a position/currencies margin parameters -func (ku *Kucoin) ChangePositionMargin(ctx context.Context, r *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { +func (e *Exchange) ChangePositionMargin(ctx context.Context, r *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } @@ -2147,20 +2146,20 @@ func (ku *Kucoin) ChangePositionMargin(ctx context.Context, r *margin.PositionCh if r.MarginType != margin.Isolated { return nil, fmt.Errorf("%w %v", margin.ErrMarginTypeUnsupported, r.MarginType) } - fPair, err := ku.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } - resp, err := ku.AddMargin(ctx, fPair.String(), fmt.Sprintf("%s%v%v", r.Pair, r.NewAllocatedMargin, time.Now().Unix()), r.NewAllocatedMargin) + resp, err := e.AddMargin(ctx, fPair.String(), fmt.Sprintf("%s%v%v", r.Pair, r.NewAllocatedMargin, time.Now().Unix()), r.NewAllocatedMargin) if err != nil { return nil, err } if resp == nil { - return nil, fmt.Errorf("%s - %s", ku.Name, "no response received") + return nil, fmt.Errorf("%s - %s", e.Name, "no response received") } return &margin.PositionChangeResponse{ - Exchange: ku.Name, + Exchange: e.Name, Pair: r.Pair, Asset: r.Asset, AllocatedMargin: resp.PosMargin, @@ -2169,7 +2168,7 @@ func (ku *Kucoin) ChangePositionMargin(ctx context.Context, r *margin.PositionCh } // GetFuturesPositionSummary returns position summary details for an active position -func (ku *Kucoin) GetFuturesPositionSummary(ctx context.Context, r *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { +func (e *Exchange) GetFuturesPositionSummary(ctx context.Context, r *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } @@ -2179,11 +2178,11 @@ func (ku *Kucoin) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi if r.Pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - fPair, err := ku.FormatExchangeCurrency(r.Pair, r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pair, r.Asset) if err != nil { return nil, err } - pos, err := ku.GetFuturesPosition(ctx, fPair.String()) + pos, err := e.GetFuturesPosition(ctx, fPair.String()) if err != nil { return nil, err } @@ -2191,7 +2190,7 @@ func (ku *Kucoin) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi if pos.CrossMode { marginType = margin.Multi } - contracts, err := ku.GetFuturesContractDetails(ctx, r.Asset) + contracts, err := e.GetFuturesContractDetails(ctx, r.Asset) if err != nil { return nil, err } @@ -2206,7 +2205,7 @@ func (ku *Kucoin) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi settlementType = contracts[i].SettlementType } - ao, err := ku.GetFuturesAccountOverview(ctx, fPair.Base.String()) + ao, err := e.GetFuturesAccountOverview(ctx, fPair.Base.String()) if err != nil { return nil, err } @@ -2242,7 +2241,7 @@ func (ku *Kucoin) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi } // GetFuturesPositionOrders returns the orders for futures positions -func (ku *Kucoin) GetFuturesPositionOrders(ctx context.Context, r *futures.PositionsRequest) ([]futures.PositionResponse, error) { +func (e *Exchange) GetFuturesPositionOrders(ctx context.Context, r *futures.PositionsRequest) ([]futures.PositionResponse, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } @@ -2256,21 +2255,21 @@ func (ku *Kucoin) GetFuturesPositionOrders(ctx context.Context, r *futures.Posit if err != nil { return nil, err } - if !r.EndDate.IsZero() && r.EndDate.Sub(r.StartDate) > ku.Features.Supports.MaximumOrderHistory { + if !r.EndDate.IsZero() && r.EndDate.Sub(r.StartDate) > e.Features.Supports.MaximumOrderHistory { if r.RespectOrderHistoryLimits { - r.StartDate = time.Now().Add(-ku.Features.Supports.MaximumOrderHistory) + r.StartDate = time.Now().Add(-e.Features.Supports.MaximumOrderHistory) } else { - return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-ku.Features.Supports.MaximumOrderHistory)) + return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-e.Features.Supports.MaximumOrderHistory)) } } - contracts, err := ku.GetFuturesContractDetails(ctx, r.Asset) + contracts, err := e.GetFuturesContractDetails(ctx, r.Asset) if err != nil { return nil, err } resp := make([]futures.PositionResponse, len(r.Pairs)) for x := range r.Pairs { var multiplier float64 - fPair, err := ku.FormatExchangeCurrency(r.Pairs[x], r.Asset) + fPair, err := e.FormatExchangeCurrency(r.Pairs[x], r.Asset) if err != nil { return nil, err } @@ -2281,7 +2280,7 @@ func (ku *Kucoin) GetFuturesPositionOrders(ctx context.Context, r *futures.Posit multiplier = contracts[i].Multiplier } - positionOrders, err := ku.GetFuturesOrders(ctx, "", fPair.String(), "", "", r.StartDate, r.EndDate) + positionOrders, err := e.GetFuturesOrders(ctx, "", fPair.String(), "", "", r.StartDate, r.EndDate) if err != nil { return nil, err } @@ -2307,7 +2306,7 @@ func (ku *Kucoin) GetFuturesPositionOrders(ctx context.Context, r *futures.Posit ExecutedAmount: positionOrders.Items[y].FilledSize, RemainingAmount: positionOrders.Items[y].Size - positionOrders.Items[y].FilledSize, CostAsset: currency.NewCode(positionOrders.Items[y].SettleCurrency), - Exchange: ku.Name, + Exchange: e.Name, OrderID: positionOrders.Items[y].ID, ClientOrderID: positionOrders.Items[y].ClientOid, Type: oType, @@ -2325,15 +2324,15 @@ func (ku *Kucoin) GetFuturesPositionOrders(ctx context.Context, r *futures.Posit } // UpdateOrderExecutionLimits updates order execution limits -func (ku *Kucoin) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { - if !ku.SupportsAsset(a) { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { + if !e.SupportsAsset(a) { return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } var limits []order.MinMaxLevel switch a { case asset.Spot, asset.Margin: - symbols, err := ku.GetSymbols(ctx, "") + symbols, err := e.GetSymbols(ctx, "") if err != nil { return err } @@ -2342,7 +2341,7 @@ func (ku *Kucoin) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) if a == asset.Margin && !symbols[x].IsMarginEnabled { continue } - pair, enabled, err := ku.MatchSymbolCheckEnabled(symbols[x].Symbol, a, true) + pair, enabled, err := e.MatchSymbolCheckEnabled(symbols[x].Symbol, a, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return err } @@ -2362,13 +2361,13 @@ func (ku *Kucoin) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) }) } case asset.Futures: - contract, err := ku.GetFuturesOpenContracts(ctx) + contract, err := e.GetFuturesOpenContracts(ctx) if err != nil { return err } limits = make([]order.MinMaxLevel, 0, len(contract)) for x := range contract { - pair, enabled, err := ku.MatchSymbolCheckEnabled(contract[x].Symbol, a, false) + pair, enabled, err := e.MatchSymbolCheckEnabled(contract[x].Symbol, a, false) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return err } @@ -2386,18 +2385,18 @@ func (ku *Kucoin) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) } } - return ku.LoadLimits(limits) + return e.LoadLimits(limits) } // GetOpenInterest returns the open interest rate for a given asset pair -func (ku *Kucoin) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { if k[i].Asset != asset.Futures { // avoid API calls or returning errors after a successful retrieval return nil, fmt.Errorf("%w %v %v", asset.ErrNotSupported, k[i].Asset, k[i].Pair()) } } - contracts, err := ku.GetFuturesOpenContracts(ctx) + contracts, err := e.GetFuturesOpenContracts(ctx) if err != nil { return nil, err } @@ -2405,7 +2404,7 @@ func (ku *Kucoin) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu for i := range contracts { var symbol currency.Pair var enabled bool - symbol, enabled, err = ku.MatchSymbolCheckEnabled(contracts[i].Symbol, asset.Futures, true) + symbol, enabled, err = e.MatchSymbolCheckEnabled(contracts[i].Symbol, asset.Futures, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2424,7 +2423,7 @@ func (ku *Kucoin) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: ku.Name, + Exchange: e.Name, Base: symbol.Base.Item, Quote: symbol.Quote.Item, Asset: asset.Futures, @@ -2436,8 +2435,8 @@ func (ku *Kucoin) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]fu } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (ku *Kucoin) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := ku.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/lbank/lbank.go b/exchanges/lbank/lbank.go index 4b20a3bd03a..04e0f097602 100644 --- a/exchanges/lbank/lbank.go +++ b/exchanges/lbank/lbank.go @@ -28,8 +28,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/request" ) -// Lbank is the overarching type across this package -type Lbank struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Lbank +type Exchange struct { exchange.Base privateKey *rsa.PrivateKey } @@ -74,19 +74,19 @@ var ( // GetTicker returns a ticker for the specified symbol // symbol: eth_btc -func (l *Lbank) GetTicker(ctx context.Context, symbol string) (*TickerResponse, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (*TickerResponse, error) { var t *TickerResponse params := url.Values{} params.Set("symbol", symbol) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion1, lbankTicker, params.Encode()) - return t, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) + return t, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) } // GetTimestamp returns a timestamp -func (l *Lbank) GetTimestamp(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetTimestamp(ctx context.Context) (time.Time, error) { var resp TimestampResponse path := fmt.Sprintf("/v%s/%s", lbankAPIVersion2, lbankTimestamp) - err := l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return time.Time{}, err } @@ -94,35 +94,35 @@ func (l *Lbank) GetTimestamp(ctx context.Context) (time.Time, error) { } // GetTickers returns all tickers -func (l *Lbank) GetTickers(ctx context.Context) ([]TickerResponse, error) { +func (e *Exchange) GetTickers(ctx context.Context) ([]TickerResponse, error) { var t []TickerResponse params := url.Values{} params.Set("symbol", "all") path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion1, lbankTicker, params.Encode()) - return t, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) + return t, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) } // GetCurrencyPairs returns a list of supported currency pairs by the exchange -func (l *Lbank) GetCurrencyPairs(ctx context.Context) ([]string, error) { +func (e *Exchange) GetCurrencyPairs(ctx context.Context) ([]string, error) { path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankCurrencyPairs) var result []string - return result, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) } // GetMarketDepths returns arrays of asks, bids and timestamp -func (l *Lbank) GetMarketDepths(ctx context.Context, symbol string, size uint64) (*MarketDepthResponse, error) { +func (e *Exchange) GetMarketDepths(ctx context.Context, symbol string, size uint64) (*MarketDepthResponse, error) { var m MarketDepthResponse params := url.Values{} params.Set("symbol", symbol) params.Set("size", strconv.FormatUint(size, 10)) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion2, lbankMarketDepths, params.Encode()) - return &m, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &m) + return &m, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &m) } // GetTrades returns an array of available trades regarding a particular exchange // The time parameter is optional, if provided it will return trades after the given time -func (l *Lbank) GetTrades(ctx context.Context, symbol string, limit uint64, tm time.Time) ([]TradeResponse, error) { +func (e *Exchange) GetTrades(ctx context.Context, symbol string, limit uint64, tm time.Time) ([]TradeResponse, error) { var g []TradeResponse params := url.Values{} params.Set("symbol", symbol) @@ -133,11 +133,11 @@ func (l *Lbank) GetTrades(ctx context.Context, symbol string, limit uint64, tm t params.Set("time", strconv.FormatInt(tm.Unix(), 10)) } path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion1, lbankTrades, params.Encode()) - return g, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &g) + return g, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &g) } // GetKlines returns kline data -func (l *Lbank) GetKlines(ctx context.Context, symbol, size, klineType string, tm time.Time) ([]KlineResponse, error) { +func (e *Exchange) GetKlines(ctx context.Context, symbol, size, klineType string, tm time.Time) ([]KlineResponse, error) { var klineTemp [][]float64 params := url.Values{} params.Set("symbol", symbol) @@ -145,7 +145,7 @@ func (l *Lbank) GetKlines(ctx context.Context, symbol, size, klineType string, t params.Set("type", klineType) params.Set("time", strconv.FormatInt(tm.Unix(), 10)) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion1, lbankKlines, params.Encode()) - err := l.SendHTTPRequest(ctx, exchange.RestSpot, path, &klineTemp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &klineTemp) if err != nil { return nil, err } @@ -168,10 +168,10 @@ func (l *Lbank) GetKlines(ctx context.Context, symbol, size, klineType string, t } // GetUserInfo gets users account info -func (l *Lbank) GetUserInfo(ctx context.Context) (InfoFinalResponse, error) { +func (e *Exchange) GetUserInfo(ctx context.Context) (InfoFinalResponse, error) { var resp InfoFinalResponse path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankUserInfo) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, nil, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, nil, &resp) if err != nil { return resp, err } @@ -184,7 +184,7 @@ func (l *Lbank) GetUserInfo(ctx context.Context) (InfoFinalResponse, error) { } // CreateOrder creates an order -func (l *Lbank) CreateOrder(ctx context.Context, pair, side string, amount, price float64) (CreateOrderResponse, error) { +func (e *Exchange) CreateOrder(ctx context.Context, pair, side string, amount, price float64) (CreateOrderResponse, error) { var resp CreateOrderResponse if !strings.EqualFold(side, order.Buy.String()) && !strings.EqualFold(side, order.Sell.String()) { return resp, order.ErrSideIsInvalid @@ -202,7 +202,7 @@ func (l *Lbank) CreateOrder(ctx context.Context, pair, side string, amount, pric params.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankPlaceOrder) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -215,13 +215,13 @@ func (l *Lbank) CreateOrder(ctx context.Context, pair, side string, amount, pric } // RemoveOrder cancels a given order -func (l *Lbank) RemoveOrder(ctx context.Context, pair, orderID string) (RemoveOrderResponse, error) { +func (e *Exchange) RemoveOrder(ctx context.Context, pair, orderID string) (RemoveOrderResponse, error) { var resp RemoveOrderResponse params := url.Values{} params.Set("symbol", pair) params.Set("order_id", orderID) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankCancelOrder) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -235,14 +235,14 @@ func (l *Lbank) RemoveOrder(ctx context.Context, pair, orderID string) (RemoveOr // QueryOrder finds out information about orders (can pass up to 3 comma separated values to this) // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) QueryOrder(ctx context.Context, pair, orderIDs string) (QueryOrderFinalResponse, error) { +func (e *Exchange) QueryOrder(ctx context.Context, pair, orderIDs string) (QueryOrderFinalResponse, error) { var resp QueryOrderFinalResponse var tempResp QueryOrderResponse params := url.Values{} params.Set("symbol", pair) params.Set("order_id", orderIDs) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankQueryOrder) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -270,7 +270,7 @@ func (l *Lbank) QueryOrder(ctx context.Context, pair, orderIDs string) (QueryOrd // QueryOrderHistory finds order info in the past 2 days // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) QueryOrderHistory(ctx context.Context, pair, pageNumber, pageLength string) (OrderHistoryFinalResponse, error) { +func (e *Exchange) QueryOrderHistory(ctx context.Context, pair, pageNumber, pageLength string) (OrderHistoryFinalResponse, error) { var resp OrderHistoryFinalResponse var tempResp OrderHistoryResponse params := url.Values{} @@ -278,7 +278,7 @@ func (l *Lbank) QueryOrderHistory(ctx context.Context, pair, pageNumber, pageLen params.Set("current_page", pageNumber) params.Set("page_length", pageLength) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankQueryHistoryOrder) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -303,20 +303,20 @@ func (l *Lbank) QueryOrderHistory(ctx context.Context, pair, pageNumber, pageLen } // GetPairInfo finds information about all trading pairs -func (l *Lbank) GetPairInfo(ctx context.Context) ([]PairInfoResponse, error) { +func (e *Exchange) GetPairInfo(ctx context.Context) ([]PairInfoResponse, error) { var resp []PairInfoResponse path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankPairInfo) - return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // OrderTransactionDetails gets info about transactions -func (l *Lbank) OrderTransactionDetails(ctx context.Context, symbol, orderID string) (TransactionHistoryResp, error) { +func (e *Exchange) OrderTransactionDetails(ctx context.Context, symbol, orderID string) (TransactionHistoryResp, error) { var resp TransactionHistoryResp params := url.Values{} params.Set("symbol", symbol) params.Set("order_id", orderID) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankOrderTransactionDetails) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -329,7 +329,7 @@ func (l *Lbank) OrderTransactionDetails(ctx context.Context, symbol, orderID str } // TransactionHistory stores info about transactions -func (l *Lbank) TransactionHistory(ctx context.Context, symbol, transactionType, startDate, endDate, from, direct, size string) (TransactionHistoryResp, error) { +func (e *Exchange) TransactionHistory(ctx context.Context, symbol, transactionType, startDate, endDate, from, direct, size string) (TransactionHistoryResp, error) { var resp TransactionHistoryResp params := url.Values{} params.Set("symbol", symbol) @@ -340,7 +340,7 @@ func (l *Lbank) TransactionHistory(ctx context.Context, symbol, transactionType, params.Set("direct", direct) params.Set("size", size) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankPastTransactions) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -354,7 +354,7 @@ func (l *Lbank) TransactionHistory(ctx context.Context, symbol, transactionType, // GetOpenOrders gets opening orders // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) GetOpenOrders(ctx context.Context, pair, pageNumber, pageLength string) (OpenOrderFinalResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, pair, pageNumber, pageLength string) (OpenOrderFinalResponse, error) { var resp OpenOrderFinalResponse var tempResp OpenOrderResponse params := url.Values{} @@ -362,7 +362,7 @@ func (l *Lbank) GetOpenOrders(ctx context.Context, pair, pageNumber, pageLength params.Set("current_page", pageNumber) params.Set("page_length", pageLength) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankOpeningOrders) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -387,23 +387,23 @@ func (l *Lbank) GetOpenOrders(ctx context.Context, pair, pageNumber, pageLength } // USD2RMBRate finds USD-CNY Rate -func (l *Lbank) USD2RMBRate(ctx context.Context) (ExchangeRateResponse, error) { +func (e *Exchange) USD2RMBRate(ctx context.Context) (ExchangeRateResponse, error) { var resp ExchangeRateResponse path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankUSD2CNYRate) - return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetWithdrawConfig gets information about withdrawals -func (l *Lbank) GetWithdrawConfig(ctx context.Context, c currency.Code) ([]WithdrawConfigResponse, error) { +func (e *Exchange) GetWithdrawConfig(ctx context.Context, c currency.Code) ([]WithdrawConfigResponse, error) { var resp []WithdrawConfigResponse params := url.Values{} params.Set("assetCode", c.Lower().String()) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion1, lbankWithdrawConfig, params.Encode()) - return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // Withdraw sends a withdrawal request -func (l *Lbank) Withdraw(ctx context.Context, account, assetCode, amount, memo, mark, withdrawType string) (WithdrawResponse, error) { +func (e *Exchange) Withdraw(ctx context.Context, account, assetCode, amount, memo, mark, withdrawType string) (WithdrawResponse, error) { var resp WithdrawResponse params := url.Values{} params.Set("account", account) @@ -420,7 +420,7 @@ func (l *Lbank) Withdraw(ctx context.Context, account, assetCode, amount, memo, } path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankWithdraw) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -433,14 +433,14 @@ func (l *Lbank) Withdraw(ctx context.Context, account, assetCode, amount, memo, } // RevokeWithdraw cancels the withdrawal given the withdrawalID -func (l *Lbank) RevokeWithdraw(ctx context.Context, withdrawID string) (RevokeWithdrawResponse, error) { +func (e *Exchange) RevokeWithdraw(ctx context.Context, withdrawID string) (RevokeWithdrawResponse, error) { var resp RevokeWithdrawResponse params := url.Values{} if withdrawID != "" { params.Set("withdrawId", withdrawID) } path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion1, lbankRevokeWithdraw) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -453,7 +453,7 @@ func (l *Lbank) RevokeWithdraw(ctx context.Context, withdrawID string) (RevokeWi } // GetWithdrawalRecords gets withdrawal records -func (l *Lbank) GetWithdrawalRecords(ctx context.Context, assetCode string, pageNo, status, pageSize int64) (WithdrawalResponse, error) { +func (e *Exchange) GetWithdrawalRecords(ctx context.Context, assetCode string, pageNo, status, pageSize int64) (WithdrawalResponse, error) { var resp WithdrawalResponse params := url.Values{} params.Set("assetCode", assetCode) @@ -461,7 +461,7 @@ func (l *Lbank) GetWithdrawalRecords(ctx context.Context, assetCode string, page params.Set("pageNo", strconv.FormatInt(pageNo, 10)) params.Set("pageSize", strconv.FormatInt(pageSize, 10)) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion1, lbankWithdrawalRecords) - err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) + err := e.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -483,8 +483,8 @@ func ErrorCapture(code int64) error { } // SendHTTPRequest sends an unauthenticated HTTP request -func (l *Lbank) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := l.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -493,18 +493,18 @@ func (l *Lbank) SendHTTPRequest(ctx context.Context, ep exchange.URL, path strin Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: l.Verbose, - HTTPDebugging: l.HTTPDebugging, - HTTPRecording: l.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return l.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } -func (l *Lbank) loadPrivKey(ctx context.Context) error { - creds, err := l.GetCredentials(ctx) +func (e *Exchange) loadPrivKey(ctx context.Context) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -525,20 +525,20 @@ func (l *Lbank) loadPrivKey(ctx context.Context) error { } var ok bool - l.privateKey, ok = p.(*rsa.PrivateKey) + e.privateKey, ok = p.(*rsa.PrivateKey) if !ok { return common.GetTypeAssertError("*rsa.PrivateKey", p) } return nil } -func (l *Lbank) sign(data string) (string, error) { - if l.privateKey == nil { +func (e *Exchange) sign(data string) (string, error) { + if e.privateKey == nil { return "", errPrivateKeyNotLoaded } md5sum := md5.Sum([]byte(data)) //nolint:gosec // Used for this exchange shasum := sha256.Sum256([]byte(strings.ToUpper(hex.EncodeToString(md5sum[:])))) - r, err := rsa.SignPKCS1v15(rand.Reader, l.privateKey, crypto.SHA256, shasum[:]) + r, err := rsa.SignPKCS1v15(rand.Reader, e.privateKey, crypto.SHA256, shasum[:]) if err != nil { return "", err } @@ -546,8 +546,8 @@ func (l *Lbank) sign(data string) (string, error) { } // SendAuthHTTPRequest sends an authenticated request -func (l *Lbank) SendAuthHTTPRequest(ctx context.Context, method, endpoint string, vals url.Values, result any) error { - creds, err := l.GetCredentials(ctx) +func (e *Exchange) SendAuthHTTPRequest(ctx context.Context, method, endpoint string, vals url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -557,7 +557,7 @@ func (l *Lbank) SendAuthHTTPRequest(ctx context.Context, method, endpoint string } vals.Set("api_key", creds.Key) - sig, err := l.sign(vals.Encode()) + sig, err := e.sign(vals.Encode()) if err != nil { return err } @@ -572,12 +572,12 @@ func (l *Lbank) SendAuthHTTPRequest(ctx context.Context, method, endpoint string Path: endpoint, Headers: headers, Result: result, - Verbose: l.Verbose, - HTTPDebugging: l.HTTPDebugging, - HTTPRecording: l.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return l.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { item.Body = bytes.NewBufferString(payload) return item, nil }, request.AuthenticatedRequest) diff --git a/exchanges/lbank/lbank_test.go b/exchanges/lbank/lbank_test.go index 2cf61fcde71..be2aa04273d 100644 --- a/exchanges/lbank/lbank_test.go +++ b/exchanges/lbank/lbank_test.go @@ -38,51 +38,51 @@ const ( ) var ( - l = &Lbank{} + e *Exchange testPair = currency.NewBTCUSDT().Format(currency.PairFormat{Delimiter: "_"}) ) func TestMain(m *testing.M) { - l = new(Lbank) - if err := testexch.Setup(l); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Lbank Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - l.API.AuthenticatedSupport = true - l.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) } func TestGetTicker(t *testing.T) { t.Parallel() - _, err := l.GetTicker(t.Context(), testPair.String()) + _, err := e.GetTicker(t.Context(), testPair.String()) assert.NoError(t, err, "GetTicker should not error") } func TestGetTimestamp(t *testing.T) { t.Parallel() - ts, err := l.GetTimestamp(t.Context()) + ts, err := e.GetTimestamp(t.Context()) require.NoError(t, err, "GetTimestamp must not error") assert.NotZero(t, ts, "GetTimestamp should return a non-zero time") } func TestGetTickers(t *testing.T) { t.Parallel() - tickers, err := l.GetTickers(t.Context()) + tickers, err := e.GetTickers(t.Context()) require.NoError(t, err, "GetTickers must not error") assert.Greater(t, len(tickers), 1, "GetTickers should return more than 1 ticker") } func TestGetCurrencyPairs(t *testing.T) { t.Parallel() - _, err := l.GetCurrencyPairs(t.Context()) + _, err := e.GetCurrencyPairs(t.Context()) assert.NoError(t, err, "GetCurrencyPairs should not error") } func TestGetMarketDepths(t *testing.T) { t.Parallel() - d, err := l.GetMarketDepths(t.Context(), testPair.String(), 4) + d, err := e.GetMarketDepths(t.Context(), testPair.String(), 4) require.NoError(t, err, "GetMarketDepths must not error") require.NotEmpty(t, d, "GetMarketDepths must return a non-empty response") assert.Len(t, d.Data.Asks, 4, "GetMarketDepths should return 4 asks") @@ -90,7 +90,7 @@ func TestGetMarketDepths(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - r, err := l.GetTrades(t.Context(), testPair.String(), 420, time.Now()) + r, err := e.GetTrades(t.Context(), testPair.String(), 420, time.Now()) require.NoError(t, err, "GetTrades must not error") require.NotEmpty(t, r, "GetTrades must return a non-empty response") assert.Len(t, r, 420, "GetTrades should return 420 trades") @@ -98,199 +98,199 @@ func TestGetTrades(t *testing.T) { func TestGetKlines(t *testing.T) { t.Parallel() - _, err := l.GetKlines(t.Context(), testPair.String(), "600", "minute1", time.Now()) + _, err := e.GetKlines(t.Context(), testPair.String(), "600", "minute1", time.Now()) assert.NoError(t, err, "GetKlines should not error") } func TestUpdateOrderbook(t *testing.T) { t.Parallel() - _, err := l.UpdateOrderbook(t.Context(), currency.EMPTYPAIR, asset.Spot) + _, err := e.UpdateOrderbook(t.Context(), currency.EMPTYPAIR, asset.Spot) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = l.UpdateOrderbook(t.Context(), testPair, asset.Options) + _, err = e.UpdateOrderbook(t.Context(), testPair, asset.Options) assert.ErrorIs(t, err, asset.ErrNotSupported) - _, err = l.UpdateOrderbook(t.Context(), testPair, asset.Spot) + _, err = e.UpdateOrderbook(t.Context(), testPair, asset.Spot) assert.NoError(t, err, "UpdateOrderbook should not error") } func TestGetUserInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetUserInfo(t.Context()) + _, err := e.GetUserInfo(t.Context()) require.NoError(t, err, "GetUserInfo must not error") } func TestCreateOrder(t *testing.T) { t.Parallel() - _, err := l.CreateOrder(t.Context(), testPair.String(), "what", 1231, 12314) + _, err := e.CreateOrder(t.Context(), testPair.String(), "what", 1231, 12314) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = l.CreateOrder(t.Context(), testPair.String(), order.Buy.String(), 0, 0) + _, err = e.CreateOrder(t.Context(), testPair.String(), order.Buy.String(), 0, 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = l.CreateOrder(t.Context(), testPair.String(), order.Sell.String(), 1231, 0) + _, err = e.CreateOrder(t.Context(), testPair.String(), order.Sell.String(), 1231, 0) require.ErrorIs(t, err, order.ErrPriceBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, l, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err = l.CreateOrder(t.Context(), testPair.String(), order.Buy.String(), 58, 681) + _, err = e.CreateOrder(t.Context(), testPair.String(), order.Buy.String(), 58, 681) assert.NoError(t, err, "CreateOrder should not error") } func TestRemoveOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := l.RemoveOrder(t.Context(), testPair.String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") + _, err := e.RemoveOrder(t.Context(), testPair.String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") assert.NoError(t, err, "RemoveOrder should not error") } func TestQueryOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.QueryOrder(t.Context(), testPair.String(), "1") + _, err := e.QueryOrder(t.Context(), testPair.String(), "1") assert.NoError(t, err, "QueryOrder should not error") } func TestQueryOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.QueryOrderHistory(t.Context(), testPair.String(), "1", "100") + _, err := e.QueryOrderHistory(t.Context(), testPair.String(), "1", "100") assert.NoError(t, err, "QueryOrderHistory should not error") } func TestGetPairInfo(t *testing.T) { t.Parallel() - _, err := l.GetPairInfo(t.Context()) + _, err := e.GetPairInfo(t.Context()) assert.NoError(t, err, "GetPairInfo should not error") } func TestOrderTransactionDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.OrderTransactionDetails(t.Context(), testPair.String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") + _, err := e.OrderTransactionDetails(t.Context(), testPair.String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") assert.NoError(t, err, "OrderTransactionDetails should not error") } func TestTransactionHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.TransactionHistory(t.Context(), testPair.String(), "", "", "", "", "", "") + _, err := e.TransactionHistory(t.Context(), testPair.String(), "", "", "", "", "", "") assert.NoError(t, err, "TransactionHistory should not error") } func TestGetOpenOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetOpenOrders(t.Context(), testPair.String(), "1", "50") + _, err := e.GetOpenOrders(t.Context(), testPair.String(), "1", "50") assert.NoError(t, err, "GetOpenOrders should not error") } func TestUSD2RMBRate(t *testing.T) { t.Parallel() - _, err := l.USD2RMBRate(t.Context()) + _, err := e.USD2RMBRate(t.Context()) assert.NoError(t, err, "USD2RMBRate should not error") } func TestGetWithdrawConfig(t *testing.T) { t.Parallel() - c, err := l.GetWithdrawConfig(t.Context(), currency.ETH) + c, err := e.GetWithdrawConfig(t.Context(), currency.ETH) require.NoError(t, err, "GetWithdrawConfig must not error") assert.NotEmpty(t, c) } func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - _, err := l.Withdraw(t.Context(), "", "", "", "", "", "") + _, err := e.Withdraw(t.Context(), "", "", "", "", "", "") require.NoError(t, err, "Withdraw must not error") } func TestGetWithdrawRecords(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetWithdrawalRecords(t.Context(), currency.ETH.String(), 0, 1, 20) + _, err := e.GetWithdrawalRecords(t.Context(), currency.ETH.String(), 0, 1, 20) assert.NoError(t, err, "GetWithdrawRecords should not error") } func TestLoadPrivKey(t *testing.T) { t.Parallel() - l2 := new(Lbank) - l2.SetDefaults() - require.ErrorIs(t, l2.loadPrivKey(t.Context()), exchange.ErrCredentialsAreEmpty) + e := new(Exchange) //nolint:govet // Intentional shadow + e.SetDefaults() + require.ErrorIs(t, e.loadPrivKey(t.Context()), exchange.ErrCredentialsAreEmpty) ctx := account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: "errortest"}) - assert.ErrorIs(t, l2.loadPrivKey(ctx), errPEMBlockIsNil) + assert.ErrorIs(t, e.loadPrivKey(ctx), errPEMBlockIsNil) key, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) der := x509.MarshalPKCS1PrivateKey(key) ctx = account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: base64.StdEncoding.EncodeToString(der)}) - require.ErrorIs(t, l2.loadPrivKey(ctx), errUnableToParsePrivateKey) + require.ErrorIs(t, e.loadPrivKey(ctx), errUnableToParsePrivateKey) ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) der, err = x509.MarshalPKCS8PrivateKey(ecdsaKey) require.NoError(t, err) ctx = account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: base64.StdEncoding.EncodeToString(der)}) - require.ErrorIs(t, l2.loadPrivKey(ctx), common.ErrTypeAssertFailure) + require.ErrorIs(t, e.loadPrivKey(ctx), common.ErrTypeAssertFailure) key, err = rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) der, err = x509.MarshalPKCS8PrivateKey(key) require.NoError(t, err) ctx = account.DeployCredentialsToContext(t.Context(), &account.Credentials{Key: "test", Secret: base64.StdEncoding.EncodeToString(der)}) - assert.NoError(t, l2.loadPrivKey(ctx), "loadPrivKey should not error") + assert.NoError(t, e.loadPrivKey(ctx), "loadPrivKey should not error") - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - assert.NoError(t, l.loadPrivKey(t.Context()), "loadPrivKey should not error") + assert.NoError(t, e.loadPrivKey(t.Context()), "loadPrivKey should not error") } func TestSign(t *testing.T) { t.Parallel() - l2 := new(Lbank) - l2.SetDefaults() - _, err := l2.sign("hello123") + e := new(Exchange) //nolint:govet // Intentional shadow + e.SetDefaults() + _, err := e.sign("hello123") require.ErrorIs(t, err, errPrivateKeyNotLoaded) key, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err, "GenerateKey must not error") - l2.privateKey = key + e.privateKey = key targetMessage := "hello123" - msg, err := l2.sign(targetMessage) + msg, err := e.sign(targetMessage) require.NoError(t, err, "sign must not error") md5sum := md5.Sum([]byte(targetMessage)) //nolint:gosec // Used for this exchange shasum := sha256.Sum256([]byte(strings.ToUpper(hex.EncodeToString(md5sum[:])))) sigBytes, err := base64.StdEncoding.DecodeString(msg) require.NoError(t, err) - err = rsa.VerifyPKCS1v15(&l2.privateKey.PublicKey, crypto.SHA256, shasum[:], sigBytes) + err = rsa.VerifyPKCS1v15(&e.privateKey.PublicKey, crypto.SHA256, shasum[:], sigBytes) require.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - require.NoError(t, l.loadPrivKey(t.Context()), "loadPrivKey must not error") + require.NoError(t, e.loadPrivKey(t.Context()), "loadPrivKey must not error") - _, err = l.sign("hello123") + _, err = e.sign("hello123") assert.NoError(t, err, "sign should not error") } func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, l, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - r, err := l.SubmitOrder(t.Context(), &order.Submit{ - Exchange: l.Name, + r, err := e.SubmitOrder(t.Context(), &order.Submit{ + Exchange: e.Name, Pair: testPair, Side: order.Buy, Type: order.Limit, @@ -299,7 +299,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, }) - if sharedtestvalues.AreAPICredentialsSet(l) { + if sharedtestvalues.AreAPICredentialsSet(e) { require.NoError(t, err, "SubmitOrder must not error") assert.Equal(t, order.New, r.Status, "SubmitOrder should return order status New") } else { @@ -309,9 +309,9 @@ func TestSubmitOrder(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - err := l.CancelOrder(t.Context(), &order.Cancel{ + err := e.CancelOrder(t.Context(), &order.Cancel{ Pair: testPair, AssetType: asset.Spot, OrderID: "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23", @@ -321,23 +321,23 @@ func TestCancelOrder(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetOrderInfo(t.Context(), "9ead39f5-701a-400b-b635-d7349eb0f6b", currency.EMPTYPAIR, asset.Spot) + _, err := e.GetOrderInfo(t.Context(), "9ead39f5-701a-400b-b635-d7349eb0f6b", currency.EMPTYPAIR, asset.Spot) assert.NoError(t, err, "GetOrderInfo should not error") } func TestGetAllOpenOrderID(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.getAllOpenOrderID(t.Context()) + _, err := e.getAllOpenOrderID(t.Context()) assert.NoError(t, err, "getAllOpenOrderID should not error") } func TestGetFeeByType(t *testing.T) { t.Parallel() - _, err := l.GetFeeByType(t.Context(), &exchange.FeeBuilder{ + _, err := e.GetFeeByType(t.Context(), &exchange.FeeBuilder{ Amount: 2, FeeType: exchange.CryptocurrencyWithdrawalFee, Pair: testPair, @@ -347,17 +347,17 @@ func TestGetFeeByType(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) assert.NoError(t, err, "UpdateAccountInfo should not error") } func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ + _, err := e.GetActiveOrders(t.Context(), &order.MultiOrderRequest{ Side: order.AnySide, AssetType: asset.Spot, Type: order.AnyType, @@ -367,9 +367,9 @@ func TestGetActiveOrders(t *testing.T) { func TestGetOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ + _, err := e.GetOrderHistory(t.Context(), &order.MultiOrderRequest{ Side: order.AnySide, AssetType: asset.Spot, Type: order.AnyType, @@ -379,15 +379,15 @@ func TestGetOrderHistory(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() - _, err := l.GetHistoricCandles(t.Context(), currency.EMPTYPAIR, asset.Spot, kline.OneMin, time.Time{}, time.Time{}) + _, err := e.GetHistoricCandles(t.Context(), currency.EMPTYPAIR, asset.Spot, kline.OneMin, time.Time{}, time.Time{}) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = l.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneMin, time.Now().Add(-24*time.Hour), time.Now()) + _, err = e.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneMin, time.Now().Add(-24*time.Hour), time.Now()) assert.NoError(t, err, "GetHistoricCandles should not error") } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - _, err := l.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Minute*2), time.Now()) + _, err := e.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Minute*2), time.Now()) assert.NoError(t, err, "GetHistoricCandlesExtended should not error") } @@ -420,7 +420,7 @@ func TestFormatExchangeKlineInterval(t *testing.T) { } { t.Run(tc.interval.String(), func(t *testing.T) { t.Parallel() - ret := l.FormatExchangeKlineInterval(tc.interval) + ret := e.FormatExchangeKlineInterval(tc.interval) assert.Equalf(t, tc.output, ret, "FormatExchangeKlineInterval(%s) should return %q", tc.interval, tc.output) }) } @@ -428,29 +428,29 @@ func TestFormatExchangeKlineInterval(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := l.GetRecentTrades(t.Context(), testPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), testPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades should not error") } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := l.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().AddDate(69, 0, 0), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().AddDate(69, 0, 0), time.Now()) assert.ErrorIs(t, err, common.ErrStartAfterEnd) - _, err = l.GetHistoricTrades(t.Context(), currency.EMPTYPAIR, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = e.GetHistoricTrades(t.Context(), currency.EMPTYPAIR, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) - _, err = l.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.NoError(t, err, "GetHistoricTrades should not error") } func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := l.UpdateTicker(t.Context(), testPair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), testPair, asset.Spot) assert.NoError(t, err, "UpdateTicker should not error") } func TestUpdateTickers(t *testing.T) { t.Parallel() - err := l.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) assert.NoError(t, err, "UpdateTickers should not error") } @@ -469,34 +469,34 @@ func TestGetStatus(t *testing.T) { } { t.Run(tt.resp.String(), func(t *testing.T) { t.Parallel() - assert.Equalf(t, tt.resp.String(), l.GetStatus(tt.status).String(), "GetStatus(%d) should return %s", tt.status, tt.resp) + assert.Equalf(t, tt.resp.String(), e.GetStatus(tt.status).String(), "GetStatus(%d) should return %s", tt.status, tt.resp) }) } } func TestGetServerTime(t *testing.T) { t.Parallel() - ts, err := l.GetServerTime(t.Context(), asset.Spot) + ts, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err, "GetServerTime must not error") assert.NotZero(t, ts, "GetServerTime should return a non-zero time") } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, l) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := l.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) assert.NoError(t, err, "GetWithdrawalsHistory should not error") } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, l) - for _, a := range l.GetAssetTypes(false) { - pairs, err := l.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "GetPairs must not error for asset %s", a) require.NotEmptyf(t, pairs, "GetPairs for asset %s must return pairs", a) - resp, err := l.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/lbank/lbank_wrapper.go b/exchanges/lbank/lbank_wrapper.go index 62d93f0dbf8..c61d899912a 100644 --- a/exchanges/lbank/lbank_wrapper.go +++ b/exchanges/lbank/lbank_wrapper.go @@ -29,21 +29,21 @@ import ( ) // SetDefaults sets the basic defaults for Lbank -func (l *Lbank) SetDefaults() { - l.Name = "Lbank" - l.Enabled = true - l.Verbose = true - l.API.CredentialsValidator.RequiresKey = true - l.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Lbank" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter} configFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter} - err := l.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - l.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, RESTCapabilities: protocol.Features{ @@ -92,13 +92,13 @@ func (l *Lbank) SetDefaults() { }, }, } - l.Requester, err = request.New(l.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout)) if err != nil { log.Errorln(log.ExchangeSys, err) } - l.API.Endpoints = l.NewEndpoints() - err = l.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: lbankAPIURL, }) if err != nil { @@ -107,33 +107,33 @@ func (l *Lbank) SetDefaults() { } // Setup sets exchange configuration profile -func (l *Lbank) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - l.SetEnabled(false) + e.SetEnabled(false) return nil } - err = l.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - if l.API.AuthenticatedSupport { - err = l.loadPrivKey(context.TODO()) + if e.API.AuthenticatedSupport { + err = e.loadPrivKey(context.TODO()) if err != nil { - l.API.AuthenticatedSupport = false - log.Errorf(log.ExchangeSys, "%s couldn't load private key, setting authenticated support to false", l.Name) + e.API.AuthenticatedSupport = false + log.Errorf(log.ExchangeSys, "%s couldn't load private key, setting authenticated support to false", e.Name) } } return nil } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (l *Lbank) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - currencies, err := l.GetCurrencyPairs(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + currencies, err := e.GetCurrencyPairs(ctx) if err != nil { return nil, err } @@ -142,25 +142,25 @@ func (l *Lbank) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency. // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (l *Lbank) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := l.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = l.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return l.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (l *Lbank) UpdateTickers(ctx context.Context, a asset.Item) error { - tickerInfo, err := l.GetTickers(ctx) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + tickerInfo, err := e.GetTickers(ctx) if err != nil { return err } - pairs, err := l.GetEnabledPairs(a) + pairs, err := e.GetEnabledPairs(a) if err != nil { return err } @@ -177,7 +177,7 @@ func (l *Lbank) UpdateTickers(ctx context.Context, a asset.Item) error { Volume: tickerInfo[j].Ticker.Volume, Pair: tickerInfo[j].Symbol, LastUpdated: tickerInfo[j].Timestamp.Time(), - ExchangeName: l.Name, + ExchangeName: e.Name, AssetType: a, }); err != nil { return err @@ -188,34 +188,34 @@ func (l *Lbank) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (l *Lbank) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := l.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(l.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { - if !l.SupportsAsset(assetType) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { + if !e.SupportsAsset(assetType) { return nil, fmt.Errorf("%w: %q", asset.ErrNotSupported, assetType) } - fPair, err := l.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - d, err := l.GetMarketDepths(ctx, fPair.String(), 60) + d, err := e.GetMarketDepths(ctx, fPair.String(), 60) if err != nil { return nil, err } book := &orderbook.Book{ - Exchange: l.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: l.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, Asks: make(orderbook.Levels, len(d.Data.Asks)), Bids: make(orderbook.Levels, len(d.Data.Bids)), } @@ -233,14 +233,14 @@ func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType return nil, err } - return orderbook.Get(l.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Lbank exchange -func (l *Lbank) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - data, err := l.GetUserInfo(ctx) + data, err := e.GetUserInfo(ctx) if err != nil { return info, err } @@ -261,9 +261,9 @@ func (l *Lbank) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac } info.Accounts = append(info.Accounts, acc) - info.Exchange = l.Name + info.Exchange = e.Name - creds, err := l.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -276,16 +276,16 @@ func (l *Lbank) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (l *Lbank) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (l *Lbank) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { - if err := l.CurrencyPairs.IsAssetEnabled(a); err != nil { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a asset.Item) ([]exchange.WithdrawalHistory, error) { + if err := e.CurrencyPairs.IsAssetEnabled(a); err != nil { return nil, err } - withdrawalRecords, err := l.GetWithdrawalRecords(ctx, c.String(), 1, 0, 100) + withdrawalRecords, err := e.GetWithdrawalRecords(ctx, c.String(), 1, 0, 100) if err != nil { return nil, err } @@ -308,17 +308,17 @@ func (l *Lbank) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a as } // GetRecentTrades returns the most recent trades for a currency and asset -func (l *Lbank) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return l.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (l *Lbank) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - p, err = l.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } @@ -328,7 +328,7 @@ func (l *Lbank) GetHistoricTrades(ctx context.Context, p currency.Pair, assetTyp allTrades: for { var tradeData []TradeResponse - tradeData, err = l.GetTrades(ctx, p.String(), limit, ts) + tradeData, err = e.GetTrades(ctx, p.String(), limit, ts) if err != nil { return nil, err } @@ -342,7 +342,7 @@ allTrades: side = order.Sell } resp = append(resp, trade.Data{ - Exchange: l.Name, + Exchange: e.Name, TID: tradeData[i].TID, CurrencyPair: p, AssetType: assetType, @@ -364,7 +364,7 @@ allTrades: } } - err = l.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -374,8 +374,8 @@ allTrades: } // SubmitOrder submits a new order -func (l *Lbank) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(l.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -385,12 +385,12 @@ func (l *Lbank) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit s.Side) } - fPair, err := l.FormatExchangeCurrency(s.Pair, asset.Spot) + fPair, err := e.FormatExchangeCurrency(s.Pair, asset.Spot) if err != nil { return nil, err } - tempResp, err := l.CreateOrder(ctx, + tempResp, err := e.CreateOrder(ctx, fPair.String(), s.Side.String(), s.Amount, @@ -403,41 +403,41 @@ func (l *Lbank) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *Lbank) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (l *Lbank) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - fPair, err := l.FormatExchangeCurrency(o.Pair, o.AssetType) + fPair, err := e.FormatExchangeCurrency(o.Pair, o.AssetType) if err != nil { return err } - _, err = l.RemoveOrder(ctx, fPair.String(), o.OrderID) + _, err = e.RemoveOrder(ctx, fPair.String(), o.OrderID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (l *Lbank) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (l *Lbank) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - return l.GetTimestamp(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + return e.GetTimestamp(ctx) } // CancelAllOrders cancels all orders associated with a currency pair -func (l *Lbank) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) { if err := o.Validate(); err != nil { return order.CancelAllResponse{}, err } var resp order.CancelAllResponse - orderIDs, err := l.getAllOpenOrderID(ctx) + orderIDs, err := e.getAllOpenOrderID(ctx) if err != nil { return resp, err } @@ -455,7 +455,7 @@ func (l *Lbank) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Can tempSlice = append(tempSlice, orderIDs[key][y]) if y%3 == 0 { input = strings.Join(tempSlice, ",") - CancelResponse, err2 := l.RemoveOrder(ctx, key, input) + CancelResponse, err2 := e.RemoveOrder(ctx, key, input) if err2 != nil { return resp, err2 } @@ -473,7 +473,7 @@ func (l *Lbank) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Can y++ } input = strings.Join(tempSlice, ",") - CancelResponse, err2 := l.RemoveOrder(ctx, key, input) + CancelResponse, err2 := e.RemoveOrder(ctx, key, input) if err2 != nil { return resp, err2 } @@ -492,9 +492,9 @@ func (l *Lbank) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.Can } // GetOrderInfo returns order information based on order ID -func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { var resp order.Detail - orderIDs, err := l.getAllOpenOrderID(ctx) + orderIDs, err := e.getAllOpenOrderID(ctx) if err != nil { return nil, err } @@ -504,11 +504,11 @@ func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pai if val[i] != orderID { continue } - tempResp, err := l.QueryOrder(ctx, key, orderID) + tempResp, err := e.QueryOrder(ctx, key, orderID) if err != nil { return nil, err } - resp.Exchange = l.Name + resp.Exchange = e.Name resp.Pair, err = currency.NewPairFromString(key) if err != nil { return nil, err @@ -520,12 +520,12 @@ func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pai resp.Side = order.Sell } - resp.Status = l.GetStatus(tempResp.Orders[0].Status) + resp.Status = e.GetStatus(tempResp.Orders[0].Status) resp.Price = tempResp.Orders[0].Price resp.Amount = tempResp.Orders[0].Amount resp.ExecutedAmount = tempResp.Orders[0].DealAmount resp.RemainingAmount = tempResp.Orders[0].Amount - tempResp.Orders[0].DealAmount - resp.Fee, err = l.GetFeeByType(ctx, &exchange.FeeBuilder{ + resp.Fee, err = e.GetFeeByType(ctx, &exchange.FeeBuilder{ FeeType: exchange.CryptocurrencyTradeFee, Amount: tempResp.Orders[0].Amount, PurchasePrice: tempResp.Orders[0].Price, @@ -539,17 +539,17 @@ func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pai } // GetDepositAddress returns a deposit address for a specified currency -func (l *Lbank) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(_ context.Context, _ currency.Code, _, _ string) (*deposit.Address, error) { return nil, common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := l.Withdraw(ctx, + resp, err := e.Withdraw(ctx, withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64), @@ -566,18 +566,18 @@ func (l *Lbank) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { err := getOrdersRequest.Validate() if err != nil { return nil, err @@ -585,18 +585,18 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Mul var finalResp []order.Detail var resp order.Detail - tempData, err := l.getAllOpenOrderID(ctx) + tempData, err := e.getAllOpenOrderID(ctx) if err != nil { return finalResp, err } for key, val := range tempData { for x := range val { - tempResp, err := l.QueryOrder(ctx, key, val[x]) + tempResp, err := e.QueryOrder(ctx, key, val[x]) if err != nil { return finalResp, err } - resp.Exchange = l.Name + resp.Exchange = e.Name resp.Pair, err = currency.NewPairFromString(key) if err != nil { return nil, err @@ -607,13 +607,13 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Mul } else { resp.Side = order.Sell } - resp.Status = l.GetStatus(tempResp.Orders[0].Status) + resp.Status = e.GetStatus(tempResp.Orders[0].Status) resp.Price = tempResp.Orders[0].Price resp.Amount = tempResp.Orders[0].Amount resp.Date = tempResp.Orders[0].CreateTime.Time() resp.ExecutedAmount = tempResp.Orders[0].DealAmount resp.RemainingAmount = tempResp.Orders[0].Amount - tempResp.Orders[0].DealAmount - resp.Fee, err = l.GetFeeByType(ctx, + resp.Fee, err = e.GetFeeByType(ctx, &exchange.FeeBuilder{ FeeType: exchange.CryptocurrencyTradeFee, Amount: tempResp.Orders[0].Amount, @@ -637,12 +637,12 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Mul } } } - return getOrdersRequest.Filter(l.Name, finalResp), nil + return getOrdersRequest.Filter(e.Name, finalResp), nil } // GetOrderHistory retrieves account order information * // Can Limit response to specific order status -func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, getOrdersRequest *order.MultiOrderRequest) (order.FilteredOrders, error) { err := getOrdersRequest.Validate() if err != nil { return nil, err @@ -653,7 +653,7 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mul var tempCurr currency.Pairs if len(getOrdersRequest.Pairs) == 0 { var err error - tempCurr, err = l.GetEnabledPairs(asset.Spot) + tempCurr, err = e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } @@ -661,25 +661,25 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mul tempCurr = getOrdersRequest.Pairs } for a := range tempCurr { - fPair, err := l.FormatExchangeCurrency(tempCurr[a], asset.Spot) + fPair, err := e.FormatExchangeCurrency(tempCurr[a], asset.Spot) if err != nil { return nil, err } b := int64(1) - tempResp, err := l.QueryOrderHistory(ctx, + tempResp, err := e.QueryOrderHistory(ctx, fPair.String(), strconv.FormatInt(b, 10), "200") if err != nil { return finalResp, err } for len(tempResp.Orders) != 0 { - tempResp, err = l.QueryOrderHistory(ctx, + tempResp, err = e.QueryOrderHistory(ctx, fPair.String(), strconv.FormatInt(b, 10), "200") if err != nil { return finalResp, err } for x := range tempResp.Orders { - resp.Exchange = l.Name + resp.Exchange = e.Name resp.Pair, err = currency.NewPairFromString(tempResp.Orders[x].Symbol) if err != nil { return nil, err @@ -690,14 +690,14 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mul } else { resp.Side = order.Sell } - resp.Status = l.GetStatus(tempResp.Orders[x].Status) + resp.Status = e.GetStatus(tempResp.Orders[x].Status) resp.Price = tempResp.Orders[x].Price resp.AverageExecutedPrice = tempResp.Orders[x].AvgPrice resp.Amount = tempResp.Orders[x].Amount resp.Date = tempResp.Orders[x].CreateTime.Time() resp.ExecutedAmount = tempResp.Orders[x].DealAmount resp.RemainingAmount = tempResp.Orders[x].Amount - tempResp.Orders[x].DealAmount - resp.Fee, err = l.GetFeeByType(ctx, + resp.Fee, err = e.GetFeeByType(ctx, &exchange.FeeBuilder{ FeeType: exchange.CryptocurrencyTradeFee, Amount: tempResp.Orders[x].Amount, @@ -712,11 +712,11 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mul } } } - return getOrdersRequest.Filter(l.Name, finalResp), nil + return getOrdersRequest.Filter(e.Name, finalResp), nil } // GetFeeByType returns an estimate of fee based on the type of transaction * -func (l *Lbank) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } @@ -725,7 +725,7 @@ func (l *Lbank) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilde return feeBuilder.Amount * feeBuilder.PurchasePrice * 0.002, nil } if feeBuilder.FeeType == exchange.CryptocurrencyWithdrawalFee { - withdrawalFee, err := l.GetWithdrawConfig(ctx, feeBuilder.Pair.Base) + withdrawalFee, err := e.GetWithdrawConfig(ctx, feeBuilder.Pair.Base) if err != nil { return resp, err } @@ -741,19 +741,19 @@ func (l *Lbank) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilde } // GetAllOpenOrderID returns all open orders by currency pairs -func (l *Lbank) getAllOpenOrderID(ctx context.Context) (map[string][]string, error) { - allPairs, err := l.GetEnabledPairs(asset.Spot) +func (e *Exchange) getAllOpenOrderID(ctx context.Context) (map[string][]string, error) { + allPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } resp := make(map[string][]string) for a := range allPairs { - fPair, err := l.FormatExchangeCurrency(allPairs[a], asset.Spot) + fPair, err := e.FormatExchangeCurrency(allPairs[a], asset.Spot) if err != nil { return nil, err } b := int64(1) - tempResp, err := l.GetOpenOrders(ctx, + tempResp, err := e.GetOpenOrders(ctx, fPair.String(), strconv.FormatInt(b, 10), "200") @@ -762,7 +762,7 @@ func (l *Lbank) getAllOpenOrderID(ctx context.Context) (map[string][]string, err } tempData := len(tempResp.Orders) for tempData != 0 { - tempResp, err = l.GetOpenOrders(ctx, + tempResp, err = e.GetOpenOrders(ctx, fPair.String(), strconv.FormatInt(b, 10), "200") @@ -786,13 +786,13 @@ func (l *Lbank) getAllOpenOrderID(ctx context.Context) (map[string][]string, err // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (l *Lbank) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := l.UpdateAccountInfo(ctx, assetType) - return l.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // FormatExchangeKlineInterval returns Interval to exchange formatted string -func (l *Lbank) FormatExchangeKlineInterval(in kline.Interval) string { +func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string { switch in { case kline.OneMin, kline.ThreeMin, kline.FiveMin, kline.FifteenMin, kline.ThirtyMin: @@ -809,16 +809,16 @@ func (l *Lbank) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (l *Lbank) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := l.GetKlineRequest(pair, a, interval, start, end, true) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, true) if err != nil { return nil, err } - data, err := l.GetKlines(ctx, + data, err := e.GetKlines(ctx, req.RequestFormatted.String(), strconv.FormatUint(req.RequestLimit, 10), - l.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), req.Start) if err != nil { return nil, err @@ -839,8 +839,8 @@ func (l *Lbank) GetHistoricCandles(ctx context.Context, pair currency.Pair, a as } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (l *Lbank) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := l.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -848,10 +848,10 @@ func (l *Lbank) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pa timeSeries := make([]kline.Candle, 0, req.Size()) for x := range req.RangeHolder.Ranges { var data []KlineResponse - data, err = l.GetKlines(ctx, + data, err = e.GetKlines(ctx, req.RequestFormatted.String(), strconv.FormatUint(req.RequestLimit, 10), - l.FormatExchangeKlineInterval(req.ExchangeInterval), + e.FormatExchangeKlineInterval(req.ExchangeInterval), req.RangeHolder.Ranges[x].Start.Time) if err != nil { return nil, err @@ -875,7 +875,7 @@ func (l *Lbank) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pa } // GetStatus returns the order.Status from the int representation. -func (l *Lbank) GetStatus(status int64) order.Status { +func (e *Exchange) GetStatus(status int64) order.Status { var oStatus order.Status switch status { case -1: @@ -894,29 +894,29 @@ func (l *Lbank) GetStatus(status int64) order.Status { // "Cancelling" oStatus = order.Cancelling default: - log.Errorf(log.Global, "%s Unhandled Order Status '%v'", l.GetName(), status) + log.Errorf(log.Global, "%s Unhandled Order Status '%v'", e.GetName(), status) } return oStatus } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (l *Lbank) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (l *Lbank) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (l *Lbank) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (l *Lbank) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := l.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/okx/helpers.go b/exchanges/okx/helpers.go index 2d940707c35..e5ad527728b 100644 --- a/exchanges/okx/helpers.go +++ b/exchanges/okx/helpers.go @@ -87,11 +87,11 @@ func orderTypeString(orderType order.Type, tif order.TimeInForce) (string, error // getAssetsFromInstrumentID parses an instrument ID and returns a list of assets types // that the instrument is associated with -func (ok *Okx) getAssetsFromInstrumentID(instrumentID string) ([]asset.Item, error) { +func (e *Exchange) getAssetsFromInstrumentID(instrumentID string) ([]asset.Item, error) { if instrumentID == "" { return nil, errMissingInstrumentID } - pf, err := ok.CurrencyPairs.GetFormat(asset.Spot, true) + pf, err := e.CurrencyPairs.GetFormat(asset.Spot, true) if err != nil { return nil, err } @@ -106,14 +106,14 @@ func (ok *Okx) getAssetsFromInstrumentID(instrumentID string) ([]asset.Item, err switch { case len(splitSymbol) == 2: resp := make([]asset.Item, 0, 2) - enabled, err := ok.IsPairEnabled(pair, asset.Spot) + enabled, err := e.IsPairEnabled(pair, asset.Spot) if err != nil { return nil, err } if enabled { resp = append(resp, asset.Spot) } - enabled, err = ok.IsPairEnabled(pair, asset.Margin) + enabled, err = e.IsPairEnabled(pair, asset.Margin) if err != nil { return nil, err } @@ -133,7 +133,7 @@ func (ok *Okx) getAssetsFromInstrumentID(instrumentID string) ([]asset.Item, err default: aType = asset.Futures } - enabled, err := ok.IsPairEnabled(pair, aType) + enabled, err := e.IsPairEnabled(pair, aType) if err != nil { return nil, err } else if enabled { diff --git a/exchanges/okx/okx.go b/exchanges/okx/okx.go index 8d9ecedcfdf..2b4bd44c6e7 100644 --- a/exchanges/okx/okx.go +++ b/exchanges/okx/okx.go @@ -28,8 +28,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/types" ) -// Okx is the overarching type across this package -type Okx struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Okx +type Exchange struct { exchange.Base messageIDSeq common.Counter @@ -51,12 +51,12 @@ const ( /************************************ MarketData Endpoints *************************************************/ // PlaceOrder places an order -func (ok *Okx) PlaceOrder(ctx context.Context, arg *PlaceOrderRequestParam) (*OrderData, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, arg *PlaceOrderRequestParam) (*OrderData, error) { if err := arg.Validate(); err != nil { return nil, err } var resp *OrderData - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, placeOrderEPL, http.MethodPost, "trade/order", &arg, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, placeOrderEPL, http.MethodPost, "trade/order", &arg, &resp, request.AuthenticatedRequest) if err != nil { if resp != nil && resp.StatusMessage != "" { return nil, fmt.Errorf("%w; %w", err, getStatusError(resp.StatusCode, resp.StatusMessage)) @@ -67,7 +67,7 @@ func (ok *Okx) PlaceOrder(ctx context.Context, arg *PlaceOrderRequestParam) (*Or } // PlaceMultipleOrders to place orders in batches. Maximum 20 orders can be placed at a time. Request parameters should be passed in the form of an array -func (ok *Okx) PlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequestParam) ([]OrderData, error) { +func (e *Exchange) PlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequestParam) ([]OrderData, error) { if len(args) == 0 { return nil, order.ErrSubmissionIsNil } @@ -77,7 +77,7 @@ func (ok *Okx) PlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequest } } var resp []OrderData - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, placeMultipleOrdersEPL, http.MethodPost, "trade/batch-orders", &args, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, placeMultipleOrdersEPL, http.MethodPost, "trade/batch-orders", &args, &resp, request.AuthenticatedRequest) if err != nil { if len(resp) == 0 { return nil, err @@ -92,7 +92,7 @@ func (ok *Okx) PlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequest } // CancelSingleOrder cancel an incomplete order -func (ok *Okx) CancelSingleOrder(ctx context.Context, arg *CancelOrderRequestParam) (*OrderData, error) { +func (e *Exchange) CancelSingleOrder(ctx context.Context, arg *CancelOrderRequestParam) (*OrderData, error) { if *arg == (CancelOrderRequestParam{}) { return nil, common.ErrEmptyParams } @@ -103,7 +103,7 @@ func (ok *Okx) CancelSingleOrder(ctx context.Context, arg *CancelOrderRequestPar return nil, order.ErrOrderIDNotSet } var resp *OrderData - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelOrderEPL, http.MethodPost, "trade/cancel-order", &arg, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, cancelOrderEPL, http.MethodPost, "trade/cancel-order", &arg, &resp, request.AuthenticatedRequest) if err != nil { if resp != nil && resp.StatusMessage != "" { return nil, fmt.Errorf("%w; %w", err, getStatusError(resp.StatusCode, resp.StatusMessage)) @@ -115,7 +115,7 @@ func (ok *Okx) CancelSingleOrder(ctx context.Context, arg *CancelOrderRequestPar // CancelMultipleOrders cancel incomplete orders in batches. Maximum 20 orders can be canceled at a time. // Request parameters should be passed in the form of an array -func (ok *Okx) CancelMultipleOrders(ctx context.Context, args []CancelOrderRequestParam) ([]*OrderData, error) { +func (e *Exchange) CancelMultipleOrders(ctx context.Context, args []CancelOrderRequestParam) ([]*OrderData, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } @@ -129,7 +129,7 @@ func (ok *Okx) CancelMultipleOrders(ctx context.Context, args []CancelOrderReque } } var resp []*OrderData - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleOrdersEPL, http.MethodPost, "trade/cancel-batch-orders", args, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleOrdersEPL, http.MethodPost, "trade/cancel-batch-orders", args, &resp, request.AuthenticatedRequest) if err != nil { if len(resp) == 0 { return nil, err @@ -146,7 +146,7 @@ func (ok *Okx) CancelMultipleOrders(ctx context.Context, args []CancelOrderReque } // AmendOrder an incomplete order -func (ok *Okx) AmendOrder(ctx context.Context, arg *AmendOrderRequestParams) (*OrderData, error) { +func (e *Exchange) AmendOrder(ctx context.Context, arg *AmendOrderRequestParams) (*OrderData, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -160,11 +160,11 @@ func (ok *Okx) AmendOrder(ctx context.Context, arg *AmendOrderRequestParams) (*O return nil, errInvalidNewSizeOrPriceInformation } var resp *OrderData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendOrderEPL, http.MethodPost, "trade/amend-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendOrderEPL, http.MethodPost, "trade/amend-order", arg, &resp, request.AuthenticatedRequest) } // AmendMultipleOrders amend incomplete orders in batches. Maximum 20 orders can be amended at a time. Request parameters should be passed in the form of an array -func (ok *Okx) AmendMultipleOrders(ctx context.Context, args []AmendOrderRequestParams) ([]OrderData, error) { +func (e *Exchange) AmendMultipleOrders(ctx context.Context, args []AmendOrderRequestParams) ([]OrderData, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } @@ -180,11 +180,11 @@ func (ok *Okx) AmendMultipleOrders(ctx context.Context, args []AmendOrderRequest } } var resp []OrderData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendMultipleOrdersEPL, http.MethodPost, "trade/amend-batch-orders", &args, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendMultipleOrdersEPL, http.MethodPost, "trade/amend-batch-orders", &args, &resp, request.AuthenticatedRequest) } // ClosePositions close all positions of an instrument via a market order -func (ok *Okx) ClosePositions(ctx context.Context, arg *ClosePositionsRequestParams) (*ClosePositionResponse, error) { +func (e *Exchange) ClosePositions(ctx context.Context, arg *ClosePositionsRequestParams) (*ClosePositionResponse, error) { if *arg == (ClosePositionsRequestParams{}) { return nil, common.ErrEmptyParams } @@ -197,11 +197,11 @@ func (ok *Okx) ClosePositions(ctx context.Context, arg *ClosePositionsRequestPar return nil, margin.ErrMarginTypeUnsupported } var resp *ClosePositionResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, closePositionEPL, http.MethodPost, "trade/close-position", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, closePositionEPL, http.MethodPost, "trade/close-position", arg, &resp, request.AuthenticatedRequest) } // GetOrderDetail retrieves order details given instrument id and order identification -func (ok *Okx) GetOrderDetail(ctx context.Context, arg *OrderDetailRequestParam) (*OrderDetail, error) { +func (e *Exchange) GetOrderDetail(ctx context.Context, arg *OrderDetailRequestParam) (*OrderDetail, error) { if *arg == (OrderDetailRequestParam{}) { return nil, common.ErrEmptyParams } @@ -219,11 +219,11 @@ func (ok *Okx) GetOrderDetail(ctx context.Context, arg *OrderDetailRequestParam) } params.Set("instId", arg.InstrumentID) var resp *OrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOrderDetEPL, http.MethodGet, common.EncodeURLValues("trade/order", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOrderDetEPL, http.MethodGet, common.EncodeURLValues("trade/order", params), nil, &resp, request.AuthenticatedRequest) } // GetOrderList retrieves all incomplete orders under the current account -func (ok *Okx) GetOrderList(ctx context.Context, arg *OrderListRequestParams) ([]OrderDetail, error) { +func (e *Exchange) GetOrderList(ctx context.Context, arg *OrderListRequestParams) ([]OrderDetail, error) { if *arg == (OrderListRequestParams{}) { return nil, common.ErrEmptyParams } @@ -253,21 +253,21 @@ func (ok *Okx) GetOrderList(ctx context.Context, arg *OrderListRequestParams) ([ params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp []OrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOrderListEPL, http.MethodGet, common.EncodeURLValues("trade/orders-pending", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOrderListEPL, http.MethodGet, common.EncodeURLValues("trade/orders-pending", params), nil, &resp, request.AuthenticatedRequest) } // Get7DayOrderHistory retrieves the completed order data for the last 7 days, and the incomplete orders that have been cancelled are only reserved for 2 hours -func (ok *Okx) Get7DayOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams) ([]OrderDetail, error) { - return ok.getOrderHistory(ctx, arg, "trade/orders-history", getOrderHistory7DaysEPL) +func (e *Exchange) Get7DayOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams) ([]OrderDetail, error) { + return e.getOrderHistory(ctx, arg, "trade/orders-history", getOrderHistory7DaysEPL) } // Get3MonthOrderHistory retrieves the completed order data for the last 7 days, and the incomplete orders that have been cancelled are only reserved for 2 hours -func (ok *Okx) Get3MonthOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams) ([]OrderDetail, error) { - return ok.getOrderHistory(ctx, arg, "trade/orders-history-archive", getOrderHistory3MonthsEPL) +func (e *Exchange) Get3MonthOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams) ([]OrderDetail, error) { + return e.getOrderHistory(ctx, arg, "trade/orders-history-archive", getOrderHistory3MonthsEPL) } // getOrderHistory retrieves the order history of the past limited times -func (ok *Okx) getOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams, route string, rateLimit request.EndpointLimit) ([]OrderDetail, error) { +func (e *Exchange) getOrderHistory(ctx context.Context, arg *OrderHistoryRequestParams, route string, rateLimit request.EndpointLimit) ([]OrderDetail, error) { if *arg == (OrderHistoryRequestParams{}) { return nil, common.ErrEmptyParams } @@ -307,21 +307,21 @@ func (ok *Okx) getOrderHistory(ctx context.Context, arg *OrderHistoryRequestPara params.Set("category", strings.ToLower(arg.Category)) } var resp []OrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) } // GetTransactionDetailsLast3Days retrieves recently-filled transaction details in the last 3 day -func (ok *Okx) GetTransactionDetailsLast3Days(ctx context.Context, arg *TransactionDetailRequestParams) ([]TransactionDetail, error) { - return ok.getTransactionDetails(ctx, arg, "trade/fills", getTransactionDetail3DaysEPL) +func (e *Exchange) GetTransactionDetailsLast3Days(ctx context.Context, arg *TransactionDetailRequestParams) ([]TransactionDetail, error) { + return e.getTransactionDetails(ctx, arg, "trade/fills", getTransactionDetail3DaysEPL) } // GetTransactionDetailsLast3Months retrieve recently-filled transaction details in the last 3 months -func (ok *Okx) GetTransactionDetailsLast3Months(ctx context.Context, arg *TransactionDetailRequestParams) ([]TransactionDetail, error) { - return ok.getTransactionDetails(ctx, arg, "trade/fills-history", getTransactionDetail3MonthsEPL) +func (e *Exchange) GetTransactionDetailsLast3Months(ctx context.Context, arg *TransactionDetailRequestParams) ([]TransactionDetail, error) { + return e.getTransactionDetails(ctx, arg, "trade/fills-history", getTransactionDetail3MonthsEPL) } // GetTransactionDetails retrieves recently-filled transaction details -func (ok *Okx) getTransactionDetails(ctx context.Context, arg *TransactionDetailRequestParams, route string, rateLimit request.EndpointLimit) ([]TransactionDetail, error) { +func (e *Exchange) getTransactionDetails(ctx context.Context, arg *TransactionDetailRequestParams, route string, rateLimit request.EndpointLimit) ([]TransactionDetail, error) { if *arg == (TransactionDetailRequestParams{}) { return nil, common.ErrEmptyParams } @@ -356,12 +356,12 @@ func (ok *Okx) getTransactionDetails(ctx context.Context, arg *TransactionDetail params.Set("before", arg.Before) } var resp []TransactionDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) } // PlaceAlgoOrder order includes trigger, oco, chase, conditional, iceberg, twap and trailing orders. // chase order only applicable to futures and swap orders -func (ok *Okx) PlaceAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -386,12 +386,12 @@ func (ok *Okx) PlaceAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoO return nil, order.ErrAmountBelowMin } var resp *AlgoOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeAlgoOrderEPL, http.MethodPost, "trade/order-algo", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeAlgoOrderEPL, http.MethodPost, "trade/order-algo", arg, &resp, request.AuthenticatedRequest) } // PlaceStopOrder places a stop order. // The order type should be "conditional" because stop orders are used for conditional take-profit or stop-loss scenarios. -func (ok *Okx) PlaceStopOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceStopOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -401,11 +401,11 @@ func (ok *Okx) PlaceStopOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoO if arg.TakeProfitTriggerPriceType == "" { return nil, order.ErrUnknownPriceType } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceTrailingStopOrder to place trailing stop order -func (ok *Okx) PlaceTrailingStopOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceTrailingStopOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -415,11 +415,11 @@ func (ok *Okx) PlaceTrailingStopOrder(ctx context.Context, arg *AlgoOrderParams) if arg.CallbackRatio == 0 && arg.CallbackSpreadVariance == 0 { return nil, fmt.Errorf(" %w \"callbackRatio\" or \"callbackSpread\" required", errPriceTrackingNotSet) } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceIcebergOrder to place iceberg algo order -func (ok *Okx) PlaceIcebergOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceIcebergOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -432,11 +432,11 @@ func (ok *Okx) PlaceIcebergOrder(ctx context.Context, arg *AlgoOrderParams) (*Al if arg.LimitPrice <= 0 { return nil, errInvalidPriceLimit } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceTWAPOrder to place TWAP algo orders -func (ok *Okx) PlaceTWAPOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceTWAPOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -452,13 +452,13 @@ func (ok *Okx) PlaceTWAPOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoO if IntervalFromString(arg.TimeInterval, true) == "" { return nil, errMissingIntervalValue } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceTakeProfitStopLossOrder places conditional and oco orders // When placing net TP/SL order (ordType=conditional) and both take-profit and stop-loss parameters are sent, // only stop-loss logic will be performed and take-profit logic will be ignored -func (ok *Okx) PlaceTakeProfitStopLossOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceTakeProfitStopLossOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -473,11 +473,11 @@ func (ok *Okx) PlaceTakeProfitStopLossOrder(ctx context.Context, arg *AlgoOrderP default: return nil, fmt.Errorf("%w, only 'last', 'index', and 'mark' are supported", order.ErrUnknownPriceType) } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceChaseAlgoOrder places an order that adjusts the price of an open limit order to match the current market price -func (ok *Okx) PlaceChaseAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceChaseAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -488,11 +488,11 @@ func (ok *Okx) PlaceChaseAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (* (arg.MaxChaseType != "" || arg.MaxChaseValue != 0) { return nil, fmt.Errorf("%w, either non or both MaxChaseType and MaxChaseValue has to be provided", errPriceTrackingNotSet) } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // PlaceTriggerAlgoOrder fetches algo trigger orders for SWAP market types -func (ok *Okx) PlaceTriggerAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { +func (e *Exchange) PlaceTriggerAlgoOrder(ctx context.Context, arg *AlgoOrderParams) (*AlgoOrder, error) { if *arg == (AlgoOrderParams{}) { return nil, common.ErrEmptyParams } @@ -507,31 +507,31 @@ func (ok *Okx) PlaceTriggerAlgoOrder(ctx context.Context, arg *AlgoOrderParams) default: return nil, fmt.Errorf("%w, only last, index and mark trigger price types are allowed", order.ErrUnknownPriceType) } - return ok.PlaceAlgoOrder(ctx, arg) + return e.PlaceAlgoOrder(ctx, arg) } // CancelAdvanceAlgoOrder Cancel unfilled algo orders // A maximum of 10 orders can be canceled at a time. // Request parameters should be passed in the form of an array -func (ok *Okx) CancelAdvanceAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams) (*AlgoOrder, error) { +func (e *Exchange) CancelAdvanceAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams) (*AlgoOrder, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } - return ok.cancelAlgoOrder(ctx, args, "trade/cancel-advance-algos", cancelAdvanceAlgoOrderEPL) + return e.cancelAlgoOrder(ctx, args, "trade/cancel-advance-algos", cancelAdvanceAlgoOrderEPL) } // CancelAlgoOrder to cancel unfilled algo orders (not including Iceberg order, TWAP order, Trailing Stop order). // A maximum of 10 orders can be canceled at a time. // Request parameters should be passed in the form of an array -func (ok *Okx) CancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams) (*AlgoOrder, error) { +func (e *Exchange) CancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams) (*AlgoOrder, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } - return ok.cancelAlgoOrder(ctx, args, "trade/cancel-algos", cancelAlgoOrderEPL) + return e.cancelAlgoOrder(ctx, args, "trade/cancel-algos", cancelAlgoOrderEPL) } // cancelAlgoOrder to cancel unfilled algo orders -func (ok *Okx) cancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams, route string, rateLimit request.EndpointLimit) (*AlgoOrder, error) { +func (e *Exchange) cancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams, route string, rateLimit request.EndpointLimit) (*AlgoOrder, error) { for x := range args { if args[x] == (AlgoOrderCancelParams{}) { return nil, common.ErrEmptyParams @@ -543,7 +543,7 @@ func (ok *Okx) cancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams } } var resp *AlgoOrder - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodPost, route, &args, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodPost, route, &args, &resp, request.AuthenticatedRequest) if err != nil { if resp != nil && resp.StatusMessage != "" { return nil, fmt.Errorf("%w; %w", err, getStatusError(resp.StatusCode, resp.StatusMessage)) @@ -555,7 +555,7 @@ func (ok *Okx) cancelAlgoOrder(ctx context.Context, args []AlgoOrderCancelParams // AmendAlgoOrder amend unfilled algo orders (Support stop order only, not including Move_order_stop order, Trigger order, Iceberg order, TWAP order, Trailing Stop order). // Only applicable to Futures and Perpetual swap -func (ok *Okx) AmendAlgoOrder(ctx context.Context, arg *AmendAlgoOrderParam) (*AmendAlgoResponse, error) { +func (e *Exchange) AmendAlgoOrder(ctx context.Context, arg *AmendAlgoOrderParam) (*AmendAlgoResponse, error) { if arg == nil { return nil, common.ErrEmptyParams } @@ -566,11 +566,11 @@ func (ok *Okx) AmendAlgoOrder(ctx context.Context, arg *AmendAlgoOrderParam) (*A return nil, fmt.Errorf("%w either AlgoID or ClientSuppliedAlgoOrderID is required", order.ErrOrderIDNotSet) } var resp *AmendAlgoResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendAlgoOrderEPL, http.MethodPost, "trade/amend-algos", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendAlgoOrderEPL, http.MethodPost, "trade/amend-algos", arg, &resp, request.AuthenticatedRequest) } // GetAlgoOrderDetail retrieves algo order details -func (ok *Okx) GetAlgoOrderDetail(ctx context.Context, algoID, clientSuppliedAlgoID string) (*AlgoOrderDetail, error) { +func (e *Exchange) GetAlgoOrderDetail(ctx context.Context, algoID, clientSuppliedAlgoID string) (*AlgoOrderDetail, error) { if algoID == "" && clientSuppliedAlgoID == "" { return nil, fmt.Errorf("%w either AlgoID or ClientSuppliedAlgoID is required", order.ErrOrderIDNotSet) } @@ -578,11 +578,11 @@ func (ok *Okx) GetAlgoOrderDetail(ctx context.Context, algoID, clientSuppliedAlg params.Set("algoId", algoID) params.Set("algoClOrdId", clientSuppliedAlgoID) var resp *AlgoOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderDetailEPL, http.MethodGet, common.EncodeURLValues("trade/order-algo", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderDetailEPL, http.MethodGet, common.EncodeURLValues("trade/order-algo", params), nil, &resp, request.AuthenticatedRequest) } // GetAlgoOrderList retrieves a list of untriggered Algo orders under the current account -func (ok *Okx) GetAlgoOrderList(ctx context.Context, orderType, algoOrderID, clientOrderID, instrumentType, instrumentID string, after, before time.Time, limit int64) ([]AlgoOrderResponse, error) { +func (e *Exchange) GetAlgoOrderList(ctx context.Context, orderType, algoOrderID, clientOrderID, instrumentType, instrumentID string, after, before time.Time, limit int64) ([]AlgoOrderResponse, error) { orderType = strings.ToLower(orderType) if orderType == "" { return nil, order.ErrTypeIsInvalid @@ -612,11 +612,11 @@ func (ok *Okx) GetAlgoOrderList(ctx context.Context, orderType, algoOrderID, cli params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []AlgoOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderListEPL, http.MethodGet, common.EncodeURLValues("trade/orders-algo-pending", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderListEPL, http.MethodGet, common.EncodeURLValues("trade/orders-algo-pending", params), nil, &resp, request.AuthenticatedRequest) } // GetAlgoOrderHistory load a list of all algo orders under the current account in the last 3 months -func (ok *Okx) GetAlgoOrderHistory(ctx context.Context, orderType, state, algoOrderID, instrumentType, instrumentID string, after, before time.Time, limit int64) ([]AlgoOrderResponse, error) { +func (e *Exchange) GetAlgoOrderHistory(ctx context.Context, orderType, state, algoOrderID, instrumentType, instrumentID string, after, before time.Time, limit int64) ([]AlgoOrderResponse, error) { if orderType == "" { return nil, order.ErrTypeIsInvalid } @@ -647,22 +647,22 @@ func (ok *Okx) GetAlgoOrderHistory(ctx context.Context, orderType, state, algoOr params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []AlgoOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("trade/orders-algo-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAlgoOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("trade/orders-algo-history", params), nil, &resp, request.AuthenticatedRequest) } // GetEasyConvertCurrencyList retrieve list of small convertibles and mainstream currencies. Only applicable to the crypto balance less than $10 -func (ok *Okx) GetEasyConvertCurrencyList(ctx context.Context, source string) (*EasyConvertDetail, error) { +func (e *Exchange) GetEasyConvertCurrencyList(ctx context.Context, source string) (*EasyConvertDetail, error) { params := url.Values{} if source != "" { params.Set("source", source) } var resp *EasyConvertDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEasyConvertCurrencyListEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEasyConvertCurrencyListEPL, http.MethodGet, common.EncodeURLValues("trade/easy-convert-currency-list", params), nil, &resp, request.AuthenticatedRequest) } // PlaceEasyConvert converts small currencies to mainstream currencies. Only applicable to the crypto balance less than $10 -func (ok *Okx) PlaceEasyConvert(ctx context.Context, arg PlaceEasyConvertParam) ([]EasyConvertItem, error) { +func (e *Exchange) PlaceEasyConvert(ctx context.Context, arg PlaceEasyConvertParam) ([]EasyConvertItem, error) { if len(arg.FromCurrency) == 0 { return nil, fmt.Errorf("%w, missing FromCurrency", currency.ErrCurrencyCodeEmpty) } @@ -670,11 +670,11 @@ func (ok *Okx) PlaceEasyConvert(ctx context.Context, arg PlaceEasyConvertParam) return nil, fmt.Errorf("%w, missing ToCurrency", currency.ErrCurrencyCodeEmpty) } var resp []EasyConvertItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeEasyConvertEPL, http.MethodPost, "trade/easy-convert", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeEasyConvertEPL, http.MethodPost, "trade/easy-convert", &arg, &resp, request.AuthenticatedRequest) } // GetEasyConvertHistory retrieves the history and status of easy convert trades -func (ok *Okx) GetEasyConvertHistory(ctx context.Context, after, before time.Time, limit int64) ([]EasyConvertItem, error) { +func (e *Exchange) GetEasyConvertHistory(ctx context.Context, after, before time.Time, limit int64) ([]EasyConvertItem, error) { params := url.Values{} if !before.IsZero() { params.Set("before", strconv.FormatInt(before.Unix(), 10)) @@ -686,24 +686,24 @@ func (ok *Okx) GetEasyConvertHistory(ctx context.Context, after, before time.Tim params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []EasyConvertItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEasyConvertHistoryEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEasyConvertHistoryEPL, http.MethodGet, common.EncodeURLValues("trade/easy-convert-history", params), nil, &resp, request.AuthenticatedRequest) } // GetOneClickRepayCurrencyList retrieves list of debt currency data and repay currencies. Debt currencies include both cross and isolated debts. // debt level "cross", and "isolated" are allowed -func (ok *Okx) GetOneClickRepayCurrencyList(ctx context.Context, debtType string) ([]CurrencyOneClickRepay, error) { +func (e *Exchange) GetOneClickRepayCurrencyList(ctx context.Context, debtType string) ([]CurrencyOneClickRepay, error) { params := url.Values{} if debtType != "" { params.Set("debtType", debtType) } var resp []CurrencyOneClickRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, oneClickRepayCurrencyListEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, oneClickRepayCurrencyListEPL, http.MethodGet, common.EncodeURLValues("trade/one-click-repay-currency-list", params), nil, &resp, request.AuthenticatedRequest) } // TradeOneClickRepay trade one-click repay to repay cross debts. Isolated debts are not applicable. The maximum repayment amount is based on the remaining available balance of funding and trading accounts -func (ok *Okx) TradeOneClickRepay(ctx context.Context, arg TradeOneClickRepayParam) ([]CurrencyOneClickRepay, error) { +func (e *Exchange) TradeOneClickRepay(ctx context.Context, arg TradeOneClickRepayParam) ([]CurrencyOneClickRepay, error) { if len(arg.DebtCurrency) == 0 { return nil, fmt.Errorf("%w, missing 'debtCcy'", currency.ErrCurrencyCodeEmpty) } @@ -711,11 +711,11 @@ func (ok *Okx) TradeOneClickRepay(ctx context.Context, arg TradeOneClickRepayPar return nil, fmt.Errorf("%w, missing 'repayCcy'", currency.ErrCurrencyCodeEmpty) } var resp []CurrencyOneClickRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, tradeOneClickRepayEPL, http.MethodPost, "trade/one-click-repay", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, tradeOneClickRepayEPL, http.MethodPost, "trade/one-click-repay", &arg, &resp, request.AuthenticatedRequest) } // GetOneClickRepayHistory get the history and status of one-click repay trades -func (ok *Okx) GetOneClickRepayHistory(ctx context.Context, after, before time.Time, limit int64) ([]CurrencyOneClickRepay, error) { +func (e *Exchange) GetOneClickRepayHistory(ctx context.Context, after, before time.Time, limit int64) ([]CurrencyOneClickRepay, error) { params := url.Values{} if !before.IsZero() { params.Set("before", strconv.FormatInt(before.Unix(), 10)) @@ -727,12 +727,12 @@ func (ok *Okx) GetOneClickRepayHistory(ctx context.Context, after, before time.T params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []CurrencyOneClickRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOneClickRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("trade/one-click-repay-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOneClickRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("trade/one-click-repay-history", params), nil, &resp, request.AuthenticatedRequest) } // CancelAllMMPOrders cancel all the MMP pending orders of an instrument family. // Only applicable to Option in Portfolio Margin mode, and MMP privilege is required -func (ok *Okx) CancelAllMMPOrders(ctx context.Context, instrumentType, instrumentFamily string, lockInterval int64) (*CancelMMPResponse, error) { +func (e *Exchange) CancelAllMMPOrders(ctx context.Context, instrumentType, instrumentFamily string, lockInterval int64) (*CancelMMPResponse, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -752,12 +752,12 @@ func (ok *Okx) CancelAllMMPOrders(ctx context.Context, instrumentType, instrumen LockInterval: lockInterval, } var resp *CancelMMPResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, tradeOneClickRepayEPL, http.MethodPost, "trade/mass-cancel", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, tradeOneClickRepayEPL, http.MethodPost, "trade/mass-cancel", arg, &resp, request.AuthenticatedRequest) } // CancelAllDelayed cancel all pending orders after the countdown timeout. // Applicable to all trading symbols through order book (except Spread trading) -func (ok *Okx) CancelAllDelayed(ctx context.Context, timeout int64, orderTag string) (*CancelResponse, error) { +func (e *Exchange) CancelAllDelayed(ctx context.Context, timeout int64, orderTag string) (*CancelResponse, error) { if (timeout != 0) && (timeout < 10 || timeout > 120) { return nil, fmt.Errorf("%w, Range of value can be 0, [10, 120]", errCountdownTimeoutRequired) } @@ -769,19 +769,19 @@ func (ok *Okx) CancelAllDelayed(ctx context.Context, timeout int64, orderTag str OrderTag: orderTag, } var resp *CancelResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllAfterCountdownEPL, http.MethodPost, "trade/cancel-all-after", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllAfterCountdownEPL, http.MethodPost, "trade/cancel-all-after", arg, &resp, request.AuthenticatedRequest) } // GetTradeAccountRateLimit get account rate limit related information. // Only new order requests and amendment order requests will be counted towards this limit. For batch order requests consisting of multiple orders, each order will be counted individually -func (ok *Okx) GetTradeAccountRateLimit(ctx context.Context) (*AccountRateLimit, error) { +func (e *Exchange) GetTradeAccountRateLimit(ctx context.Context) (*AccountRateLimit, error) { var resp *AccountRateLimit - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTradeAccountRateLimitEPL, http.MethodGet, "trade/account-rate-limit", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTradeAccountRateLimitEPL, http.MethodGet, "trade/account-rate-limit", nil, &resp, request.AuthenticatedRequest) } // PreCheckOrder returns the account information before and after placing a potential order // Only applicable to Multi-currency margin mode, and Portfolio margin mode -func (ok *Okx) PreCheckOrder(ctx context.Context, arg *OrderPreCheckParams) (*OrderPreCheckResponse, error) { +func (e *Exchange) PreCheckOrder(ctx context.Context, arg *OrderPreCheckParams) (*OrderPreCheckResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -801,19 +801,19 @@ func (ok *Okx) PreCheckOrder(ctx context.Context, arg *OrderPreCheckParams) (*Or return nil, order.ErrAmountBelowMin } var resp *OrderPreCheckResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, orderPreCheckEPL, http.MethodPost, "trade/order-precheck", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, orderPreCheckEPL, http.MethodPost, "trade/order-precheck", arg, &resp, request.AuthenticatedRequest) } /*************************************** Block trading ********************************/ // GetCounterparties retrieves the list of counterparties that the user has permissions to trade with -func (ok *Okx) GetCounterparties(ctx context.Context) ([]CounterpartiesResponse, error) { +func (e *Exchange) GetCounterparties(ctx context.Context) ([]CounterpartiesResponse, error) { var resp []CounterpartiesResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getCounterpartiesEPL, http.MethodGet, "rfq/counterparties", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getCounterpartiesEPL, http.MethodGet, "rfq/counterparties", nil, &resp, request.AuthenticatedRequest) } // CreateRFQ Creates a new RFQ -func (ok *Okx) CreateRFQ(ctx context.Context, arg *CreateRFQInput) (*RFQResponse, error) { +func (e *Exchange) CreateRFQ(ctx context.Context, arg *CreateRFQInput) (*RFQResponse, error) { if len(arg.CounterParties) == 0 { return nil, errInvalidCounterParties } @@ -821,23 +821,23 @@ func (ok *Okx) CreateRFQ(ctx context.Context, arg *CreateRFQInput) (*RFQResponse return nil, errMissingLegs } var resp *RFQResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, createRFQEPL, http.MethodPost, "rfq/create-rfq", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, createRFQEPL, http.MethodPost, "rfq/create-rfq", &arg, &resp, request.AuthenticatedRequest) } // CancelRFQ cancels a request for quotation -func (ok *Okx) CancelRFQ(ctx context.Context, rfqID, clientRFQID string) (*CancelRFQResponse, error) { +func (e *Exchange) CancelRFQ(ctx context.Context, rfqID, clientRFQID string) (*CancelRFQResponse, error) { if rfqID == "" && clientRFQID == "" { return nil, order.ErrOrderIDNotSet } var resp *CancelRFQResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelRFQEPL, http.MethodPost, "rfq/cancel-rfq", &CancelRFQRequestParam{ + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelRFQEPL, http.MethodPost, "rfq/cancel-rfq", &CancelRFQRequestParam{ RFQID: rfqID, ClientRFQID: clientRFQID, }, &resp, request.AuthenticatedRequest) } // CancelMultipleRFQs cancel multiple active RFQs in a single batch. Maximum 100 RFQ orders can be canceled at a time -func (ok *Okx) CancelMultipleRFQs(ctx context.Context, arg *CancelRFQRequestsParam) ([]CancelRFQResponse, error) { +func (e *Exchange) CancelMultipleRFQs(ctx context.Context, arg *CancelRFQRequestsParam) ([]CancelRFQResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -847,35 +847,35 @@ func (ok *Okx) CancelMultipleRFQs(ctx context.Context, arg *CancelRFQRequestsPar return nil, errMaxRFQOrdersToCancel } var resp []CancelRFQResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleRFQEPL, http.MethodPost, "rfq/cancel-batch-rfqs", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleRFQEPL, http.MethodPost, "rfq/cancel-batch-rfqs", &arg, &resp, request.AuthenticatedRequest) } // CancelAllRFQs cancels all active RFQs -func (ok *Okx) CancelAllRFQs(ctx context.Context) (types.Time, error) { +func (e *Exchange) CancelAllRFQs(ctx context.Context) (types.Time, error) { resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllRFQsEPL, http.MethodPost, "rfq/cancel-all-rfqs", nil, resp, request.AuthenticatedRequest) + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllRFQsEPL, http.MethodPost, "rfq/cancel-all-rfqs", nil, resp, request.AuthenticatedRequest) } // ExecuteQuote executes a Quote. It is only used by the creator of the RFQ -func (ok *Okx) ExecuteQuote(ctx context.Context, rfqID, quoteID string) (*ExecuteQuoteResponse, error) { +func (e *Exchange) ExecuteQuote(ctx context.Context, rfqID, quoteID string) (*ExecuteQuoteResponse, error) { if rfqID == "" || quoteID == "" { return nil, errMissingRFQIDOrQuoteID } var resp *ExecuteQuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, executeQuoteEPL, http.MethodPost, "rfq/execute-quote", &ExecuteQuoteParams{ + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, executeQuoteEPL, http.MethodPost, "rfq/execute-quote", &ExecuteQuoteParams{ RFQID: rfqID, QuoteID: quoteID, }, &resp, request.AuthenticatedRequest) } // GetQuoteProducts retrieve the products which makers want to quote and receive RFQs for, and the corresponding price and size limit -func (ok *Okx) GetQuoteProducts(ctx context.Context) ([]QuoteProduct, error) { +func (e *Exchange) GetQuoteProducts(ctx context.Context) ([]QuoteProduct, error) { var resp []QuoteProduct - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getQuoteProductsEPL, http.MethodGet, "rfq/maker-instrument-settings", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getQuoteProductsEPL, http.MethodGet, "rfq/maker-instrument-settings", nil, &resp, request.AuthenticatedRequest) } // SetQuoteProducts customize the products which makers want to quote and receive RFQs for, and the corresponding price and size limit -func (ok *Okx) SetQuoteProducts(ctx context.Context, args []SetQuoteProductParam) (*SetQuoteProductsResult, error) { +func (e *Exchange) SetQuoteProducts(ctx context.Context, args []SetQuoteProductParam) (*SetQuoteProductsResult, error) { if len(args) == 0 { return nil, common.ErrEmptyParams } @@ -897,18 +897,18 @@ func (ok *Okx) SetQuoteProducts(ctx context.Context, args []SetQuoteProductParam } } var resp *SetQuoteProductsResult - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setQuoteProductsEPL, http.MethodPost, "rfq/maker-instrument-settings", &args, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setQuoteProductsEPL, http.MethodPost, "rfq/maker-instrument-settings", &args, &resp, request.AuthenticatedRequest) } // ResetRFQMMPStatus reset the MMP status to be inactive -func (ok *Okx) ResetRFQMMPStatus(ctx context.Context) (types.Time, error) { +func (e *Exchange) ResetRFQMMPStatus(ctx context.Context) (types.Time, error) { resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, resetRFQMMPEPL, http.MethodPost, "rfq/mmp-reset", nil, resp, request.AuthenticatedRequest) + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, resetRFQMMPEPL, http.MethodPost, "rfq/mmp-reset", nil, resp, request.AuthenticatedRequest) } // CreateQuote allows the user to Quote an RFQ that they are a counterparty to. The user MUST quote // the entire RFQ and not part of the legs or part of the quantity. Partial quoting or partial fills are not allowed -func (ok *Okx) CreateQuote(ctx context.Context, arg *CreateQuoteParams) (*QuoteResponse, error) { +func (e *Exchange) CreateQuote(ctx context.Context, arg *CreateQuoteParams) (*QuoteResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -934,38 +934,38 @@ func (ok *Okx) CreateQuote(ctx context.Context, arg *CreateQuoteParams) (*QuoteR } } var resp *QuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, createQuoteEPL, http.MethodPost, "rfq/create-quote", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, createQuoteEPL, http.MethodPost, "rfq/create-quote", &arg, &resp, request.AuthenticatedRequest) } // CancelQuote cancels an existing active quote you have created in response to an RFQ -func (ok *Okx) CancelQuote(ctx context.Context, quoteID, clientQuoteID string) (*CancelQuoteResponse, error) { +func (e *Exchange) CancelQuote(ctx context.Context, quoteID, clientQuoteID string) (*CancelQuoteResponse, error) { if clientQuoteID == "" && quoteID == "" { return nil, order.ErrOrderIDNotSet } var resp *CancelQuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelQuoteEPL, http.MethodPost, "rfq/cancel-quote", &CancelQuoteRequestParams{ + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelQuoteEPL, http.MethodPost, "rfq/cancel-quote", &CancelQuoteRequestParams{ QuoteID: quoteID, ClientQuoteID: clientQuoteID, }, &resp, request.AuthenticatedRequest) } // CancelMultipleQuote cancels multiple active quotes in a single batch, with a maximum of 100 quote orders cancellable at once -func (ok *Okx) CancelMultipleQuote(ctx context.Context, arg CancelQuotesRequestParams) ([]CancelQuoteResponse, error) { +func (e *Exchange) CancelMultipleQuote(ctx context.Context, arg CancelQuotesRequestParams) ([]CancelQuoteResponse, error) { if len(arg.QuoteIDs) == 0 && len(arg.ClientQuoteIDs) == 0 { return nil, order.ErrOrderIDNotSet } var resp []CancelQuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleQuotesEPL, http.MethodPost, "rfq/cancel-batch-quotes", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelMultipleQuotesEPL, http.MethodPost, "rfq/cancel-batch-quotes", &arg, &resp, request.AuthenticatedRequest) } // CancelAllRFQQuotes cancels all active quote orders -func (ok *Okx) CancelAllRFQQuotes(ctx context.Context) (types.Time, error) { +func (e *Exchange) CancelAllRFQQuotes(ctx context.Context) (types.Time, error) { resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllQuotesEPL, http.MethodPost, "rfq/cancel-all-quotes", nil, resp, request.AuthenticatedRequest) + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllQuotesEPL, http.MethodPost, "rfq/cancel-all-quotes", nil, resp, request.AuthenticatedRequest) } // GetRFQs retrieves details of RFQs where the user is a counterparty, either as the creator or the recipient -func (ok *Okx) GetRFQs(ctx context.Context, arg *RFQRequestParams) ([]RFQResponse, error) { +func (e *Exchange) GetRFQs(ctx context.Context, arg *RFQRequestParams) ([]RFQResponse, error) { if *arg == (RFQRequestParams{}) { return nil, common.ErrEmptyParams } @@ -989,11 +989,11 @@ func (ok *Okx) GetRFQs(ctx context.Context, arg *RFQRequestParams) ([]RFQRespons params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp []RFQResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getRFQsEPL, http.MethodGet, common.EncodeURLValues("rfq/rfqs", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getRFQsEPL, http.MethodGet, common.EncodeURLValues("rfq/rfqs", params), nil, &resp, request.AuthenticatedRequest) } // GetQuotes retrieves all Quotes where the user is a counterparty, either as the creator or the receiver -func (ok *Okx) GetQuotes(ctx context.Context, arg *QuoteRequestParams) ([]QuoteResponse, error) { +func (e *Exchange) GetQuotes(ctx context.Context, arg *QuoteRequestParams) ([]QuoteResponse, error) { if *arg == (QuoteRequestParams{}) { return nil, common.ErrEmptyParams } @@ -1023,11 +1023,11 @@ func (ok *Okx) GetQuotes(ctx context.Context, arg *QuoteRequestParams) ([]QuoteR params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp []QuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getQuotesEPL, http.MethodGet, common.EncodeURLValues("rfq/quotes", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getQuotesEPL, http.MethodGet, common.EncodeURLValues("rfq/quotes", params), nil, &resp, request.AuthenticatedRequest) } // GetRFQTrades retrieves executed trades where the user is a counterparty, either as the creator or the receiver -func (ok *Okx) GetRFQTrades(ctx context.Context, arg *RFQTradesRequestParams) ([]RFQTradeResponse, error) { +func (e *Exchange) GetRFQTrades(ctx context.Context, arg *RFQTradesRequestParams) ([]RFQTradeResponse, error) { if *arg == (RFQTradesRequestParams{}) { return nil, common.ErrEmptyParams } @@ -1060,11 +1060,11 @@ func (ok *Okx) GetRFQTrades(ctx context.Context, arg *RFQTradesRequestParams) ([ params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp []RFQTradeResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTradesEPL, http.MethodGet, common.EncodeURLValues("rfq/trades", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTradesEPL, http.MethodGet, common.EncodeURLValues("rfq/trades", params), nil, &resp, request.AuthenticatedRequest) } // GetPublicRFQTrades retrieves recent executed block trades -func (ok *Okx) GetPublicRFQTrades(ctx context.Context, beginID, endID string, limit int64) ([]PublicTradesResponse, error) { +func (e *Exchange) GetPublicRFQTrades(ctx context.Context, beginID, endID string, limit int64) ([]PublicTradesResponse, error) { params := url.Values{} if beginID != "" { params.Set("beginId", beginID) @@ -1076,55 +1076,55 @@ func (ok *Okx) GetPublicRFQTrades(ctx context.Context, beginID, endID string, li params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PublicTradesResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPublicTradesEPL, http.MethodGet, common.EncodeURLValues("rfq/public-trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPublicTradesEPL, http.MethodGet, common.EncodeURLValues("rfq/public-trades", params), nil, &resp, request.UnauthenticatedRequest) } /*************************************** Funding Tradings ********************************/ // GetFundingCurrencies retrieve a list of all currencies -func (ok *Okx) GetFundingCurrencies(ctx context.Context, ccy currency.Code) ([]CurrencyResponse, error) { +func (e *Exchange) GetFundingCurrencies(ctx context.Context, ccy currency.Code) ([]CurrencyResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []CurrencyResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getCurrenciesEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getCurrenciesEPL, http.MethodGet, common.EncodeURLValues("asset/currencies", params), nil, &resp, request.AuthenticatedRequest) } // GetBalance retrieves the funding account balances of all the assets and the amount that is available or on hold -func (ok *Okx) GetBalance(ctx context.Context, ccy currency.Code) ([]AssetBalance, error) { +func (e *Exchange) GetBalance(ctx context.Context, ccy currency.Code) ([]AssetBalance, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []AssetBalance - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBalanceEPL, http.MethodGet, common.EncodeURLValues("asset/balances", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBalanceEPL, http.MethodGet, common.EncodeURLValues("asset/balances", params), nil, &resp, request.AuthenticatedRequest) } // GetNonTradableAssets retrieves non tradable assets -func (ok *Okx) GetNonTradableAssets(ctx context.Context, ccy currency.Code) ([]NonTradableAsset, error) { +func (e *Exchange) GetNonTradableAssets(ctx context.Context, ccy currency.Code) ([]NonTradableAsset, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []NonTradableAsset - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getNonTradableAssetsEPL, http.MethodGet, common.EncodeURLValues("asset/non-tradable-assets", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getNonTradableAssetsEPL, http.MethodGet, common.EncodeURLValues("asset/non-tradable-assets", params), nil, &resp, request.AuthenticatedRequest) } // GetAccountAssetValuation view account asset valuation -func (ok *Okx) GetAccountAssetValuation(ctx context.Context, ccy currency.Code) ([]AccountAssetValuation, error) { +func (e *Exchange) GetAccountAssetValuation(ctx context.Context, ccy currency.Code) ([]AccountAssetValuation, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.Upper().String()) } var resp []AccountAssetValuation - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountAssetValuationEPL, http.MethodGet, common.EncodeURLValues("asset/asset-valuation", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountAssetValuationEPL, http.MethodGet, common.EncodeURLValues("asset/asset-valuation", params), nil, &resp, request.AuthenticatedRequest) } // FundingTransfer transfer of funds between your funding account and trading account, // and from the master account to sub-accounts -func (ok *Okx) FundingTransfer(ctx context.Context, arg *FundingTransferRequestInput) ([]FundingTransferResponse, error) { +func (e *Exchange) FundingTransfer(ctx context.Context, arg *FundingTransferRequestInput) ([]FundingTransferResponse, error) { if *arg == (FundingTransferRequestInput{}) { return nil, common.ErrEmptyParams } @@ -1141,11 +1141,11 @@ func (ok *Okx) FundingTransfer(ctx context.Context, arg *FundingTransferRequestI return nil, fmt.Errorf("%w, beneficiary account type 6: Funding account 18: Trading account", errAddressRequired) } var resp []FundingTransferResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, fundsTransferEPL, http.MethodPost, "asset/transfer", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, fundsTransferEPL, http.MethodPost, "asset/transfer", arg, &resp, request.AuthenticatedRequest) } // GetFundsTransferState get funding rate response -func (ok *Okx) GetFundsTransferState(ctx context.Context, transferID, clientID string, transferType int64) ([]TransferFundRateResponse, error) { +func (e *Exchange) GetFundsTransferState(ctx context.Context, transferID, clientID string, transferType int64) ([]TransferFundRateResponse, error) { if transferID == "" && clientID == "" { return nil, fmt.Errorf("%w, 'transfer id' or 'client id' is required", order.ErrOrderIDNotSet) } @@ -1160,12 +1160,12 @@ func (ok *Okx) GetFundsTransferState(ctx context.Context, transferID, clientID s params.Set("type", strconv.FormatInt(transferType, 10)) } var resp []TransferFundRateResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFundsTransferStateEPL, http.MethodGet, common.EncodeURLValues("asset/transfer-state", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFundsTransferStateEPL, http.MethodGet, common.EncodeURLValues("asset/transfer-state", params), nil, &resp, request.AuthenticatedRequest) } // GetAssetBillsDetails query the billing record, you can get the latest 1 month historical data // Bills type possible values are listed here: https://www.okx.com/docs-v5/en/#funding-account-rest-api-asset-bills-details -func (ok *Okx) GetAssetBillsDetails(ctx context.Context, ccy currency.Code, clientID string, after, before time.Time, billType, limit int64) ([]AssetBillDetail, error) { +func (e *Exchange) GetAssetBillsDetails(ctx context.Context, ccy currency.Code, clientID string, after, before time.Time, billType, limit int64) ([]AssetBillDetail, error) { params := url.Values{} if billType > 0 { params.Set("type", strconv.FormatInt(billType, 10)) @@ -1186,12 +1186,12 @@ func (ok *Okx) GetAssetBillsDetails(ctx context.Context, ccy currency.Code, clie params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []AssetBillDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, assetBillsDetailsEPL, http.MethodGet, common.EncodeURLValues("asset/bills", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, assetBillsDetailsEPL, http.MethodGet, common.EncodeURLValues("asset/bills", params), nil, &resp, request.AuthenticatedRequest) } // GetLightningDeposits users can create up to 10 thousand different invoices within 24 hours. // this method fetches list of lightning deposits filtered by a currency and amount -func (ok *Okx) GetLightningDeposits(ctx context.Context, ccy currency.Code, amount float64, to int64) ([]LightningDepositItem, error) { +func (e *Exchange) GetLightningDeposits(ctx context.Context, ccy currency.Code, amount float64, to int64) ([]LightningDepositItem, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -1205,23 +1205,23 @@ func (ok *Okx) GetLightningDeposits(ctx context.Context, ccy currency.Code, amou params.Set("to", strconv.FormatInt(to, 10)) } var resp []LightningDepositItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, lightningDepositsEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-lightning", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, lightningDepositsEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-lightning", params), nil, &resp, request.AuthenticatedRequest) } // GetCurrencyDepositAddress retrieve the deposit addresses of currencies, including previously-used addresses -func (ok *Okx) GetCurrencyDepositAddress(ctx context.Context, ccy currency.Code) ([]CurrencyDepositResponseItem, error) { +func (e *Exchange) GetCurrencyDepositAddress(ctx context.Context, ccy currency.Code) ([]CurrencyDepositResponseItem, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("ccy", ccy.String()) var resp []CurrencyDepositResponseItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDepositAddressEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-address", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDepositAddressEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-address", params), nil, &resp, request.AuthenticatedRequest) } // GetCurrencyDepositHistory retrieves deposit records and withdrawal status information depending on the currency, timestamp, and chronological order. // Possible deposit 'type' are Deposit Type '3': internal transfer '4': deposit from chain -func (ok *Okx) GetCurrencyDepositHistory(ctx context.Context, ccy currency.Code, depositID, transactionID, fromWithdrawalID, depositType string, after, before time.Time, state, limit int64) ([]DepositHistoryResponseItem, error) { +func (e *Exchange) GetCurrencyDepositHistory(ctx context.Context, ccy currency.Code, depositID, transactionID, fromWithdrawalID, depositType string, after, before time.Time, state, limit int64) ([]DepositHistoryResponseItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -1249,11 +1249,11 @@ func (ok *Okx) GetCurrencyDepositHistory(ctx context.Context, ccy currency.Code, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []DepositHistoryResponseItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDepositHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDepositHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-history", params), nil, &resp, request.AuthenticatedRequest) } // Withdrawal to perform a withdrawal action. Sub-account does not support withdrawal -func (ok *Okx) Withdrawal(ctx context.Context, arg *WithdrawalInput) (*WithdrawalResponse, error) { +func (e *Exchange) Withdrawal(ctx context.Context, arg *WithdrawalInput) (*WithdrawalResponse, error) { if *arg == (WithdrawalInput{}) { return nil, common.ErrEmptyParams } @@ -1268,7 +1268,7 @@ func (ok *Okx) Withdrawal(ctx context.Context, arg *WithdrawalInput) (*Withdrawa return nil, fmt.Errorf("%w, missing verified digital currency address \"toAddr\" information", errAddressRequired) } var resp *WithdrawalResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, withdrawalEPL, http.MethodPost, "asset/withdrawal", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, withdrawalEPL, http.MethodPost, "asset/withdrawal", &arg, &resp, request.AuthenticatedRequest) } /* @@ -1276,7 +1276,7 @@ func (ok *Okx) Withdrawal(ctx context.Context, arg *WithdrawalInput) (*Withdrawa */ // LightningWithdrawal to withdraw a currency from an invoice -func (ok *Okx) LightningWithdrawal(ctx context.Context, arg *LightningWithdrawalRequestInput) (*LightningWithdrawalResponse, error) { +func (e *Exchange) LightningWithdrawal(ctx context.Context, arg *LightningWithdrawalRequestInput) (*LightningWithdrawalResponse, error) { if *arg == (LightningWithdrawalRequestInput{}) { return nil, common.ErrEmptyParams } @@ -1286,11 +1286,11 @@ func (ok *Okx) LightningWithdrawal(ctx context.Context, arg *LightningWithdrawal return nil, errInvoiceTextMissing } var resp *LightningWithdrawalResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, lightningWithdrawalsEPL, http.MethodPost, "asset/withdrawal-lightning", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, lightningWithdrawalsEPL, http.MethodPost, "asset/withdrawal-lightning", &arg, &resp, request.AuthenticatedRequest) } // CancelWithdrawal cancels a normal withdrawal request but cannot be used to cancel Lightning withdrawals -func (ok *Okx) CancelWithdrawal(ctx context.Context, withdrawalID string) (string, error) { +func (e *Exchange) CancelWithdrawal(ctx context.Context, withdrawalID string) (string, error) { if withdrawalID == "" { return "", errMissingValidWithdrawalID } @@ -1298,12 +1298,12 @@ func (ok *Okx) CancelWithdrawal(ctx context.Context, withdrawalID string) (strin WithdrawalID: withdrawalID, } var resp withdrawData - return resp.WithdrawalID, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalEPL, http.MethodPost, "asset/cancel-withdrawal", arg, &resp, request.AuthenticatedRequest) + return resp.WithdrawalID, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalEPL, http.MethodPost, "asset/cancel-withdrawal", arg, &resp, request.AuthenticatedRequest) } // GetWithdrawalHistory retrieves the withdrawal records according to the currency, withdrawal status, and time range in reverse chronological order. // The 100 most recent records are returned by default -func (ok *Okx) GetWithdrawalHistory(ctx context.Context, ccy currency.Code, withdrawalID, clientID, transactionID, state string, after, before time.Time, limit int64) ([]WithdrawalHistoryResponse, error) { +func (e *Exchange) GetWithdrawalHistory(ctx context.Context, ccy currency.Code, withdrawalID, clientID, transactionID, state string, after, before time.Time, limit int64) ([]WithdrawalHistoryResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -1330,11 +1330,11 @@ func (ok *Okx) GetWithdrawalHistory(ctx context.Context, ccy currency.Code, with params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []WithdrawalHistoryResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/withdrawal-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/withdrawal-history", params), nil, &resp, request.AuthenticatedRequest) } // GetDepositWithdrawalStatus retrieves the detailed status and estimated completion time for deposits and withdrawals -func (ok *Okx) GetDepositWithdrawalStatus(ctx context.Context, ccy currency.Code, withdrawalID, transactionID, addressTo, chain string) ([]DepositWithdrawStatus, error) { +func (e *Exchange) GetDepositWithdrawalStatus(ctx context.Context, ccy currency.Code, withdrawalID, transactionID, addressTo, chain string) ([]DepositWithdrawStatus, error) { if withdrawalID == "" && transactionID == "" { return nil, fmt.Errorf("%w, either withdrawal id or transaction id is required", order.ErrOrderIDNotSet) } @@ -1356,33 +1356,33 @@ func (ok *Okx) GetDepositWithdrawalStatus(ctx context.Context, ccy currency.Code params.Set("chain", chain) } var resp []DepositWithdrawStatus - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDepositWithdrawalStatusEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-withdraw-status", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDepositWithdrawalStatusEPL, http.MethodGet, common.EncodeURLValues("asset/deposit-withdraw-status", params), nil, &resp, request.AuthenticatedRequest) } // SmallAssetsConvert Convert small assets in funding account to OKB. Only one convert is allowed within 24 hours -func (ok *Okx) SmallAssetsConvert(ctx context.Context, currency []string) (*SmallAssetConvertResponse, error) { +func (e *Exchange) SmallAssetsConvert(ctx context.Context, currency []string) (*SmallAssetConvertResponse, error) { var resp *SmallAssetConvertResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, smallAssetsConvertEPL, http.MethodPost, "asset/convert-dust-assets", map[string][]string{"ccy": currency}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, smallAssetsConvertEPL, http.MethodPost, "asset/convert-dust-assets", map[string][]string{"ccy": currency}, &resp, request.AuthenticatedRequest) } // GetPublicExchangeList retrieves exchanges -func (ok *Okx) GetPublicExchangeList(ctx context.Context) ([]ExchangeInfo, error) { +func (e *Exchange) GetPublicExchangeList(ctx context.Context) ([]ExchangeInfo, error) { var resp []ExchangeInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPublicExchangeListEPL, http.MethodGet, "asset/exchange-list", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPublicExchangeListEPL, http.MethodGet, "asset/exchange-list", nil, &resp, request.UnauthenticatedRequest) } // GetSavingBalance returns saving balance, and only assets in the funding account can be used for saving -func (ok *Okx) GetSavingBalance(ctx context.Context, ccy currency.Code) ([]SavingBalanceResponse, error) { +func (e *Exchange) GetSavingBalance(ctx context.Context, ccy currency.Code) ([]SavingBalanceResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []SavingBalanceResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSavingBalanceEPL, http.MethodGet, common.EncodeURLValues("finance/savings/balance", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSavingBalanceEPL, http.MethodGet, common.EncodeURLValues("finance/savings/balance", params), nil, &resp, request.AuthenticatedRequest) } // SavingsPurchaseOrRedemption creates a purchase or redemption instance -func (ok *Okx) SavingsPurchaseOrRedemption(ctx context.Context, arg *SavingsPurchaseRedemptionInput) (*SavingsPurchaseRedemptionResponse, error) { +func (e *Exchange) SavingsPurchaseOrRedemption(ctx context.Context, arg *SavingsPurchaseRedemptionInput) (*SavingsPurchaseRedemptionResponse, error) { if *arg == (SavingsPurchaseRedemptionInput{}) { return nil, common.ErrEmptyParams } @@ -1398,11 +1398,11 @@ func (ok *Okx) SavingsPurchaseOrRedemption(ctx context.Context, arg *SavingsPurc return nil, fmt.Errorf("%w, the rate value range is between 0.01 and 3.65", errRateRequired) } var resp *SavingsPurchaseRedemptionResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, savingsPurchaseRedemptionEPL, http.MethodPost, "finance/savings/purchase-redempt", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, savingsPurchaseRedemptionEPL, http.MethodPost, "finance/savings/purchase-redempt", &arg, &resp, request.AuthenticatedRequest) } // GetLendingHistory lending history -func (ok *Okx) GetLendingHistory(ctx context.Context, ccy currency.Code, before, after time.Time, limit int64) ([]LendingHistory, error) { +func (e *Exchange) GetLendingHistory(ctx context.Context, ccy currency.Code, before, after time.Time, limit int64) ([]LendingHistory, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -1417,11 +1417,11 @@ func (ok *Okx) GetLendingHistory(ctx context.Context, ccy currency.Code, before, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []LendingHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLendingHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLendingHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-history", params), nil, &resp, request.AuthenticatedRequest) } // SetLendingRate sets an assets lending rate -func (ok *Okx) SetLendingRate(ctx context.Context, arg *LendingRate) (*LendingRate, error) { +func (e *Exchange) SetLendingRate(ctx context.Context, arg *LendingRate) (*LendingRate, error) { if *arg == (LendingRate{}) { return nil, common.ErrEmptyParams } @@ -1431,21 +1431,21 @@ func (ok *Okx) SetLendingRate(ctx context.Context, arg *LendingRate) (*LendingRa return nil, fmt.Errorf("%w, rate value range is between 1 percent (0.01) and 365 percent (3.65)", errRateRequired) } var resp *LendingRate - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setLendingRateEPL, http.MethodPost, "finance/savings/set-lending-rate", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setLendingRateEPL, http.MethodPost, "finance/savings/set-lending-rate", &arg, &resp, request.AuthenticatedRequest) } // GetPublicBorrowInfo returns the public borrow info -func (ok *Okx) GetPublicBorrowInfo(ctx context.Context, ccy currency.Code) ([]PublicBorrowInfo, error) { +func (e *Exchange) GetPublicBorrowInfo(ctx context.Context, ccy currency.Code) ([]PublicBorrowInfo, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []PublicBorrowInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPublicBorrowInfoEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-rate-summary", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPublicBorrowInfoEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-rate-summary", params), nil, &resp, request.UnauthenticatedRequest) } // GetPublicBorrowHistory return list of publix borrow history -func (ok *Okx) GetPublicBorrowHistory(ctx context.Context, ccy currency.Code, before, after time.Time, limit int64) ([]PublicBorrowHistory, error) { +func (e *Exchange) GetPublicBorrowHistory(ctx context.Context, ccy currency.Code, before, after time.Time, limit int64) ([]PublicBorrowHistory, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -1460,42 +1460,42 @@ func (ok *Okx) GetPublicBorrowHistory(ctx context.Context, ccy currency.Code, be params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PublicBorrowHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPublicBorrowHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-rate-history", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPublicBorrowHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/savings/lending-rate-history", params), nil, &resp, request.UnauthenticatedRequest) } /***********************************Convert Endpoints | Authenticated s*****************************************/ // ApplyForMonthlyStatement requests a monthly statement for any month within the past year -func (ok *Okx) ApplyForMonthlyStatement(ctx context.Context, month string) (types.Time, error) { +func (e *Exchange) ApplyForMonthlyStatement(ctx context.Context, month string) (types.Time, error) { if month == "" { return types.Time{}, errMonthNameRequired } resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, applyForMonthlyStatementEPL, + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, applyForMonthlyStatementEPL, http.MethodPost, "asset/monthly-statement", &map[string]string{"month": month}, resp, request.AuthenticatedRequest) } // GetMonthlyStatement retrieves monthly statements for the past year. // Month is in the form of Jan, Feb, March etc. -func (ok *Okx) GetMonthlyStatement(ctx context.Context, month string) ([]MonthlyStatement, error) { +func (e *Exchange) GetMonthlyStatement(ctx context.Context, month string) ([]MonthlyStatement, error) { if month == "" { return nil, errMonthNameRequired } params := url.Values{} params.Set("month", month) var resp []MonthlyStatement - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMonthlyStatementEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMonthlyStatementEPL, http.MethodGet, common.EncodeURLValues("asset/monthly-statement", params), nil, &resp, request.AuthenticatedRequest) } // GetConvertCurrencies retrieves the currency conversion information -func (ok *Okx) GetConvertCurrencies(ctx context.Context) ([]ConvertCurrency, error) { +func (e *Exchange) GetConvertCurrencies(ctx context.Context) ([]ConvertCurrency, error) { var resp []ConvertCurrency - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getConvertCurrenciesEPL, http.MethodGet, "asset/convert/currencies", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getConvertCurrenciesEPL, http.MethodGet, "asset/convert/currencies", nil, &resp, request.AuthenticatedRequest) } // GetConvertCurrencyPair retrieves the currency conversion response detail given the 'currency from' and 'currency to' -func (ok *Okx) GetConvertCurrencyPair(ctx context.Context, fromCcy, toCcy currency.Code) (*ConvertCurrencyPair, error) { +func (e *Exchange) GetConvertCurrencyPair(ctx context.Context, fromCcy, toCcy currency.Code) (*ConvertCurrencyPair, error) { if fromCcy.IsEmpty() { return nil, fmt.Errorf("%w, source currency is required", currency.ErrCurrencyCodeEmpty) } @@ -1506,11 +1506,11 @@ func (ok *Okx) GetConvertCurrencyPair(ctx context.Context, fromCcy, toCcy curren params.Set("fromCcy", fromCcy.String()) params.Set("toCcy", toCcy.String()) var resp *ConvertCurrencyPair - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getConvertCurrencyPairEPL, http.MethodGet, common.EncodeURLValues("asset/convert/currency-pair", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getConvertCurrencyPairEPL, http.MethodGet, common.EncodeURLValues("asset/convert/currency-pair", params), nil, &resp, request.AuthenticatedRequest) } // EstimateQuote retrieves quote estimation detail result given the base and quote currency -func (ok *Okx) EstimateQuote(ctx context.Context, arg *EstimateQuoteRequestInput) (*EstimateQuoteResponse, error) { +func (e *Exchange) EstimateQuote(ctx context.Context, arg *EstimateQuoteRequestInput) (*EstimateQuoteResponse, error) { if *arg == (EstimateQuoteRequestInput{}) { return nil, common.ErrEmptyParams } @@ -1533,11 +1533,11 @@ func (ok *Okx) EstimateQuote(ctx context.Context, arg *EstimateQuoteRequestInput return nil, fmt.Errorf("%w, missing RFQ currency", currency.ErrCurrencyCodeEmpty) } var resp *EstimateQuoteResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, estimateQuoteEPL, http.MethodPost, "asset/convert/estimate-quote", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, estimateQuoteEPL, http.MethodPost, "asset/convert/estimate-quote", arg, &resp, request.AuthenticatedRequest) } // ConvertTrade converts a base currency to quote currency -func (ok *Okx) ConvertTrade(ctx context.Context, arg *ConvertTradeInput) (*ConvertTradeResponse, error) { +func (e *Exchange) ConvertTrade(ctx context.Context, arg *ConvertTradeInput) (*ConvertTradeResponse, error) { if *arg == (ConvertTradeInput{}) { return nil, common.ErrEmptyParams } @@ -1563,11 +1563,11 @@ func (ok *Okx) ConvertTrade(ctx context.Context, arg *ConvertTradeInput) (*Conve return nil, fmt.Errorf("%w, quote id required", order.ErrOrderIDNotSet) } var resp *ConvertTradeResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, convertTradeEPL, http.MethodPost, "asset/convert/trade", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, convertTradeEPL, http.MethodPost, "asset/convert/trade", &arg, &resp, request.AuthenticatedRequest) } // GetConvertHistory gets the recent history -func (ok *Okx) GetConvertHistory(ctx context.Context, before, after time.Time, limit int64, tag string) ([]ConvertHistory, error) { +func (e *Exchange) GetConvertHistory(ctx context.Context, before, after time.Time, limit int64, tag string) ([]ConvertHistory, error) { params := url.Values{} if !before.IsZero() { params.Set("before", strconv.FormatInt(before.UnixMilli(), 10)) @@ -1582,13 +1582,13 @@ func (ok *Okx) GetConvertHistory(ctx context.Context, before, after time.Time, l params.Set("tag", tag) } var resp []ConvertHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getConvertHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/convert/history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getConvertHistoryEPL, http.MethodGet, common.EncodeURLValues("asset/convert/history", params), nil, &resp, request.AuthenticatedRequest) } /********************************** Account endpoints ***************************************************/ // GetAccountInstruments retrieve available instruments info of current account -func (ok *Okx) GetAccountInstruments(ctx context.Context, instrumentType asset.Item, underlying, instrumentFamily, instrumentID string) ([]AccountInstrument, error) { +func (e *Exchange) GetAccountInstruments(ctx context.Context, instrumentType asset.Item, underlying, instrumentFamily, instrumentID string) ([]AccountInstrument, error) { if instrumentType == asset.Empty { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -1619,22 +1619,22 @@ func (ok *Okx) GetAccountInstruments(ctx context.Context, instrumentType asset.I params.Set("instId", instrumentID) } var resp []AccountInstrument - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountInstrumentsEPL, http.MethodGet, common.EncodeURLValues("account/instruments", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountInstrumentsEPL, http.MethodGet, common.EncodeURLValues("account/instruments", params), nil, &resp, request.AuthenticatedRequest) } // AccountBalance retrieves a list of assets (with non-zero balance), remaining balance, and available amount in the trading account. // Interest-free quota and discount rates are public data and not displayed on the account interface -func (ok *Okx) AccountBalance(ctx context.Context, ccy currency.Code) ([]Account, error) { +func (e *Exchange) AccountBalance(ctx context.Context, ccy currency.Code) ([]Account, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []Account - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountBalanceEPL, http.MethodGet, common.EncodeURLValues("account/balance", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountBalanceEPL, http.MethodGet, common.EncodeURLValues("account/balance", params), nil, &resp, request.AuthenticatedRequest) } // GetPositions retrieves information on your positions. When the account is in net mode, net positions will be displayed, and when the account is in long/short mode, long or short positions will be displayed -func (ok *Okx) GetPositions(ctx context.Context, instrumentType, instrumentID, positionID string) ([]AccountPosition, error) { +func (e *Exchange) GetPositions(ctx context.Context, instrumentType, instrumentID, positionID string) ([]AccountPosition, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -1646,11 +1646,11 @@ func (ok *Okx) GetPositions(ctx context.Context, instrumentType, instrumentID, p params.Set("posId", positionID) } var resp []AccountPosition - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPositionsEPL, http.MethodGet, common.EncodeURLValues("account/positions", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPositionsEPL, http.MethodGet, common.EncodeURLValues("account/positions", params), nil, &resp, request.AuthenticatedRequest) } // GetPositionsHistory retrieves the updated position data for the last 3 months -func (ok *Okx) GetPositionsHistory(ctx context.Context, instrumentType, instrumentID, marginMode, positionID string, closePositionType, limit int64, after, before time.Time) ([]AccountPositionHistory, error) { +func (e *Exchange) GetPositionsHistory(ctx context.Context, instrumentType, instrumentID, marginMode, positionID string, closePositionType, limit int64, after, before time.Time) ([]AccountPositionHistory, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -1680,35 +1680,35 @@ func (ok *Okx) GetPositionsHistory(ctx context.Context, instrumentType, instrume params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []AccountPositionHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPositionsHistoryEPL, http.MethodGet, common.EncodeURLValues("account/positions-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPositionsHistoryEPL, http.MethodGet, common.EncodeURLValues("account/positions-history", params), nil, &resp, request.AuthenticatedRequest) } // GetAccountAndPositionRisk get account and position risks -func (ok *Okx) GetAccountAndPositionRisk(ctx context.Context, instrumentType string) ([]AccountAndPositionRisk, error) { +func (e *Exchange) GetAccountAndPositionRisk(ctx context.Context, instrumentType string) ([]AccountAndPositionRisk, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", strings.ToUpper(instrumentType)) } var resp []AccountAndPositionRisk - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountAndPositionRiskEPL, http.MethodGet, common.EncodeURLValues("account/account-position-risk", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountAndPositionRiskEPL, http.MethodGet, common.EncodeURLValues("account/account-position-risk", params), nil, &resp, request.AuthenticatedRequest) } // GetBillsDetailLast7Days The bill refers to all transaction records that result in changing the balance of an account. Pagination is supported, and the response is sorted with the most recent first. This endpoint can retrieve data from the last 7 days -func (ok *Okx) GetBillsDetailLast7Days(ctx context.Context, arg *BillsDetailQueryParameter) ([]BillsDetailResponse, error) { - return ok.GetBillsDetail(ctx, arg, "account/bills", getBillsDetailsEPL) +func (e *Exchange) GetBillsDetailLast7Days(ctx context.Context, arg *BillsDetailQueryParameter) ([]BillsDetailResponse, error) { + return e.GetBillsDetail(ctx, arg, "account/bills", getBillsDetailsEPL) } // GetBillsDetail3Months retrieves the account’s bills. // The bill refers to all transaction records that result in changing the balance of an account. // Pagination is supported, and the response is sorted with most recent first. // This endpoint can retrieve data from the last 3 months -func (ok *Okx) GetBillsDetail3Months(ctx context.Context, arg *BillsDetailQueryParameter) ([]BillsDetailResponse, error) { - return ok.GetBillsDetail(ctx, arg, "account/bills-archive", getBillsDetailArchiveEPL) +func (e *Exchange) GetBillsDetail3Months(ctx context.Context, arg *BillsDetailQueryParameter) ([]BillsDetailResponse, error) { + return e.GetBillsDetail(ctx, arg, "account/bills-archive", getBillsDetailArchiveEPL) } // ApplyBillDetails apply for bill data since 1 February, 2021 except for the current quarter. // Quarter, valid value is Q1, Q2, Q3, Q4 -func (ok *Okx) ApplyBillDetails(ctx context.Context, year, quarter string) ([]BillsDetailResp, error) { +func (e *Exchange) ApplyBillDetails(ctx context.Context, year, quarter string) ([]BillsDetailResp, error) { if year == "" { return nil, errYearRequired } @@ -1716,11 +1716,11 @@ func (ok *Okx) ApplyBillDetails(ctx context.Context, year, quarter string) ([]Bi return nil, errQuarterValueRequired } var resp []BillsDetailResp - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, billHistoryArchiveEPL, http.MethodPost, "account/bills-history-archive", map[string]string{"year": year, "quarter": quarter}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, billHistoryArchiveEPL, http.MethodPost, "account/bills-history-archive", map[string]string{"year": year, "quarter": quarter}, &resp, request.AuthenticatedRequest) } // GetBillsHistoryArchive retrieves bill data archive -func (ok *Okx) GetBillsHistoryArchive(ctx context.Context, year, quarter string) ([]BillsArchiveInfo, error) { +func (e *Exchange) GetBillsHistoryArchive(ctx context.Context, year, quarter string) ([]BillsArchiveInfo, error) { if year == "" { return nil, errYearRequired } @@ -1731,11 +1731,11 @@ func (ok *Okx) GetBillsHistoryArchive(ctx context.Context, year, quarter string) params.Set("year", year) params.Set("quarter", quarter) var resp []BillsArchiveInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBillHistoryArchiveEPL, http.MethodGet, common.EncodeURLValues("account/bills-history-archive", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBillHistoryArchiveEPL, http.MethodGet, common.EncodeURLValues("account/bills-history-archive", params), nil, &resp, request.AuthenticatedRequest) } // GetBillsDetail retrieves the bills of the account -func (ok *Okx) GetBillsDetail(ctx context.Context, arg *BillsDetailQueryParameter, route string, epl request.EndpointLimit) ([]BillsDetailResponse, error) { +func (e *Exchange) GetBillsDetail(ctx context.Context, arg *BillsDetailQueryParameter, route string, epl request.EndpointLimit) ([]BillsDetailResponse, error) { if *arg == (BillsDetailQueryParameter{}) { return nil, common.ErrEmptyParams } @@ -1777,29 +1777,29 @@ func (ok *Okx) GetBillsDetail(ctx context.Context, arg *BillsDetailQueryParamete params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp []BillsDetailResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) } // GetAccountConfiguration retrieves current account configuration -func (ok *Okx) GetAccountConfiguration(ctx context.Context) (*AccountConfigurationResponse, error) { +func (e *Exchange) GetAccountConfiguration(ctx context.Context) (*AccountConfigurationResponse, error) { var resp *AccountConfigurationResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountConfigurationEPL, http.MethodGet, "account/config", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountConfigurationEPL, http.MethodGet, "account/config", nil, &resp, request.AuthenticatedRequest) } // SetPositionMode FUTURES and SWAP support both long/short mode and net mode. In net mode, users can only have positions in one direction; In long/short mode, users can hold positions in long and short directions. // Position mode 'long_short_mode': long/short, only applicable to FUTURES/SWAP'net_mode': net -func (ok *Okx) SetPositionMode(ctx context.Context, positionMode string) (*PositionMode, error) { +func (e *Exchange) SetPositionMode(ctx context.Context, positionMode string) (*PositionMode, error) { if positionMode != "long_short_mode" && positionMode != "net_mode" { return nil, errInvalidPositionMode } var resp *PositionMode - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setPositionModeEPL, http.MethodPost, "account/set-position-mode", &PositionMode{ + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setPositionModeEPL, http.MethodPost, "account/set-position-mode", &PositionMode{ PositionMode: positionMode, }, &resp, request.AuthenticatedRequest) } // SetLeverageRate sets a leverage setting for instrument id -func (ok *Okx) SetLeverageRate(ctx context.Context, arg *SetLeverageInput) (*SetLeverageResponse, error) { +func (e *Exchange) SetLeverageRate(ctx context.Context, arg *SetLeverageInput) (*SetLeverageResponse, error) { if *arg == (SetLeverageInput{}) { return nil, common.ErrEmptyParams } @@ -1814,11 +1814,11 @@ func (ok *Okx) SetLeverageRate(ctx context.Context, arg *SetLeverageInput) (*Set } arg.PositionSide = strings.ToLower(arg.PositionSide) var resp *SetLeverageResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setLeverageEPL, http.MethodPost, "account/set-leverage", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setLeverageEPL, http.MethodPost, "account/set-leverage", &arg, &resp, request.AuthenticatedRequest) } // GetMaximumBuySellAmountOROpenAmount retrieves the maximum buy or sell amount for a sell id -func (ok *Okx) GetMaximumBuySellAmountOROpenAmount(ctx context.Context, ccy currency.Code, instrumentID, tradeMode, leverage string, price float64, unSpotOffset bool) ([]MaximumBuyAndSell, error) { +func (e *Exchange) GetMaximumBuySellAmountOROpenAmount(ctx context.Context, ccy currency.Code, instrumentID, tradeMode, leverage string, price float64, unSpotOffset bool) ([]MaximumBuyAndSell, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -1843,11 +1843,11 @@ func (ok *Okx) GetMaximumBuySellAmountOROpenAmount(ctx context.Context, ccy curr params.Set("unSpotOffset", "true") } var resp []MaximumBuyAndSell - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumBuyOrSellAmountEPL, http.MethodGet, common.EncodeURLValues("account/max-size", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumBuyOrSellAmountEPL, http.MethodGet, common.EncodeURLValues("account/max-size", params), nil, &resp, request.AuthenticatedRequest) } // GetMaximumAvailableTradableAmount retrieves the maximum tradable amount for specific instrument id, and/or currency -func (ok *Okx) GetMaximumAvailableTradableAmount(ctx context.Context, ccy currency.Code, instrumentID, tradeMode, quickMarginType string, reduceOnly, upSpotOffset bool, price float64) ([]MaximumTradableAmount, error) { +func (e *Exchange) GetMaximumAvailableTradableAmount(ctx context.Context, ccy currency.Code, instrumentID, tradeMode, quickMarginType string, reduceOnly, upSpotOffset bool, price float64) ([]MaximumTradableAmount, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -1874,11 +1874,11 @@ func (ok *Okx) GetMaximumAvailableTradableAmount(ctx context.Context, ccy curren params.Set("upSpotOffset", "true") } var resp []MaximumTradableAmount - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumAvailableTradableAmountEPL, http.MethodGet, common.EncodeURLValues("account/max-avail-size", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumAvailableTradableAmountEPL, http.MethodGet, common.EncodeURLValues("account/max-avail-size", params), nil, &resp, request.AuthenticatedRequest) } // IncreaseDecreaseMargin Increase or decrease the margin of the isolated position. Margin reduction may result in the change of the actual leverage -func (ok *Okx) IncreaseDecreaseMargin(ctx context.Context, arg *IncreaseDecreaseMarginInput) (*IncreaseDecreaseMargin, error) { +func (e *Exchange) IncreaseDecreaseMargin(ctx context.Context, arg *IncreaseDecreaseMarginInput) (*IncreaseDecreaseMargin, error) { if *arg == (IncreaseDecreaseMarginInput{}) { return nil, common.ErrEmptyParams } @@ -1895,11 +1895,11 @@ func (ok *Okx) IncreaseDecreaseMargin(ctx context.Context, arg *IncreaseDecrease return nil, order.ErrAmountBelowMin } var resp *IncreaseDecreaseMargin - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, increaseOrDecreaseMarginEPL, http.MethodPost, "account/position/margin-balance", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, increaseOrDecreaseMarginEPL, http.MethodPost, "account/position/margin-balance", &arg, &resp, request.AuthenticatedRequest) } // GetLeverageRate retrieves leverage data for different instrument id or margin mode -func (ok *Okx) GetLeverageRate(ctx context.Context, instrumentID, marginMode string, ccy currency.Code) ([]LeverageResponse, error) { +func (e *Exchange) GetLeverageRate(ctx context.Context, instrumentID, marginMode string, ccy currency.Code) ([]LeverageResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -1915,12 +1915,12 @@ func (ok *Okx) GetLeverageRate(ctx context.Context, instrumentID, marginMode str params.Set("ccy", ccy.String()) } var resp []LeverageResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeverageEPL, http.MethodGet, common.EncodeURLValues("account/leverage-info", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeverageEPL, http.MethodGet, common.EncodeURLValues("account/leverage-info", params), nil, &resp, request.AuthenticatedRequest) } // GetLeverageEstimatedInfo retrieves leverage estimated information. // Instrument type: possible values are MARGIN, SWAP, FUTURES -func (ok *Okx) GetLeverageEstimatedInfo(ctx context.Context, instrumentType, marginMode, leverage, positionSide, instrumentID string, ccy currency.Code) ([]LeverageEstimatedInfo, error) { +func (e *Exchange) GetLeverageEstimatedInfo(ctx context.Context, instrumentType, marginMode, leverage, positionSide, instrumentID string, ccy currency.Code) ([]LeverageEstimatedInfo, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -1947,11 +1947,11 @@ func (ok *Okx) GetLeverageEstimatedInfo(ctx context.Context, instrumentType, mar params.Set("posSide", positionSide) } var resp []LeverageEstimatedInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeverateEstimatedInfoEPL, http.MethodGet, common.EncodeURLValues("account/adjust-leverage-info", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeverateEstimatedInfoEPL, http.MethodGet, common.EncodeURLValues("account/adjust-leverage-info", params), nil, &resp, request.AuthenticatedRequest) } // GetMaximumLoanOfInstrument returns list of maximum loan of instruments -func (ok *Okx) GetMaximumLoanOfInstrument(ctx context.Context, instrumentID, marginMode string, mgnCurrency currency.Code) ([]MaximumLoanInstrument, error) { +func (e *Exchange) GetMaximumLoanOfInstrument(ctx context.Context, instrumentID, marginMode string, mgnCurrency currency.Code) ([]MaximumLoanInstrument, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -1965,20 +1965,20 @@ func (ok *Okx) GetMaximumLoanOfInstrument(ctx context.Context, instrumentID, mar params.Set("mgnCcy", mgnCurrency.String()) } var resp []MaximumLoanInstrument - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTheMaximumLoanOfInstrumentEPL, http.MethodGet, common.EncodeURLValues("account/max-loan", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTheMaximumLoanOfInstrumentEPL, http.MethodGet, common.EncodeURLValues("account/max-loan", params), nil, &resp, request.AuthenticatedRequest) } // GetFee returns Cryptocurrency trade fee, and offline trade fee -func (ok *Okx) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { // Here the Asset Type for the instrument Type is needed for getting the CryptocurrencyTrading Fee. var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - uly, err := ok.GetUnderlying(feeBuilder.Pair, asset.Spot) + uly, err := e.GetUnderlying(feeBuilder.Pair, asset.Spot) if err != nil { return 0, err } - responses, err := ok.GetTradeFee(ctx, instTypeSpot, uly, "", "", "") + responses, err := e.GetTradeFee(ctx, instTypeSpot, uly, "", "", "") if err != nil { return 0, err } else if len(responses) == 0 { @@ -2009,7 +2009,7 @@ func (ok *Okx) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (flo } // GetTradeFee queries the trade fee rates for various instrument types and their respective IDs -func (ok *Okx) GetTradeFee(ctx context.Context, instrumentType, instrumentID, underlying, instrumentFamily, ruleType string) ([]TradeFeeRate, error) { +func (e *Exchange) GetTradeFee(ctx context.Context, instrumentType, instrumentID, underlying, instrumentFamily, ruleType string) ([]TradeFeeRate, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -2028,11 +2028,11 @@ func (ok *Okx) GetTradeFee(ctx context.Context, instrumentType, instrumentID, un params.Set("ruleType", ruleType) } var resp []TradeFeeRate - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFeeRatesEPL, http.MethodGet, common.EncodeURLValues("account/trade-fee", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFeeRatesEPL, http.MethodGet, common.EncodeURLValues("account/trade-fee", params), nil, &resp, request.AuthenticatedRequest) } // GetInterestAccruedData retrieves data on accrued interest -func (ok *Okx) GetInterestAccruedData(ctx context.Context, loanType, limit int64, ccy currency.Code, instrumentID, marginMode string, after, before time.Time) ([]InterestAccruedData, error) { +func (e *Exchange) GetInterestAccruedData(ctx context.Context, loanType, limit int64, ccy currency.Code, instrumentID, marginMode string, after, before time.Time) ([]InterestAccruedData, error) { params := url.Values{} if loanType == 1 || loanType == 2 { params.Set("type", strconv.FormatInt(loanType, 10)) @@ -2056,21 +2056,21 @@ func (ok *Okx) GetInterestAccruedData(ctx context.Context, loanType, limit int64 params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []InterestAccruedData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInterestAccruedDataEPL, http.MethodGet, common.EncodeURLValues("account/interest-accrued", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getInterestAccruedDataEPL, http.MethodGet, common.EncodeURLValues("account/interest-accrued", params), nil, &resp, request.AuthenticatedRequest) } // GetInterestRate get the user's current leveraged currency borrowing interest rate -func (ok *Okx) GetInterestRate(ctx context.Context, ccy currency.Code) ([]InterestRateResponse, error) { +func (e *Exchange) GetInterestRate(ctx context.Context, ccy currency.Code) ([]InterestRateResponse, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []InterestRateResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateEPL, http.MethodGet, common.EncodeURLValues("account/interest-rate", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateEPL, http.MethodGet, common.EncodeURLValues("account/interest-rate", params), nil, &resp, request.AuthenticatedRequest) } // SetGreeks set the display type of Greeks. PA: Greeks in coins BS: Black-Scholes Greeks in dollars -func (ok *Okx) SetGreeks(ctx context.Context, greeksType string) (*GreeksType, error) { +func (e *Exchange) SetGreeks(ctx context.Context, greeksType string) (*GreeksType, error) { greeksType = strings.ToUpper(greeksType) if greeksType != "PA" && greeksType != "BS" { return nil, errMissingValidGreeksType @@ -2079,11 +2079,11 @@ func (ok *Okx) SetGreeks(ctx context.Context, greeksType string) (*GreeksType, e GreeksType: greeksType, } var resp *GreeksType - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setGreeksEPL, http.MethodPost, "account/set-greeks", input, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setGreeksEPL, http.MethodPost, "account/set-greeks", input, &resp, request.AuthenticatedRequest) } // IsolatedMarginTradingSettings configures the currency margin and sets the isolated margin trading mode for futures or perpetual contracts -func (ok *Okx) IsolatedMarginTradingSettings(ctx context.Context, arg *IsolatedMode) (*IsolatedMode, error) { +func (e *Exchange) IsolatedMarginTradingSettings(ctx context.Context, arg *IsolatedMode) (*IsolatedMode, error) { if *arg == (IsolatedMode{}) { return nil, common.ErrEmptyParams } @@ -2097,11 +2097,11 @@ func (ok *Okx) IsolatedMarginTradingSettings(ctx context.Context, arg *IsolatedM return nil, fmt.Errorf("%w, received '%v' only margin and contract instrument types are allowed", errInvalidInstrumentType, arg.InstrumentType) } var resp *IsolatedMode - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, isolatedMarginTradingSettingsEPL, http.MethodPost, "account/set-isolated-mode", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, isolatedMarginTradingSettingsEPL, http.MethodPost, "account/set-isolated-mode", &arg, &resp, request.AuthenticatedRequest) } // ManualBorrowAndRepayInQuickMarginMode initiates a new manual borrow and repayment process in Quick Margin mode -func (ok *Okx) ManualBorrowAndRepayInQuickMarginMode(ctx context.Context, arg *BorrowAndRepay) (*BorrowAndRepay, error) { +func (e *Exchange) ManualBorrowAndRepayInQuickMarginMode(ctx context.Context, arg *BorrowAndRepay) (*BorrowAndRepay, error) { if *arg == (BorrowAndRepay{}) { return nil, common.ErrEmptyParams } @@ -2118,11 +2118,11 @@ func (ok *Okx) ManualBorrowAndRepayInQuickMarginMode(ctx context.Context, arg *B return nil, errMissingInstrumentID } var resp *BorrowAndRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, manualBorrowAndRepayEPL, http.MethodPost, "account/quick-margin-borrow-repay", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, manualBorrowAndRepayEPL, http.MethodPost, "account/quick-margin-borrow-repay", arg, &resp, request.AuthenticatedRequest) } // GetBorrowAndRepayHistoryInQuickMarginMode retrieves borrow and repay history in quick margin mode -func (ok *Okx) GetBorrowAndRepayHistoryInQuickMarginMode(ctx context.Context, instrumentID currency.Pair, ccy currency.Code, side, afterPaginationID, beforePaginationID string, beginTime, endTime time.Time, limit int64) ([]BorrowRepayHistoryItem, error) { +func (e *Exchange) GetBorrowAndRepayHistoryInQuickMarginMode(ctx context.Context, instrumentID currency.Pair, ccy currency.Code, side, afterPaginationID, beforePaginationID string, beginTime, endTime time.Time, limit int64) ([]BorrowRepayHistoryItem, error) { params := url.Values{} if !instrumentID.IsEmpty() { params.Set("instId", instrumentID.String()) @@ -2149,28 +2149,28 @@ func (ok *Okx) GetBorrowAndRepayHistoryInQuickMarginMode(ctx context.Context, in params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []BorrowRepayHistoryItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowAndRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("account/quick-margin-borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowAndRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("account/quick-margin-borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) } // GetMaximumWithdrawals retrieves the maximum transferable amount from a trading account to a funding account for quick margin borrowing and repayment -func (ok *Okx) GetMaximumWithdrawals(ctx context.Context, ccy currency.Code) ([]MaximumWithdrawal, error) { +func (e *Exchange) GetMaximumWithdrawals(ctx context.Context, ccy currency.Code) ([]MaximumWithdrawal, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []MaximumWithdrawal - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumWithdrawalsEPL, http.MethodGet, common.EncodeURLValues("account/max-withdrawal", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMaximumWithdrawalsEPL, http.MethodGet, common.EncodeURLValues("account/max-withdrawal", params), nil, &resp, request.AuthenticatedRequest) } // GetAccountRiskState gets the account risk status. // only applicable to Portfolio margin account -func (ok *Okx) GetAccountRiskState(ctx context.Context) ([]AccountRiskState, error) { +func (e *Exchange) GetAccountRiskState(ctx context.Context) ([]AccountRiskState, error) { var resp []AccountRiskState - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAccountRiskStateEPL, http.MethodGet, "account/risk-state", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAccountRiskStateEPL, http.MethodGet, "account/risk-state", nil, &resp, request.AuthenticatedRequest) } // VIPLoansBorrowAndRepay creates VIP borrow or repay for a currency -func (ok *Okx) VIPLoansBorrowAndRepay(ctx context.Context, arg *LoanBorrowAndReplayInput) (*LoanBorrowAndReplay, error) { +func (e *Exchange) VIPLoansBorrowAndRepay(ctx context.Context, arg *LoanBorrowAndReplayInput) (*LoanBorrowAndReplay, error) { if *arg == (LoanBorrowAndReplayInput{}) { return nil, common.ErrEmptyParams } @@ -2184,11 +2184,11 @@ func (ok *Okx) VIPLoansBorrowAndRepay(ctx context.Context, arg *LoanBorrowAndRep return nil, order.ErrAmountBelowMin } var resp *LoanBorrowAndReplay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, vipLoansBorrowAnsRepayEPL, http.MethodPost, "account/borrow-repay", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, vipLoansBorrowAnsRepayEPL, http.MethodPost, "account/borrow-repay", &arg, &resp, request.AuthenticatedRequest) } // GetBorrowAndRepayHistoryForVIPLoans retrieves borrow and repay history for VIP loans -func (ok *Okx) GetBorrowAndRepayHistoryForVIPLoans(ctx context.Context, ccy currency.Code, after, before time.Time, limit int64) ([]BorrowRepayHistory, error) { +func (e *Exchange) GetBorrowAndRepayHistoryForVIPLoans(ctx context.Context, ccy currency.Code, after, before time.Time, limit int64) ([]BorrowRepayHistory, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2203,11 +2203,11 @@ func (ok *Okx) GetBorrowAndRepayHistoryForVIPLoans(ctx context.Context, ccy curr params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []BorrowRepayHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowAnsRepayHistoryHistoryEPL, http.MethodGet, common.EncodeURLValues("account/borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowAnsRepayHistoryHistoryEPL, http.MethodGet, common.EncodeURLValues("account/borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) } // GetVIPInterestAccruedData retrieves VIP interest accrued data -func (ok *Okx) GetVIPInterestAccruedData(ctx context.Context, ccy currency.Code, orderID string, after, before time.Time, limit int64) ([]VIPInterestData, error) { +func (e *Exchange) GetVIPInterestAccruedData(ctx context.Context, ccy currency.Code, orderID string, after, before time.Time, limit int64) ([]VIPInterestData, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2225,11 +2225,11 @@ func (ok *Okx) GetVIPInterestAccruedData(ctx context.Context, ccy currency.Code, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []VIPInterestData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getVIPInterestAccruedDataEPL, http.MethodGet, common.EncodeURLValues("account/vip-interest-accrued", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getVIPInterestAccruedDataEPL, http.MethodGet, common.EncodeURLValues("account/vip-interest-accrued", params), nil, &resp, request.AuthenticatedRequest) } // GetVIPInterestDeductedData retrieves a VIP interest deducted data -func (ok *Okx) GetVIPInterestDeductedData(ctx context.Context, ccy currency.Code, orderID string, after, before time.Time, limit int64) ([]VIPInterestData, error) { +func (e *Exchange) GetVIPInterestDeductedData(ctx context.Context, ccy currency.Code, orderID string, after, before time.Time, limit int64) ([]VIPInterestData, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2247,12 +2247,12 @@ func (ok *Okx) GetVIPInterestDeductedData(ctx context.Context, ccy currency.Code params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []VIPInterestData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getVIPInterestDeductedDataEPL, http.MethodGet, common.EncodeURLValues("account/vip-interest-deducted", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getVIPInterestDeductedDataEPL, http.MethodGet, common.EncodeURLValues("account/vip-interest-deducted", params), nil, &resp, request.AuthenticatedRequest) } // GetVIPLoanOrderList retrieves VIP loan order list // state: possible values are 1:Borrowing 2:Borrowed 3:Repaying 4:Repaid 5:Borrow failed -func (ok *Okx) GetVIPLoanOrderList(ctx context.Context, orderID, state string, ccy currency.Code, after, before time.Time, limit int64) ([]VIPLoanOrder, error) { +func (e *Exchange) GetVIPLoanOrderList(ctx context.Context, orderID, state string, ccy currency.Code, after, before time.Time, limit int64) ([]VIPLoanOrder, error) { params := url.Values{} if orderID != "" { params.Set("ordId", orderID) @@ -2273,11 +2273,11 @@ func (ok *Okx) GetVIPLoanOrderList(ctx context.Context, orderID, state string, c params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []VIPLoanOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getVIPLoanOrderListEPL, http.MethodGet, common.EncodeURLValues("account/vip-loan-order-list", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getVIPLoanOrderListEPL, http.MethodGet, common.EncodeURLValues("account/vip-loan-order-list", params), nil, &resp, request.AuthenticatedRequest) } // GetVIPLoanOrderDetail retrieves list of loan order details -func (ok *Okx) GetVIPLoanOrderDetail(ctx context.Context, orderID string, ccy currency.Code, after, before time.Time, limit int64) (*VIPLoanOrderDetail, error) { +func (e *Exchange) GetVIPLoanOrderDetail(ctx context.Context, orderID string, ccy currency.Code, after, before time.Time, limit int64) (*VIPLoanOrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2296,11 +2296,11 @@ func (ok *Okx) GetVIPLoanOrderDetail(ctx context.Context, orderID string, ccy cu params.Set("limit", strconv.FormatInt(limit, 10)) } var resp *VIPLoanOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getVIPLoanOrderDetailEPL, http.MethodGet, common.EncodeURLValues("account/vip-loan-order-detail", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getVIPLoanOrderDetailEPL, http.MethodGet, common.EncodeURLValues("account/vip-loan-order-detail", params), nil, &resp, request.AuthenticatedRequest) } // GetBorrowInterestAndLimit borrow interest and limit -func (ok *Okx) GetBorrowInterestAndLimit(ctx context.Context, loanType int64, ccy currency.Code) ([]BorrowInterestAndLimitResponse, error) { +func (e *Exchange) GetBorrowInterestAndLimit(ctx context.Context, loanType int64, ccy currency.Code) ([]BorrowInterestAndLimitResponse, error) { params := url.Values{} if loanType == 1 || loanType == 2 { params.Set("type", strconv.FormatInt(loanType, 10)) @@ -2309,17 +2309,17 @@ func (ok *Okx) GetBorrowInterestAndLimit(ctx context.Context, loanType int64, cc params.Set("ccy", ccy.String()) } var resp []BorrowInterestAndLimitResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowInterestAndLimitEPL, http.MethodGet, common.EncodeURLValues("account/interest-limits", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowInterestAndLimitEPL, http.MethodGet, common.EncodeURLValues("account/interest-limits", params), nil, &resp, request.AuthenticatedRequest) } // GetFixedLoanBorrowLimit retrieves a fixed loadn borrow limit information -func (ok *Okx) GetFixedLoanBorrowLimit(ctx context.Context) (*FixedLoanBorrowLimitInformation, error) { +func (e *Exchange) GetFixedLoanBorrowLimit(ctx context.Context) (*FixedLoanBorrowLimitInformation, error) { var resp *FixedLoanBorrowLimitInformation - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowLimitEPL, http.MethodGet, "account/fixed-loan/borrowing-limit", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowLimitEPL, http.MethodGet, "account/fixed-loan/borrowing-limit", nil, &resp, request.AuthenticatedRequest) } // GetFixedLoanBorrowQuote retrieves a fixed loan borrow quote information -func (ok *Okx) GetFixedLoanBorrowQuote(ctx context.Context, borrowingCurrency currency.Code, borrowType, term, orderID string, amount, maxRate float64) (*FixedLoanBorrowQuote, error) { +func (e *Exchange) GetFixedLoanBorrowQuote(ctx context.Context, borrowingCurrency currency.Code, borrowType, term, orderID string, amount, maxRate float64) (*FixedLoanBorrowQuote, error) { if borrowType == "" { return nil, errBorrowTypeRequired } @@ -2362,11 +2362,11 @@ func (ok *Okx) GetFixedLoanBorrowQuote(ctx context.Context, borrowingCurrency cu params.Set("ordId", orderID) } var resp *FixedLoanBorrowQuote - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowQuoteEPL, http.MethodGet, common.EncodeURLValues("account/fixed-loan/borrowing-quote", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowQuoteEPL, http.MethodGet, common.EncodeURLValues("account/fixed-loan/borrowing-quote", params), nil, &resp, request.AuthenticatedRequest) } // PlaceFixedLoanBorrowingOrder for new borrowing orders, they belong to the IOC (immediately close and cancel the remaining) type. For renewal orders, they belong to the FOK (Fill-or-kill) type -func (ok *Okx) PlaceFixedLoanBorrowingOrder(ctx context.Context, ccy currency.Code, amount, maxRate, reborrowRate float64, term string, reborrow bool) (*OrderIDResponse, error) { +func (e *Exchange) PlaceFixedLoanBorrowingOrder(ctx context.Context, ccy currency.Code, amount, maxRate, reborrowRate float64, term string, reborrow bool) (*OrderIDResponse, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2395,11 +2395,11 @@ func (ok *Okx) PlaceFixedLoanBorrowingOrder(ctx context.Context, ccy currency.Co ReborrowRate: reborrowRate, } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/borrowing-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/borrowing-order", arg, &resp, request.AuthenticatedRequest) } // AmendFixedLoanBorrowingOrder amends a fixed loan borrowing order -func (ok *Okx) AmendFixedLoanBorrowingOrder(ctx context.Context, orderID string, reborrow bool, renewMaxRate float64) (*OrderIDResponse, error) { +func (e *Exchange) AmendFixedLoanBorrowingOrder(ctx context.Context, orderID string, reborrow bool, renewMaxRate float64) (*OrderIDResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2413,11 +2413,11 @@ func (ok *Okx) AmendFixedLoanBorrowingOrder(ctx context.Context, orderID string, RenewMaxRate: renewMaxRate, } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendFixedLaonBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/amend-borrowing-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendFixedLaonBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/amend-borrowing-order", arg, &resp, request.AuthenticatedRequest) } // ManualRenewFixedLoanBorrowingOrder manual renew fixed loan borrowing order -func (ok *Okx) ManualRenewFixedLoanBorrowingOrder(ctx context.Context, orderID string, maxRate float64) (*OrderIDResponse, error) { +func (e *Exchange) ManualRenewFixedLoanBorrowingOrder(ctx context.Context, orderID string, maxRate float64) (*OrderIDResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2432,29 +2432,29 @@ func (ok *Okx) ManualRenewFixedLoanBorrowingOrder(ctx context.Context, orderID s MaxRate: maxRate, } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, manualRenewFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/manual-reborrow", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, manualRenewFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/manual-reborrow", arg, &resp, request.AuthenticatedRequest) } // RepayFixedLoanBorrowingOrder repays fixed loan borrowing order -func (ok *Okx) RepayFixedLoanBorrowingOrder(ctx context.Context, orderID string) (*OrderIDResponse, error) { +func (e *Exchange) RepayFixedLoanBorrowingOrder(ctx context.Context, orderID string) (*OrderIDResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, repayFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/repay-borrowing-order", map[string]string{"ordId": orderID}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, repayFixedLoanBorrowingOrderEPL, http.MethodPost, "account/fixed-loan/repay-borrowing-order", map[string]string{"ordId": orderID}, &resp, request.AuthenticatedRequest) } // ConvertFixedLoanToMarketLoan converts fixed loan to market loan -func (ok *Okx) ConvertFixedLoanToMarketLoan(ctx context.Context, orderID string) (*OrderIDResponse, error) { +func (e *Exchange) ConvertFixedLoanToMarketLoan(ctx context.Context, orderID string) (*OrderIDResponse, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, convertFixedLoanToMarketLoanEPL, http.MethodPost, "account/fixed-loan/convert-to-market-loan", nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, convertFixedLoanToMarketLoanEPL, http.MethodPost, "account/fixed-loan/convert-to-market-loan", nil, &resp, request.AuthenticatedRequest) } // ReduceLiabilitiesForFixedLoan provide the function of "setting pending repay state / canceling pending repay state" for fixed loan order -func (ok *Okx) ReduceLiabilitiesForFixedLoan(ctx context.Context, orderID string, pendingRepay bool) (*ReduceLiabilities, error) { +func (e *Exchange) ReduceLiabilitiesForFixedLoan(ctx context.Context, orderID string, pendingRepay bool) (*ReduceLiabilities, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -2466,12 +2466,12 @@ func (ok *Okx) ReduceLiabilitiesForFixedLoan(ctx context.Context, orderID string PendingRepayment: pendingRepay, } var resp *ReduceLiabilities - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, reduceLiabilitiesForFixedLoanEPL, http.MethodPost, "account/fixed-loan/reduce-liabilities", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, reduceLiabilitiesForFixedLoanEPL, http.MethodPost, "account/fixed-loan/reduce-liabilities", arg, &resp, request.AuthenticatedRequest) } // GetFixedLoanBorrowOrderList retrieves fixed loan borrow order list // State '1': Borrowing '2': Borrowed '3': Settled (Repaid) '4': Borrow failed '5': Overdue '6': Settling '7': Reborrowing '8': Pending repay -func (ok *Okx) GetFixedLoanBorrowOrderList(ctx context.Context, ccy currency.Code, orderID, state, term string, after, before time.Time, limit int64) ([]FixedLoanBorrowOrderDetail, error) { +func (e *Exchange) GetFixedLoanBorrowOrderList(ctx context.Context, ccy currency.Code, orderID, state, term string, after, before time.Time, limit int64) ([]FixedLoanBorrowOrderDetail, error) { params := url.Values{} if orderID != "" { params.Set("ordId", orderID) @@ -2497,11 +2497,11 @@ func (ok *Okx) GetFixedLoanBorrowOrderList(ctx context.Context, ccy currency.Cod params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []FixedLoanBorrowOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowOrderListEPL, http.MethodGet, common.EncodeURLValues("account/fixed-loan/borrowing-orders-list", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFixedLoanBorrowOrderListEPL, http.MethodGet, common.EncodeURLValues("account/fixed-loan/borrowing-orders-list", params), nil, &resp, request.AuthenticatedRequest) } // ManualBorrowOrRepay borrow or repay assets. only applicable to Spot mode (enabled borrowing) -func (ok *Okx) ManualBorrowOrRepay(ctx context.Context, ccy currency.Code, side string, amount float64) (*BorrowOrRepay, error) { +func (e *Exchange) ManualBorrowOrRepay(ctx context.Context, ccy currency.Code, side string, amount float64) (*BorrowOrRepay, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2521,20 +2521,20 @@ func (ok *Okx) ManualBorrowOrRepay(ctx context.Context, ccy currency.Code, side Amount: amount, } var resp *BorrowOrRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, manualBorrowOrRepayEPL, http.MethodPost, "account/spot-manual-borrow-repay", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, manualBorrowOrRepayEPL, http.MethodPost, "account/spot-manual-borrow-repay", arg, &resp, request.AuthenticatedRequest) } // SetAutoRepay represents an auto-repay. Only applicable to Spot mode (enabled borrowing) -func (ok *Okx) SetAutoRepay(ctx context.Context, autoRepay bool) (*AutoRepay, error) { +func (e *Exchange) SetAutoRepay(ctx context.Context, autoRepay bool) (*AutoRepay, error) { arg := AutoRepay{ AutoRepay: autoRepay, } var resp *AutoRepay - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setAutoRepayEPL, http.MethodPost, "account/set-auto-repay", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setAutoRepayEPL, http.MethodPost, "account/set-auto-repay", arg, &resp, request.AuthenticatedRequest) } // GetBorrowRepayHistory retrieve the borrow/repay history under Spot mode -func (ok *Okx) GetBorrowRepayHistory(ctx context.Context, ccy currency.Code, eventType string, after, before time.Time, limit int64) ([]BorrowRepayItem, error) { +func (e *Exchange) GetBorrowRepayHistory(ctx context.Context, ccy currency.Code, eventType string, after, before time.Time, limit int64) ([]BorrowRepayItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2554,21 +2554,21 @@ func (ok *Okx) GetBorrowRepayHistory(ctx context.Context, ccy currency.Code, eve params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []BorrowRepayItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("account/spot-borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBorrowRepayHistoryEPL, http.MethodGet, common.EncodeURLValues("account/spot-borrow-repay-history", params), nil, &resp, request.AuthenticatedRequest) } // NewPositionBuilder calculates portfolio margin information for virtual position/assets or current position of the user. // You can add up to 200 virtual positions and 200 virtual assets in one request -func (ok *Okx) NewPositionBuilder(ctx context.Context, arg *PositionBuilderParam) (*PositionBuilderDetail, error) { +func (e *Exchange) NewPositionBuilder(ctx context.Context, arg *PositionBuilderParam) (*PositionBuilderDetail, error) { if arg == nil { return nil, common.ErrNilPointer } var resp *PositionBuilderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, newPositionBuilderEPL, http.MethodPost, "account/position-builder", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, newPositionBuilderEPL, http.MethodPost, "account/position-builder", arg, &resp, request.AuthenticatedRequest) } // SetRiskOffsetAmount set risk offset amount. This does not represent the actual spot risk offset amount. Only applicable to Portfolio Margin Mode -func (ok *Okx) SetRiskOffsetAmount(ctx context.Context, ccy currency.Code, clientSpotInUseAmount float64) (*RiskOffsetAmount, error) { +func (e *Exchange) SetRiskOffsetAmount(ctx context.Context, ccy currency.Code, clientSpotInUseAmount float64) (*RiskOffsetAmount, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2583,21 +2583,21 @@ func (ok *Okx) SetRiskOffsetAmount(ctx context.Context, ccy currency.Code, clien ClientSpotInUseAmount: clientSpotInUseAmount, } var resp *RiskOffsetAmount - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setRiskOffsetAmountEPL, http.MethodPost, "account/set-riskOffset-amt", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setRiskOffsetAmountEPL, http.MethodPost, "account/set-riskOffset-amt", arg, &resp, request.AuthenticatedRequest) } // GetGreeks retrieves a greeks list of all assets in the account -func (ok *Okx) GetGreeks(ctx context.Context, ccy currency.Code) ([]GreeksItem, error) { +func (e *Exchange) GetGreeks(ctx context.Context, ccy currency.Code) ([]GreeksItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) } var resp []GreeksItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getGreeksEPL, http.MethodGet, common.EncodeURLValues("account/greeks", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getGreeksEPL, http.MethodGet, common.EncodeURLValues("account/greeks", params), nil, &resp, request.AuthenticatedRequest) } // GetPMPositionLimitation retrieve cross position limitation of SWAP/FUTURES/OPTION under Portfolio margin mode -func (ok *Okx) GetPMPositionLimitation(ctx context.Context, instrumentType, underlying, instrumentFamily string) ([]PMLimitationResponse, error) { +func (e *Exchange) GetPMPositionLimitation(ctx context.Context, instrumentType, underlying, instrumentFamily string) ([]PMLimitationResponse, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -2613,7 +2613,7 @@ func (ok *Okx) GetPMPositionLimitation(ctx context.Context, instrumentType, unde params.Set("instFamily", instrumentFamily) } var resp []PMLimitationResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPMLimitationEPL, http.MethodGet, common.EncodeURLValues("account/position-tiers", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPMLimitationEPL, http.MethodGet, common.EncodeURLValues("account/position-tiers", params), nil, &resp, request.AuthenticatedRequest) } // SetRiskOffsetType configure the risk offset type in portfolio margin mode. @@ -2621,37 +2621,37 @@ func (ok *Okx) GetPMPositionLimitation(ctx context.Context, instrumentType, unde // 1: Spot-derivatives (USDT) risk offset // 2: Spot-derivatives (Crypto) risk offset // 3:Derivatives only mode -func (ok *Okx) SetRiskOffsetType(ctx context.Context, riskOffsetType string) (*RiskOffsetType, error) { +func (e *Exchange) SetRiskOffsetType(ctx context.Context, riskOffsetType string) (*RiskOffsetType, error) { if riskOffsetType == "" { return nil, errors.New("missing risk offset type") } var resp *RiskOffsetType - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setRiskOffsetLimiterEPL, http.MethodPost, "account/set-riskOffset-type", &map[string]string{"type": riskOffsetType}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setRiskOffsetLimiterEPL, http.MethodPost, "account/set-riskOffset-type", &map[string]string{"type": riskOffsetType}, &resp, request.AuthenticatedRequest) } // ActivateOption activates option -func (ok *Okx) ActivateOption(ctx context.Context) (types.Time, error) { +func (e *Exchange) ActivateOption(ctx context.Context) (types.Time, error) { resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, activateOptionEPL, http.MethodPost, "account/activate-option", nil, resp, request.AuthenticatedRequest) + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, activateOptionEPL, http.MethodPost, "account/activate-option", nil, resp, request.AuthenticatedRequest) } // SetAutoLoan only applicable to Multi-currency margin and Portfolio margin -func (ok *Okx) SetAutoLoan(ctx context.Context, autoLoan bool) (*AutoLoan, error) { +func (e *Exchange) SetAutoLoan(ctx context.Context, autoLoan bool) (*AutoLoan, error) { var resp *AutoLoan - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setAutoLoanEPL, http.MethodPost, "account/set-auto-loan", &AutoLoan{AutoLoan: autoLoan}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setAutoLoanEPL, http.MethodPost, "account/set-auto-loan", &AutoLoan{AutoLoan: autoLoan}, &resp, request.AuthenticatedRequest) } // SetAccountMode to set on the Web/App for the first set of every account mode. // Account mode 1: Simple mode 2: Single-currency margin mode 3: Multi-currency margin code 4: Portfolio margin mode -func (ok *Okx) SetAccountMode(ctx context.Context, accountLevel string) (*AccountMode, error) { +func (e *Exchange) SetAccountMode(ctx context.Context, accountLevel string) (*AccountMode, error) { var resp *AccountMode - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setAccountLevelEPL, http.MethodPost, "account/set-account-level", &map[string]string{"acctLv": accountLevel}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setAccountLevelEPL, http.MethodPost, "account/set-account-level", &map[string]string{"acctLv": accountLevel}, &resp, request.AuthenticatedRequest) } // ResetMMPStatus reset the MMP status to be inactive. // you can unfreeze by this endpoint once MMP is triggered. // Only applicable to Option in Portfolio Margin mode, and MMP privilege is required -func (ok *Okx) ResetMMPStatus(ctx context.Context, instrumentType, instrumentFamily string) (*MMPStatusResponse, error) { +func (e *Exchange) ResetMMPStatus(ctx context.Context, instrumentType, instrumentFamily string) (*MMPStatusResponse, error) { if instrumentFamily == "" { return nil, errInstrumentFamilyRequired } @@ -2663,12 +2663,12 @@ func (ok *Okx) ResetMMPStatus(ctx context.Context, instrumentType, instrumentFam InstrumentFamily: instrumentFamily, } var resp *MMPStatusResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, resetMMPStatusEPL, http.MethodPost, "account/mmp-reset", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, resetMMPStatusEPL, http.MethodPost, "account/mmp-reset", arg, &resp, request.AuthenticatedRequest) } // SetMMP set MMP configure // Only applicable to Option in Portfolio Margin mode, and MMP privilege is required -func (ok *Okx) SetMMP(ctx context.Context, arg *MMPConfig) (*MMPConfig, error) { +func (e *Exchange) SetMMP(ctx context.Context, arg *MMPConfig) (*MMPConfig, error) { if *arg == (MMPConfig{}) { return nil, common.ErrEmptyParams } @@ -2679,24 +2679,24 @@ func (ok *Okx) SetMMP(ctx context.Context, arg *MMPConfig) (*MMPConfig, error) { return nil, errInvalidQuantityLimit } var resp *MMPConfig - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setMMPEPL, http.MethodPost, "account/mmp-config", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setMMPEPL, http.MethodPost, "account/mmp-config", arg, &resp, request.AuthenticatedRequest) } // GetMMPConfig retrieves MMP configure information // Only applicable to Option in Portfolio Margin mode, and MMP privilege is required -func (ok *Okx) GetMMPConfig(ctx context.Context, instrumentFamily string) ([]MMPConfigDetail, error) { +func (e *Exchange) GetMMPConfig(ctx context.Context, instrumentFamily string) ([]MMPConfigDetail, error) { params := url.Values{} if instrumentFamily != "" { params.Set("instFamily", instrumentFamily) } var resp []MMPConfigDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMMPConfigEPL, http.MethodGet, common.EncodeURLValues("account/mmp-config", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMMPConfigEPL, http.MethodGet, common.EncodeURLValues("account/mmp-config", params), nil, &resp, request.AuthenticatedRequest) } /********************************** Subaccount Endpoints ***************************************************/ // ViewSubAccountList applies to master accounts only -func (ok *Okx) ViewSubAccountList(ctx context.Context, enable bool, subaccountName string, after, before time.Time, limit int64) ([]SubaccountInfo, error) { +func (e *Exchange) ViewSubAccountList(ctx context.Context, enable bool, subaccountName string, after, before time.Time, limit int64) ([]SubaccountInfo, error) { params := url.Values{} if enable { params.Set("enable", "true") @@ -2714,11 +2714,11 @@ func (ok *Okx) ViewSubAccountList(ctx context.Context, enable bool, subaccountNa params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SubaccountInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, viewSubaccountListEPL, http.MethodGet, common.EncodeURLValues("users/subaccount/list", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, viewSubaccountListEPL, http.MethodGet, common.EncodeURLValues("users/subaccount/list", params), nil, &resp, request.AuthenticatedRequest) } // ResetSubAccountAPIKey applies to master accounts only and master accounts APIKey must be linked to IP addresses -func (ok *Okx) ResetSubAccountAPIKey(ctx context.Context, arg *SubAccountAPIKeyParam) (*SubAccountAPIKeyResponse, error) { +func (e *Exchange) ResetSubAccountAPIKey(ctx context.Context, arg *SubAccountAPIKeyParam) (*SubAccountAPIKeyResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -2745,22 +2745,22 @@ func (ok *Okx) ResetSubAccountAPIKey(ctx context.Context, arg *SubAccountAPIKeyP return nil, errInvalidAPIKeyPermission } var resp *SubAccountAPIKeyResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, resetSubAccountAPIKeyEPL, http.MethodPost, "users/subaccount/modify-apikey", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, resetSubAccountAPIKeyEPL, http.MethodPost, "users/subaccount/modify-apikey", &arg, &resp, request.AuthenticatedRequest) } // GetSubaccountTradingBalance query detailed balance info of Trading Account of a sub-account via the master account (applies to master accounts only) -func (ok *Okx) GetSubaccountTradingBalance(ctx context.Context, subaccountName string) ([]SubaccountBalanceResponse, error) { +func (e *Exchange) GetSubaccountTradingBalance(ctx context.Context, subaccountName string) ([]SubaccountBalanceResponse, error) { if subaccountName == "" { return nil, errInvalidSubAccountName } params := url.Values{} params.Set("subAcct", subaccountName) var resp []SubaccountBalanceResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSubaccountTradingBalanceEPL, http.MethodGet, common.EncodeURLValues("account/subaccount/balances", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSubaccountTradingBalanceEPL, http.MethodGet, common.EncodeURLValues("account/subaccount/balances", params), nil, &resp, request.AuthenticatedRequest) } // GetSubaccountFundingBalance query detailed balance info of Funding Account of a sub-account via the master account (applies to master accounts only) -func (ok *Okx) GetSubaccountFundingBalance(ctx context.Context, subaccountName string, ccy currency.Code) ([]FundingBalance, error) { +func (e *Exchange) GetSubaccountFundingBalance(ctx context.Context, subaccountName string, ccy currency.Code) ([]FundingBalance, error) { if subaccountName == "" { return nil, errInvalidSubAccountName } @@ -2770,12 +2770,12 @@ func (ok *Okx) GetSubaccountFundingBalance(ctx context.Context, subaccountName s params.Set("ccy", ccy.String()) } var resp []FundingBalance - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSubaccountFundingBalanceEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSubaccountFundingBalanceEPL, http.MethodGet, common.EncodeURLValues("asset/subaccount/balances", params), nil, &resp, request.AuthenticatedRequest) } // GetSubAccountMaximumWithdrawal retrieve the maximum withdrawal information of a sub-account via the master account (applies to master accounts only). If no currency is specified, the transferable amount of all owned currencies will be returned -func (ok *Okx) GetSubAccountMaximumWithdrawal(ctx context.Context, subAccountName string, ccy currency.Code) ([]SubAccountMaximumWithdrawal, error) { +func (e *Exchange) GetSubAccountMaximumWithdrawal(ctx context.Context, subAccountName string, ccy currency.Code) ([]SubAccountMaximumWithdrawal, error) { if subAccountName == "" { return nil, errInvalidSubAccountName } @@ -2785,13 +2785,13 @@ func (ok *Okx) GetSubAccountMaximumWithdrawal(ctx context.Context, subAccountNam params.Set("ccy", ccy.String()) } var resp []SubAccountMaximumWithdrawal - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSubAccountMaxWithdrawalEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSubAccountMaxWithdrawalEPL, http.MethodGet, common.EncodeURLValues("account/subaccount/max-withdrawal", params), nil, &resp, request.AuthenticatedRequest) } // HistoryOfSubaccountTransfer retrieves subaccount transfer histories; applies to master accounts only. // retrieve the transfer data for the last 3 months -func (ok *Okx) HistoryOfSubaccountTransfer(ctx context.Context, ccy currency.Code, subaccountType, subaccountName string, before, after time.Time, limit int64) ([]SubaccountBillItem, error) { +func (e *Exchange) HistoryOfSubaccountTransfer(ctx context.Context, ccy currency.Code, subaccountType, subaccountName string, before, after time.Time, limit int64) ([]SubaccountBillItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2812,12 +2812,12 @@ func (ok *Okx) HistoryOfSubaccountTransfer(ctx context.Context, ccy currency.Cod params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SubaccountBillItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, historyOfSubaccountTransferEPL, http.MethodGet, common.EncodeURLValues("asset/subaccount/bills", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, historyOfSubaccountTransferEPL, http.MethodGet, common.EncodeURLValues("asset/subaccount/bills", params), nil, &resp, request.AuthenticatedRequest) } // GetHistoryOfManagedSubAccountTransfer retrieves managed sub-account transfers. // nly applicable to the trading team's master account to getting transfer records of managed sub accounts entrusted to oneself -func (ok *Okx) GetHistoryOfManagedSubAccountTransfer(ctx context.Context, ccy currency.Code, transferType, subAccountName, subAccountUID string, after, before time.Time, limit int64) ([]SubAccountTransfer, error) { +func (e *Exchange) GetHistoryOfManagedSubAccountTransfer(ctx context.Context, ccy currency.Code, transferType, subAccountName, subAccountUID string, after, before time.Time, limit int64) ([]SubAccountTransfer, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -2841,11 +2841,11 @@ func (ok *Okx) GetHistoryOfManagedSubAccountTransfer(ctx context.Context, ccy cu params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SubAccountTransfer - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, managedSubAccountTransferEPL, http.MethodGet, common.EncodeURLValues("asset/subaccount/managed-subaccount-bills", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, managedSubAccountTransferEPL, http.MethodGet, common.EncodeURLValues("asset/subaccount/managed-subaccount-bills", params), nil, &resp, request.AuthenticatedRequest) } // MasterAccountsManageTransfersBetweenSubaccounts master accounts manage the transfers between sub-accounts applies to master accounts only -func (ok *Okx) MasterAccountsManageTransfersBetweenSubaccounts(ctx context.Context, arg *SubAccountAssetTransferParams) ([]TransferIDInfo, error) { +func (e *Exchange) MasterAccountsManageTransfersBetweenSubaccounts(ctx context.Context, arg *SubAccountAssetTransferParams) ([]TransferIDInfo, error) { if *arg == (SubAccountAssetTransferParams{}) { return nil, common.ErrEmptyParams } @@ -2868,11 +2868,11 @@ func (ok *Okx) MasterAccountsManageTransfersBetweenSubaccounts(ctx context.Conte return nil, errInvalidSubAccountName } var resp []TransferIDInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, masterAccountsManageTransfersBetweenSubaccountEPL, http.MethodPost, "asset/subaccount/transfer", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, masterAccountsManageTransfersBetweenSubaccountEPL, http.MethodPost, "asset/subaccount/transfer", &arg, &resp, request.AuthenticatedRequest) } // SetPermissionOfTransferOut set permission of transfer out for sub-account(only applicable to master account). Sub-account can transfer out to master account by default -func (ok *Okx) SetPermissionOfTransferOut(ctx context.Context, arg *PermissionOfTransfer) ([]PermissionOfTransfer, error) { +func (e *Exchange) SetPermissionOfTransferOut(ctx context.Context, arg *PermissionOfTransfer) ([]PermissionOfTransfer, error) { if *arg == (PermissionOfTransfer{}) { return nil, common.ErrEmptyParams } @@ -2880,22 +2880,22 @@ func (ok *Okx) SetPermissionOfTransferOut(ctx context.Context, arg *PermissionOf return nil, errInvalidSubAccountName } var resp []PermissionOfTransfer - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setPermissionOfTransferOutEPL, http.MethodPost, "users/subaccount/set-transfer-out", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setPermissionOfTransferOutEPL, http.MethodPost, "users/subaccount/set-transfer-out", &arg, &resp, request.AuthenticatedRequest) } // GetCustodyTradingSubaccountList the trading team uses this interface to view the list of sub-accounts currently under escrow // usersEntrustSubaccountList ="users/entrust-subaccount-list" -func (ok *Okx) GetCustodyTradingSubaccountList(ctx context.Context, subaccountName string) ([]SubaccountName, error) { +func (e *Exchange) GetCustodyTradingSubaccountList(ctx context.Context, subaccountName string) ([]SubaccountName, error) { params := url.Values{} if subaccountName != "" { params.Set("setAcct", subaccountName) } var resp []SubaccountName - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getCustodyTradingSubaccountListEPL, http.MethodGet, common.EncodeURLValues("users/entrust-subaccount-list", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getCustodyTradingSubaccountListEPL, http.MethodGet, common.EncodeURLValues("users/entrust-subaccount-list", params), nil, &resp, request.AuthenticatedRequest) } // SetSubAccountVIPLoanAllocation set the VIP loan allocation of sub-accounts. Only Applicable to master account API keys with Trade access -func (ok *Okx) SetSubAccountVIPLoanAllocation(ctx context.Context, arg *SubAccountLoanAllocationParam) (bool, error) { +func (e *Exchange) SetSubAccountVIPLoanAllocation(ctx context.Context, arg *SubAccountLoanAllocationParam) (bool, error) { if len(arg.Alloc) == 0 { return false, common.ErrEmptyParams } @@ -2913,12 +2913,12 @@ func (ok *Okx) SetSubAccountVIPLoanAllocation(ctx context.Context, arg *SubAccou resp := &struct { Result bool `json:"result"` }{} - return resp.Result, ok.SendHTTPRequest(ctx, exchange.RestSpot, setSubAccountVIPLoanAllocationEPL, http.MethodPost, "account/subaccount/set-loan-allocation", arg, resp, request.AuthenticatedRequest) + return resp.Result, e.SendHTTPRequest(ctx, exchange.RestSpot, setSubAccountVIPLoanAllocationEPL, http.MethodPost, "account/subaccount/set-loan-allocation", arg, resp, request.AuthenticatedRequest) } // GetSubAccountBorrowInterestAndLimit retrieves sub-account borrow interest and limit // Only applicable to master account API keys. Only return VIP loan information -func (ok *Okx) GetSubAccountBorrowInterestAndLimit(ctx context.Context, subAccount string, ccy currency.Code) ([]SubAccounBorrowInterestAndLimit, error) { +func (e *Exchange) GetSubAccountBorrowInterestAndLimit(ctx context.Context, subAccount string, ccy currency.Code) ([]SubAccounBorrowInterestAndLimit, error) { if subAccount == "" { return nil, errInvalidSubAccountName } @@ -2928,13 +2928,13 @@ func (ok *Okx) GetSubAccountBorrowInterestAndLimit(ctx context.Context, subAccou params.Set("ccy", ccy.String()) } var resp []SubAccounBorrowInterestAndLimit - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSubAccountBorrowInterestAndLimitEPL, http.MethodGet, common.EncodeURLValues("account/subaccount/interest-limits", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSubAccountBorrowInterestAndLimitEPL, http.MethodGet, common.EncodeURLValues("account/subaccount/interest-limits", params), nil, &resp, request.AuthenticatedRequest) } /*************************************** Grid Trading Endpoints ***************************************************/ // PlaceGridAlgoOrder place spot grid algo order -func (ok *Okx) PlaceGridAlgoOrder(ctx context.Context, arg *GridAlgoOrder) (*GridAlgoOrderIDResponse, error) { +func (e *Exchange) PlaceGridAlgoOrder(ctx context.Context, arg *GridAlgoOrder) (*GridAlgoOrderIDResponse, error) { if *arg == (GridAlgoOrder{}) { return nil, common.ErrEmptyParams } @@ -2968,7 +2968,7 @@ func (ok *Okx) PlaceGridAlgoOrder(ctx context.Context, arg *GridAlgoOrder) (*Gri } } var resp *GridAlgoOrderIDResponse - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, gridTradingEPL, http.MethodPost, "tradingBot/grid/order-algo", &arg, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, gridTradingEPL, http.MethodPost, "tradingBot/grid/order-algo", &arg, &resp, request.AuthenticatedRequest) if err != nil { if resp != nil && resp.StatusMessage != "" { return nil, fmt.Errorf("%w; %w", err, getStatusError(resp.StatusCode, resp.StatusMessage)) @@ -2979,7 +2979,7 @@ func (ok *Okx) PlaceGridAlgoOrder(ctx context.Context, arg *GridAlgoOrder) (*Gri } // AmendGridAlgoOrder supported contract grid algo order amendment -func (ok *Okx) AmendGridAlgoOrder(ctx context.Context, arg *GridAlgoOrderAmend) (*GridAlgoOrderIDResponse, error) { +func (e *Exchange) AmendGridAlgoOrder(ctx context.Context, arg *GridAlgoOrderAmend) (*GridAlgoOrderIDResponse, error) { if *arg == (GridAlgoOrderAmend{}) { return nil, common.ErrEmptyParams } @@ -2990,7 +2990,7 @@ func (ok *Okx) AmendGridAlgoOrder(ctx context.Context, arg *GridAlgoOrderAmend) return nil, errMissingInstrumentID } var resp *GridAlgoOrderIDResponse - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, amendGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/amend-order-algo", &arg, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, amendGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/amend-order-algo", &arg, &resp, request.AuthenticatedRequest) if err != nil { if resp != nil && resp.StatusMessage == "" { return nil, fmt.Errorf("%w; %w", err, getStatusError(resp.StatusCode, resp.StatusMessage)) @@ -3002,7 +3002,7 @@ func (ok *Okx) AmendGridAlgoOrder(ctx context.Context, arg *GridAlgoOrderAmend) // StopGridAlgoOrder stop a batch of grid algo orders. // A maximum of 10 orders can be canceled per request -func (ok *Okx) StopGridAlgoOrder(ctx context.Context, arg []StopGridAlgoOrderRequest) ([]GridAlgoOrderIDResponse, error) { +func (e *Exchange) StopGridAlgoOrder(ctx context.Context, arg []StopGridAlgoOrderRequest) ([]GridAlgoOrderIDResponse, error) { if len(arg) == 0 { return nil, common.ErrEmptyParams } @@ -3025,7 +3025,7 @@ func (ok *Okx) StopGridAlgoOrder(ctx context.Context, arg []StopGridAlgoOrderReq } } var resp []GridAlgoOrderIDResponse - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, stopGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/stop-order-algo", arg, &resp, request.AuthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, stopGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/stop-order-algo", arg, &resp, request.AuthenticatedRequest) if err != nil { if len(resp) == 0 { return nil, err @@ -3042,7 +3042,7 @@ func (ok *Okx) StopGridAlgoOrder(ctx context.Context, arg []StopGridAlgoOrderReq } // ClosePositionForContractID close position when the contract grid stop type is 'keep position' -func (ok *Okx) ClosePositionForContractID(ctx context.Context, arg *ClosePositionParams) (*ClosePositionContractGridResponse, error) { +func (e *Exchange) ClosePositionForContractID(ctx context.Context, arg *ClosePositionParams) (*ClosePositionContractGridResponse, error) { if *arg == (ClosePositionParams{}) { return nil, common.ErrEmptyParams } @@ -3056,11 +3056,11 @@ func (ok *Okx) ClosePositionForContractID(ctx context.Context, arg *ClosePositio return nil, order.ErrPriceBelowMin } var resp *ClosePositionContractGridResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, closePositionForForContractGridEPL, http.MethodPost, "tradingBot/grid/close-position", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, closePositionForForContractGridEPL, http.MethodPost, "tradingBot/grid/close-position", arg, &resp, request.AuthenticatedRequest) } // CancelClosePositionOrderForContractGrid cancels close position order for contract grid -func (ok *Okx) CancelClosePositionOrderForContractGrid(ctx context.Context, arg *CancelClosePositionOrder) (*ClosePositionContractGridResponse, error) { +func (e *Exchange) CancelClosePositionOrderForContractGrid(ctx context.Context, arg *CancelClosePositionOrder) (*ClosePositionContractGridResponse, error) { if *arg == (CancelClosePositionOrder{}) { return nil, common.ErrEmptyParams } @@ -3071,37 +3071,37 @@ func (ok *Okx) CancelClosePositionOrderForContractGrid(ctx context.Context, arg return nil, order.ErrOrderIDNotSet } var resp *ClosePositionContractGridResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelClosePositionOrderForContractGridEPL, http.MethodPost, "tradingBot/grid/cancel-close-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelClosePositionOrderForContractGridEPL, http.MethodPost, "tradingBot/grid/cancel-close-order", arg, &resp, request.AuthenticatedRequest) } // InstantTriggerGridAlgoOrder triggers grid algo order -func (ok *Okx) InstantTriggerGridAlgoOrder(ctx context.Context, algoID string) (*TriggeredGridAlgoOrderInfo, error) { +func (e *Exchange) InstantTriggerGridAlgoOrder(ctx context.Context, algoID string) (*TriggeredGridAlgoOrderInfo, error) { var resp *TriggeredGridAlgoOrderInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, instantTriggerGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/order-instant-trigger", &map[string]string{"algoId": algoID}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, instantTriggerGridAlgoOrderEPL, http.MethodPost, "tradingBot/grid/order-instant-trigger", &map[string]string{"algoId": algoID}, &resp, request.AuthenticatedRequest) } // GetGridAlgoOrdersList retrieves list of pending grid algo orders with the complete data -func (ok *Okx) GetGridAlgoOrdersList(ctx context.Context, algoOrderType, algoID, +func (e *Exchange) GetGridAlgoOrdersList(ctx context.Context, algoOrderType, algoID, instrumentID, instrumentType, after, before string, limit int64, ) ([]GridAlgoOrderResponse, error) { - return ok.getGridAlgoOrders(ctx, algoOrderType, algoID, + return e.getGridAlgoOrders(ctx, algoOrderType, algoID, instrumentID, instrumentType, after, before, "tradingBot/grid/orders-algo-pending", limit) } // GetGridAlgoOrderHistory retrieves list of grid algo orders with the complete data including the stopped orders -func (ok *Okx) GetGridAlgoOrderHistory(ctx context.Context, algoOrderType, algoID, +func (e *Exchange) GetGridAlgoOrderHistory(ctx context.Context, algoOrderType, algoID, instrumentID, instrumentType, after, before string, limit int64, ) ([]GridAlgoOrderResponse, error) { - return ok.getGridAlgoOrders(ctx, algoOrderType, algoID, + return e.getGridAlgoOrders(ctx, algoOrderType, algoID, instrumentID, instrumentType, after, before, "tradingBot/grid/orders-algo-history", limit) } // getGridAlgoOrderList retrieves list of grid algo orders with the complete data -func (ok *Okx) getGridAlgoOrders(ctx context.Context, algoOrderType, algoID, +func (e *Exchange) getGridAlgoOrders(ctx context.Context, algoOrderType, algoID, instrumentID, instrumentType, after, before, route string, limit int64, ) ([]GridAlgoOrderResponse, error) { @@ -3134,11 +3134,11 @@ func (ok *Okx) getGridAlgoOrders(ctx context.Context, algoOrderType, algoID, epl = getGridAlgoOrderHistoryEPL } var resp []GridAlgoOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.AuthenticatedRequest) } // GetGridAlgoOrderDetails retrieves grid algo order details -func (ok *Okx) GetGridAlgoOrderDetails(ctx context.Context, algoOrderType, algoID string) (*GridAlgoOrderResponse, error) { +func (e *Exchange) GetGridAlgoOrderDetails(ctx context.Context, algoOrderType, algoID string) (*GridAlgoOrderResponse, error) { if algoOrderType != AlgoOrdTypeGrid && algoOrderType != AlgoOrdTypeContractGrid { return nil, errMissingAlgoOrderType @@ -3150,11 +3150,11 @@ func (ok *Okx) GetGridAlgoOrderDetails(ctx context.Context, algoOrderType, algoI params.Set("algoOrdType", algoOrderType) params.Set("algoId", algoID) var resp *GridAlgoOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) } // GetGridAlgoSubOrders retrieves grid algo sub orders -func (ok *Okx) GetGridAlgoSubOrders(ctx context.Context, algoOrderType, algoID, subOrderType, groupID, after, before string, limit int64) ([]GridAlgoOrderResponse, error) { +func (e *Exchange) GetGridAlgoSubOrders(ctx context.Context, algoOrderType, algoID, subOrderType, groupID, after, before string, limit int64) ([]GridAlgoOrderResponse, error) { if algoOrderType != AlgoOrdTypeGrid && algoOrderType != AlgoOrdTypeContractGrid { return nil, errMissingAlgoOrderType @@ -3182,11 +3182,11 @@ func (ok *Okx) GetGridAlgoSubOrders(ctx context.Context, algoOrderType, algoID, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []GridAlgoOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoSubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/sub-orders", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoSubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/sub-orders", params), nil, &resp, request.AuthenticatedRequest) } // GetGridAlgoOrderPositions retrieves grid algo order positions -func (ok *Okx) GetGridAlgoOrderPositions(ctx context.Context, algoOrderType, algoID string) ([]AlgoOrderPosition, error) { +func (e *Exchange) GetGridAlgoOrderPositions(ctx context.Context, algoOrderType, algoID string) ([]AlgoOrderPosition, error) { if algoOrderType != AlgoOrdTypeGrid && algoOrderType != AlgoOrdTypeContractGrid { return nil, errInvalidAlgoOrderType } @@ -3197,11 +3197,11 @@ func (ok *Okx) GetGridAlgoOrderPositions(ctx context.Context, algoOrderType, alg params.Set("algoOrdType", algoOrderType) params.Set("algoId", algoID) var resp []AlgoOrderPosition - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoOrderPositionsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/positions", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getGridAlgoOrderPositionsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/positions", params), nil, &resp, request.AuthenticatedRequest) } // SpotGridWithdrawProfit returns the spot grid orders withdrawal profit given an instrument id -func (ok *Okx) SpotGridWithdrawProfit(ctx context.Context, algoID string) (*AlgoOrderWithdrawalProfit, error) { +func (e *Exchange) SpotGridWithdrawProfit(ctx context.Context, algoID string) (*AlgoOrderWithdrawalProfit, error) { if algoID == "" { return nil, errAlgoIDRequired } @@ -3211,11 +3211,11 @@ func (ok *Okx) SpotGridWithdrawProfit(ctx context.Context, algoID string) (*Algo AlgoID: algoID, } var resp *AlgoOrderWithdrawalProfit - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, spotGridWithdrawIncomeEPL, http.MethodPost, "tradingBot/grid/withdraw-income", input, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, spotGridWithdrawIncomeEPL, http.MethodPost, "tradingBot/grid/withdraw-income", input, &resp, request.AuthenticatedRequest) } // ComputeMarginBalance computes margin balance with 'add' and 'reduce' balance type -func (ok *Okx) ComputeMarginBalance(ctx context.Context, arg MarginBalanceParam) (*ComputeMarginBalance, error) { +func (e *Exchange) ComputeMarginBalance(ctx context.Context, arg MarginBalanceParam) (*ComputeMarginBalance, error) { if arg.AlgoID == "" { return nil, errAlgoIDRequired } @@ -3223,11 +3223,11 @@ func (ok *Okx) ComputeMarginBalance(ctx context.Context, arg MarginBalanceParam) return nil, errInvalidMarginTypeAdjust } var resp *ComputeMarginBalance - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, computeMarginBalanceEPL, http.MethodPost, "tradingBot/grid/compute-margin-balance", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, computeMarginBalanceEPL, http.MethodPost, "tradingBot/grid/compute-margin-balance", &arg, &resp, request.AuthenticatedRequest) } // AdjustMarginBalance retrieves adjust margin balance with 'add' and 'reduce' balance type -func (ok *Okx) AdjustMarginBalance(ctx context.Context, arg *MarginBalanceParam) (*AdjustMarginBalanceResponse, error) { +func (e *Exchange) AdjustMarginBalance(ctx context.Context, arg *MarginBalanceParam) (*AdjustMarginBalanceResponse, error) { if *arg == (MarginBalanceParam{}) { return nil, common.ErrEmptyParams } @@ -3241,11 +3241,11 @@ func (ok *Okx) AdjustMarginBalance(ctx context.Context, arg *MarginBalanceParam) return nil, fmt.Errorf("%w, either percentage or amount is required", order.ErrAmountIsInvalid) } var resp *AdjustMarginBalanceResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, adjustMarginBalanceEPL, http.MethodPost, "tradingBot/grid/margin-balance", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, adjustMarginBalanceEPL, http.MethodPost, "tradingBot/grid/margin-balance", &arg, &resp, request.AuthenticatedRequest) } // GetGridAIParameter retrieves grid AI parameter -func (ok *Okx) GetGridAIParameter(ctx context.Context, algoOrderType, instrumentID, direction, duration string) ([]GridAIParameterResponse, error) { +func (e *Exchange) GetGridAIParameter(ctx context.Context, algoOrderType, instrumentID, direction, duration string) ([]GridAIParameterResponse, error) { if !slices.Contains([]string{"moon_grid", "contract_grid", "grid"}, algoOrderType) { return nil, errInvalidAlgoOrderType } @@ -3263,11 +3263,11 @@ func (ok *Okx) GetGridAIParameter(ctx context.Context, algoOrderType, instrument return nil, errInvalidDuration } var resp []GridAIParameterResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getGridAIParameterEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/ai-param", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getGridAIParameterEPL, http.MethodGet, common.EncodeURLValues("tradingBot/grid/ai-param", params), nil, &resp, request.UnauthenticatedRequest) } // ComputeMinInvestment computes minimum investment -func (ok *Okx) ComputeMinInvestment(ctx context.Context, arg *ComputeInvestmentDataParam) (*InvestmentResult, error) { +func (e *Exchange) ComputeMinInvestment(ctx context.Context, arg *ComputeInvestmentDataParam) (*InvestmentResult, error) { if arg.InstrumentID == "" { return nil, errMissingInstrumentID } @@ -3307,7 +3307,7 @@ func (ok *Okx) ComputeMinInvestment(ctx context.Context, arg *ComputeInvestmentD } } var resp *InvestmentResult - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, computeMinInvestmentEPL, http.MethodPost, "tradingBot/grid/min-investment", arg, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, computeMinInvestmentEPL, http.MethodPost, "tradingBot/grid/min-investment", arg, &resp, request.UnauthenticatedRequest) } // RSIBackTesting relative strength index(RSI) backtesting @@ -3316,7 +3316,7 @@ func (ok *Okx) ComputeMinInvestment(ctx context.Context, arg *ComputeInvestmentD // TriggerCondition: possible values are "cross_up" "cross_down" "above" "below" "cross" Default is cross_down // // Threshold: The value should be an integer between 1 to 100 -func (ok *Okx) RSIBackTesting(ctx context.Context, instrumentID, triggerCondition, duration string, threshold, timePeriod int64, timeFrame kline.Interval) (*RSIBacktestingResponse, error) { +func (e *Exchange) RSIBackTesting(ctx context.Context, instrumentID, triggerCondition, duration string, threshold, timePeriod int64, timeFrame kline.Interval) (*RSIBacktestingResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -3341,14 +3341,14 @@ func (ok *Okx) RSIBackTesting(ctx context.Context, instrumentID, triggerConditio params.Set("duration", duration) } var resp *RSIBacktestingResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rsiBackTestingEPL, http.MethodGet, common.EncodeURLValues("tradingBot/public/rsi-back-testing", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rsiBackTestingEPL, http.MethodGet, common.EncodeURLValues("tradingBot/public/rsi-back-testing", params), nil, &resp, request.UnauthenticatedRequest) } // ****************************************** Signal bot trading ************************************************** // GetSignalBotOrderDetail create and customize your own signals while gaining access to a diverse selection of signals from top providers. // Empower your trading strategies and stay ahead of the game with our comprehensive signal trading platform -func (ok *Okx) GetSignalBotOrderDetail(ctx context.Context, algoOrderType, algoID string) (*SignalBotOrderDetail, error) { +func (e *Exchange) GetSignalBotOrderDetail(ctx context.Context, algoOrderType, algoID string) (*SignalBotOrderDetail, error) { if algoOrderType == "" { return nil, errInvalidAlgoOrderType } @@ -3359,11 +3359,11 @@ func (ok *Okx) GetSignalBotOrderDetail(ctx context.Context, algoOrderType, algoI params.Set("algoId", algoID) params.Set("algoOrdType", algoOrderType) var resp *SignalBotOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, signalBotOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, signalBotOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) } // GetSignalOrderPositions retrieves signal bot order positions -func (ok *Okx) GetSignalOrderPositions(ctx context.Context, algoOrderType, algoID string) (*SignalBotPosition, error) { +func (e *Exchange) GetSignalOrderPositions(ctx context.Context, algoOrderType, algoID string) (*SignalBotPosition, error) { if algoOrderType == "" { return nil, errInvalidAlgoOrderType } @@ -3374,11 +3374,11 @@ func (ok *Okx) GetSignalOrderPositions(ctx context.Context, algoOrderType, algoI params.Set("algoId", algoID) params.Set("algoOrdType", algoOrderType) var resp *SignalBotPosition - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, signalBotOrderPositionsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/positions", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, signalBotOrderPositionsEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/positions", params), nil, &resp, request.AuthenticatedRequest) } // GetSignalBotSubOrders retrieves historical filled sub orders and designated sub orders -func (ok *Okx) GetSignalBotSubOrders(ctx context.Context, algoID, algoOrderType, subOrderType, clientOrderID, afterPaginationID, beforePaginationID string, begin, end time.Time, limit int64) ([]SubOrder, error) { +func (e *Exchange) GetSignalBotSubOrders(ctx context.Context, algoID, algoOrderType, subOrderType, clientOrderID, afterPaginationID, beforePaginationID string, begin, end time.Time, limit int64) ([]SubOrder, error) { if algoID == "" { return nil, errAlgoIDRequired } @@ -3412,11 +3412,11 @@ func (ok *Okx) GetSignalBotSubOrders(ctx context.Context, algoID, algoOrderType, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SubOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, signalBotSubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/sub-orders", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, signalBotSubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/sub-orders", params), nil, &resp, request.AuthenticatedRequest) } // GetSignalBotEventHistory retrieves signal bot event history -func (ok *Okx) GetSignalBotEventHistory(ctx context.Context, algoID string, after, before time.Time, limit int64) ([]SignalBotEventHistory, error) { +func (e *Exchange) GetSignalBotEventHistory(ctx context.Context, algoID string, after, before time.Time, limit int64) ([]SignalBotEventHistory, error) { if algoID == "" { return nil, errAlgoIDRequired } @@ -3432,7 +3432,7 @@ func (ok *Okx) GetSignalBotEventHistory(ctx context.Context, algoID string, afte params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SignalBotEventHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, signalBotEventHistoryEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/event-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, signalBotEventHistoryEPL, http.MethodGet, common.EncodeURLValues("tradingBot/signal/event-history", params), nil, &resp, request.AuthenticatedRequest) } // ****************************************** Recurring Buy ***************************************** @@ -3440,7 +3440,7 @@ func (ok *Okx) GetSignalBotEventHistory(ctx context.Context, algoID string, afte // PlaceRecurringBuyOrder recurring buy is a strategy for investing a fixed amount in crypto at fixed intervals. // An appropriate recurring approach in volatile markets allows you to buy crypto at lower costs. Learn more // The API endpoints of Recurring buy require authentication -func (ok *Okx) PlaceRecurringBuyOrder(ctx context.Context, arg *PlaceRecurringBuyOrderParam) (*RecurringOrderResponse, error) { +func (e *Exchange) PlaceRecurringBuyOrder(ctx context.Context, arg *PlaceRecurringBuyOrderParam) (*RecurringOrderResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -3465,11 +3465,11 @@ func (ok *Okx) PlaceRecurringBuyOrder(ctx context.Context, arg *PlaceRecurringBu return nil, errInvalidTradeModeValue } var resp *RecurringOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/order-algo", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/order-algo", arg, &resp, request.AuthenticatedRequest) } // AmendRecurringBuyOrder amends recurring order -func (ok *Okx) AmendRecurringBuyOrder(ctx context.Context, arg *AmendRecurringOrderParam) (*RecurringOrderResponse, error) { +func (e *Exchange) AmendRecurringBuyOrder(ctx context.Context, arg *AmendRecurringOrderParam) (*RecurringOrderResponse, error) { if (*arg) == (AmendRecurringOrderParam{}) { return nil, common.ErrEmptyParams } @@ -3480,11 +3480,11 @@ func (ok *Okx) AmendRecurringBuyOrder(ctx context.Context, arg *AmendRecurringOr return nil, errStrategyNameRequired } var resp *RecurringOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/amend-order-algo", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/amend-order-algo", arg, &resp, request.AuthenticatedRequest) } // StopRecurringBuyOrder stops recurring buy order. A maximum of 10 orders can be stopped per request -func (ok *Okx) StopRecurringBuyOrder(ctx context.Context, arg []StopRecurringBuyOrder) ([]RecurringOrderResponse, error) { +func (e *Exchange) StopRecurringBuyOrder(ctx context.Context, arg []StopRecurringBuyOrder) ([]RecurringOrderResponse, error) { if len(arg) == 0 { return nil, common.ErrEmptyParams } @@ -3494,11 +3494,11 @@ func (ok *Okx) StopRecurringBuyOrder(ctx context.Context, arg []StopRecurringBuy } } var resp []RecurringOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, stopRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/stop-order-algo", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, stopRecurringBuyOrderEPL, http.MethodPost, "tradingBot/recurring/stop-order-algo", arg, &resp, request.AuthenticatedRequest) } // GetRecurringBuyOrderList retrieves recurring buy order list -func (ok *Okx) GetRecurringBuyOrderList(ctx context.Context, algoID, algoOrderState string, after, before time.Time, limit int64) ([]RecurringOrderItem, error) { +func (e *Exchange) GetRecurringBuyOrderList(ctx context.Context, algoID, algoOrderState string, after, before time.Time, limit int64) ([]RecurringOrderItem, error) { params := url.Values{} if algoOrderState != "" { params.Set("state", algoOrderState) @@ -3516,11 +3516,11 @@ func (ok *Okx) GetRecurringBuyOrderList(ctx context.Context, algoID, algoOrderSt params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []RecurringOrderItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderListEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-pending", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderListEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-pending", params), nil, &resp, request.AuthenticatedRequest) } // GetRecurringBuyOrderHistory retrieves recurring buy order history -func (ok *Okx) GetRecurringBuyOrderHistory(ctx context.Context, algoID string, after, before time.Time, limit int64) ([]RecurringOrderItem, error) { +func (e *Exchange) GetRecurringBuyOrderHistory(ctx context.Context, algoID string, after, before time.Time, limit int64) ([]RecurringOrderItem, error) { params := url.Values{} if algoID != "" { params.Set("algoId", algoID) @@ -3535,11 +3535,11 @@ func (ok *Okx) GetRecurringBuyOrderHistory(ctx context.Context, algoID string, a params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []RecurringOrderItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-history", params), nil, &resp, request.AuthenticatedRequest) } // GetRecurringOrderDetails retrieves a single recurring order detail -func (ok *Okx) GetRecurringOrderDetails(ctx context.Context, algoID, algoOrderState string) (*RecurringOrderDeail, error) { +func (e *Exchange) GetRecurringOrderDetails(ctx context.Context, algoID, algoOrderState string) (*RecurringOrderDeail, error) { if algoID == "" { return nil, errAlgoIDRequired } @@ -3549,11 +3549,11 @@ func (ok *Okx) GetRecurringOrderDetails(ctx context.Context, algoID, algoOrderSt params.Set("state", algoOrderState) } var resp *RecurringOrderDeail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderDetailEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuyOrderDetailEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/orders-algo-details", params), nil, &resp, request.AuthenticatedRequest) } // GetRecurringSubOrders retrieves recurring buy sub orders -func (ok *Okx) GetRecurringSubOrders(ctx context.Context, algoID, orderID string, after, before time.Time, limit int64) ([]RecurringBuySubOrder, error) { +func (e *Exchange) GetRecurringSubOrders(ctx context.Context, algoID, orderID string, after, before time.Time, limit int64) ([]RecurringBuySubOrder, error) { if algoID == "" { return nil, errAlgoIDRequired } @@ -3572,13 +3572,13 @@ func (ok *Okx) GetRecurringSubOrders(ctx context.Context, algoID, orderID string params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []RecurringBuySubOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuySubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/sub-orders", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getRecurringBuySubOrdersEPL, http.MethodGet, common.EncodeURLValues("tradingBot/recurring/sub-orders", params), nil, &resp, request.AuthenticatedRequest) } // ****************************************** Earn ************************************************** // GetExistingLeadingPositions retrieves leading positions that are not closed -func (ok *Okx) GetExistingLeadingPositions(ctx context.Context, instrumentType, instrumentID string, before, after time.Time, limit int64) ([]PositionInfo, error) { +func (e *Exchange) GetExistingLeadingPositions(ctx context.Context, instrumentType, instrumentID string, before, after time.Time, limit int64) ([]PositionInfo, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -3596,12 +3596,12 @@ func (ok *Okx) GetExistingLeadingPositions(ctx context.Context, instrumentType, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PositionInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getExistingLeadingPositionsEPL, http.MethodGet, common.EncodeURLValues("copytrading/current-subpositions", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getExistingLeadingPositionsEPL, http.MethodGet, common.EncodeURLValues("copytrading/current-subpositions", params), nil, &resp, request.AuthenticatedRequest) } // GetLeadingPositionsHistory leading trader retrieves the completed leading position of the last 3 months. // Returns reverse chronological order with subPosId -func (ok *Okx) GetLeadingPositionsHistory(ctx context.Context, instrumentType, instrumentID string, before, after time.Time, limit int64) ([]PositionInfo, error) { +func (e *Exchange) GetLeadingPositionsHistory(ctx context.Context, instrumentType, instrumentID string, before, after time.Time, limit int64) ([]PositionInfo, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -3619,11 +3619,11 @@ func (ok *Okx) GetLeadingPositionsHistory(ctx context.Context, instrumentType, i params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PositionInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("copytrading/subpositions-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("copytrading/subpositions-history", params), nil, &resp, request.AuthenticatedRequest) } // PlaceLeadingStopOrder holds leading trader sets TP/SL for the current leading position that are not closed -func (ok *Okx) PlaceLeadingStopOrder(ctx context.Context, arg *TPSLOrderParam) (*PositionIDInfo, error) { +func (e *Exchange) PlaceLeadingStopOrder(ctx context.Context, arg *TPSLOrderParam) (*PositionIDInfo, error) { if *arg == (TPSLOrderParam{}) { return nil, common.ErrEmptyParams } @@ -3631,11 +3631,11 @@ func (ok *Okx) PlaceLeadingStopOrder(ctx context.Context, arg *TPSLOrderParam) ( return nil, errSubPositionIDRequired } var resp *PositionIDInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeLeadingStopOrderEPL, http.MethodPost, "copytrading/algo-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeLeadingStopOrderEPL, http.MethodPost, "copytrading/algo-order", arg, &resp, request.AuthenticatedRequest) } // CloseLeadingPosition close a leading position once a time -func (ok *Okx) CloseLeadingPosition(ctx context.Context, arg *CloseLeadingPositionParam) (*PositionIDInfo, error) { +func (e *Exchange) CloseLeadingPosition(ctx context.Context, arg *CloseLeadingPositionParam) (*PositionIDInfo, error) { if *arg == (CloseLeadingPositionParam{}) { return nil, common.ErrEmptyParams } @@ -3643,27 +3643,27 @@ func (ok *Okx) CloseLeadingPosition(ctx context.Context, arg *CloseLeadingPositi return nil, errSubPositionIDRequired } var resp *PositionIDInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, closeLeadingPositionEPL, http.MethodPost, "copytrading/close-subposition", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, closeLeadingPositionEPL, http.MethodPost, "copytrading/close-subposition", arg, &resp, request.AuthenticatedRequest) } // GetLeadingInstrument retrieves leading instruments -func (ok *Okx) GetLeadingInstrument(ctx context.Context, instrumentType string) ([]LeadingInstrumentItem, error) { +func (e *Exchange) GetLeadingInstrument(ctx context.Context, instrumentType string) ([]LeadingInstrumentItem, error) { params := url.Values{} if instrumentType == "" { params.Set("instType", instrumentType) } var resp []LeadingInstrumentItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingInstrumentsEPL, http.MethodGet, common.EncodeURLValues("copytrading/instruments", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingInstrumentsEPL, http.MethodGet, common.EncodeURLValues("copytrading/instruments", params), nil, &resp, request.AuthenticatedRequest) } // AmendLeadingInstruments amend current leading instruments, need to set initial leading instruments while applying to become a leading trader. // All non-leading contracts can't have position or pending orders for the current request when setting non-leading contracts as leading contracts -func (ok *Okx) AmendLeadingInstruments(ctx context.Context, instrumentID, instrumentType string) ([]LeadingInstrumentItem, error) { +func (e *Exchange) AmendLeadingInstruments(ctx context.Context, instrumentID, instrumentType string) ([]LeadingInstrumentItem, error) { if instrumentID == "" { return nil, errMissingInstrumentID } var resp []LeadingInstrumentItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingInstrumentsEPL, http.MethodPost, "copytrading/set-instruments", &struct { + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadingInstrumentsEPL, http.MethodPost, "copytrading/set-instruments", &struct { InstrumentType string `json:"instType,omitempty"` InstrumentID string `json:"instId"` }{ @@ -3673,7 +3673,7 @@ func (ok *Okx) AmendLeadingInstruments(ctx context.Context, instrumentID, instru } // GetProfitSharingDetails gets profits shared details for the last 3 months -func (ok *Okx) GetProfitSharingDetails(ctx context.Context, instrumentType string, before, after time.Time, limit int64) ([]ProfitSharingItem, error) { +func (e *Exchange) GetProfitSharingDetails(ctx context.Context, instrumentType string, before, after time.Time, limit int64) ([]ProfitSharingItem, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -3688,49 +3688,49 @@ func (ok *Okx) GetProfitSharingDetails(ctx context.Context, instrumentType strin params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []ProfitSharingItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getProfitSharingLimitEPL, http.MethodGet, common.EncodeURLValues("copytrading/profit-sharing-details", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getProfitSharingLimitEPL, http.MethodGet, common.EncodeURLValues("copytrading/profit-sharing-details", params), nil, &resp, request.AuthenticatedRequest) } // GetTotalProfitSharing gets the total amount of profit shared since joining the platform. // Instrument type 'SPOT' 'SWAP' It returns all types by default -func (ok *Okx) GetTotalProfitSharing(ctx context.Context, instrumentType string) ([]TotalProfitSharing, error) { +func (e *Exchange) GetTotalProfitSharing(ctx context.Context, instrumentType string) ([]TotalProfitSharing, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) } var resp []TotalProfitSharing - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTotalProfitSharingEPL, http.MethodGet, common.EncodeURLValues("copytrading/total-profit-sharing", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTotalProfitSharingEPL, http.MethodGet, common.EncodeURLValues("copytrading/total-profit-sharing", params), nil, &resp, request.AuthenticatedRequest) } // GetUnrealizedProfitSharingDetails gets leading trader gets the profit sharing details that are expected to be shared in the next settlement cycle. // The unrealized profit sharing details will update once there copy position is closed -func (ok *Okx) GetUnrealizedProfitSharingDetails(ctx context.Context, instrumentType string) ([]ProfitSharingItem, error) { +func (e *Exchange) GetUnrealizedProfitSharingDetails(ctx context.Context, instrumentType string) ([]ProfitSharingItem, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) } var resp []ProfitSharingItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTotalProfitSharingEPL, http.MethodGet, common.EncodeURLValues("copytrading/unrealized-profit-sharing-details", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTotalProfitSharingEPL, http.MethodGet, common.EncodeURLValues("copytrading/unrealized-profit-sharing-details", params), nil, &resp, request.AuthenticatedRequest) } // SetFirstCopySettings set first copy settings for the certain lead trader. You need to first copy settings after stopping copying -func (ok *Okx) SetFirstCopySettings(ctx context.Context, arg *FirstCopySettings) (*ResponseResult, error) { +func (e *Exchange) SetFirstCopySettings(ctx context.Context, arg *FirstCopySettings) (*ResponseResult, error) { err := validateFirstCopySettings(arg) if err != nil { return nil, err } var resp *ResponseResult - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setFirstCopySettingsEPL, http.MethodPost, "copytrading/first-copy-settings", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setFirstCopySettingsEPL, http.MethodPost, "copytrading/first-copy-settings", arg, &resp, request.AuthenticatedRequest) } // AmendCopySettings amends need to use this endpoint for amending copy settings -func (ok *Okx) AmendCopySettings(ctx context.Context, arg *FirstCopySettings) (*ResponseResult, error) { +func (e *Exchange) AmendCopySettings(ctx context.Context, arg *FirstCopySettings) (*ResponseResult, error) { err := validateFirstCopySettings(arg) if err != nil { return nil, err } var resp *ResponseResult - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendFirstCopySettingsEPL, http.MethodPost, "copytrading/amend-copy-settings", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendFirstCopySettingsEPL, http.MethodPost, "copytrading/amend-copy-settings", arg, &resp, request.AuthenticatedRequest) } func validateFirstCopySettings(arg *FirstCopySettings) error { @@ -3753,7 +3753,7 @@ func validateFirstCopySettings(arg *FirstCopySettings) error { } // StopCopying need to use this endpoint for amending copy settings -func (ok *Okx) StopCopying(ctx context.Context, arg *StopCopyingParameter) (*ResponseResult, error) { +func (e *Exchange) StopCopying(ctx context.Context, arg *StopCopyingParameter) (*ResponseResult, error) { if *arg == (StopCopyingParameter{}) { return nil, common.ErrEmptyParams } @@ -3764,11 +3764,11 @@ func (ok *Okx) StopCopying(ctx context.Context, arg *StopCopyingParameter) (*Res return nil, errSubPositionCloseTypeRequired } var resp *ResponseResult - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, stopCopyingEPL, http.MethodPost, "copytrading/stop-copy-trading", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, stopCopyingEPL, http.MethodPost, "copytrading/stop-copy-trading", arg, &resp, request.AuthenticatedRequest) } // GetCopySettings retrieve the copy settings about certain lead trader -func (ok *Okx) GetCopySettings(ctx context.Context, instrumentType, uniqueCode string) (*CopySetting, error) { +func (e *Exchange) GetCopySettings(ctx context.Context, instrumentType, uniqueCode string) (*CopySetting, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -3778,11 +3778,11 @@ func (ok *Okx) GetCopySettings(ctx context.Context, instrumentType, uniqueCode s params.Set("instType", instrumentType) } var resp *CopySetting - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getCopySettingsEPL, http.MethodGet, common.EncodeURLValues("copytrading/copy-settings", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getCopySettingsEPL, http.MethodGet, common.EncodeURLValues("copytrading/copy-settings", params), nil, &resp, request.AuthenticatedRequest) } // GetMultipleLeverages retrieve leverages that belong to the lead trader and you -func (ok *Okx) GetMultipleLeverages(ctx context.Context, marginMode, uniqueCode, instrumentID string) ([]Leverages, error) { +func (e *Exchange) GetMultipleLeverages(ctx context.Context, marginMode, uniqueCode, instrumentID string) ([]Leverages, error) { if marginMode == "" { return nil, margin.ErrInvalidMarginType } @@ -3796,11 +3796,11 @@ func (ok *Okx) GetMultipleLeverages(ctx context.Context, marginMode, uniqueCode, params.Set("instId", instrumentID) } var resp []Leverages - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMultipleLeveragesEPL, http.MethodGet, common.EncodeURLValues("copytrading/batch-leverage-info", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMultipleLeveragesEPL, http.MethodGet, common.EncodeURLValues("copytrading/batch-leverage-info", params), nil, &resp, request.AuthenticatedRequest) } // SetMultipleLeverages set Multiple leverages -func (ok *Okx) SetMultipleLeverages(ctx context.Context, arg *SetLeveragesParam) (*SetMultipleLeverageResponse, error) { +func (e *Exchange) SetMultipleLeverages(ctx context.Context, arg *SetLeveragesParam) (*SetMultipleLeverageResponse, error) { if *arg == (SetLeveragesParam{}) { return nil, common.ErrEmptyParams } @@ -3814,21 +3814,21 @@ func (ok *Okx) SetMultipleLeverages(ctx context.Context, arg *SetLeveragesParam) return nil, errMissingInstrumentID } var resp *SetMultipleLeverageResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, setBatchLeverageEPL, http.MethodPost, "copytrading/batch-set-leverage", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, setBatchLeverageEPL, http.MethodPost, "copytrading/batch-set-leverage", arg, &resp, request.AuthenticatedRequest) } // GetMyLeadTraders retrieve my lead traders -func (ok *Okx) GetMyLeadTraders(ctx context.Context, instrumentType string) ([]CopyTradingLeadTrader, error) { +func (e *Exchange) GetMyLeadTraders(ctx context.Context, instrumentType string) ([]CopyTradingLeadTrader, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) } var resp []CopyTradingLeadTrader - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMyLeadTradersEPL, http.MethodGet, common.EncodeURLValues("copytrading/current-lead-traders", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMyLeadTradersEPL, http.MethodGet, common.EncodeURLValues("copytrading/current-lead-traders", params), nil, &resp, request.AuthenticatedRequest) } // GetHistoryLeadTraders retrieve my history lead traders -func (ok *Okx) GetHistoryLeadTraders(ctx context.Context, instrumentType, after, before string, limit int64) ([]CopyTradingLeadTrader, error) { +func (e *Exchange) GetHistoryLeadTraders(ctx context.Context, instrumentType, after, before string, limit int64) ([]CopyTradingLeadTrader, error) { params := url.Values{} if instrumentType != "" { params.Set("instType", instrumentType) @@ -3843,11 +3843,11 @@ func (ok *Okx) GetHistoryLeadTraders(ctx context.Context, instrumentType, after, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []CopyTradingLeadTrader - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMyLeadTradersEPL, http.MethodGet, common.EncodeURLValues("copytrading/lead-traders-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getMyLeadTradersEPL, http.MethodGet, common.EncodeURLValues("copytrading/lead-traders-history", params), nil, &resp, request.AuthenticatedRequest) } // GetLeadTradersRanks retrieves lead trader ranks -func (ok *Okx) GetLeadTradersRanks(ctx context.Context, req *LeadTraderRanksRequest) ([]LeadTradersRank, error) { +func (e *Exchange) GetLeadTradersRanks(ctx context.Context, req *LeadTraderRanksRequest) ([]LeadTradersRank, error) { params := url.Values{} if req.InstrumentType != "" { params.Set("instType", req.InstrumentType) @@ -3883,11 +3883,11 @@ func (ok *Okx) GetLeadTradersRanks(ctx context.Context, req *LeadTraderRanksRequ params.Set("limit", strconv.FormatUint(req.Limit, 10)) } var resp []LeadTradersRank - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderRanksEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-lead-traders", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderRanksEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-lead-traders", params), nil, &resp, request.UnauthenticatedRequest) } // GetWeeklyTraderProfitAndLoss retrieve lead trader weekly pnl. Results are returned in counter chronological order -func (ok *Okx) GetWeeklyTraderProfitAndLoss(ctx context.Context, instrumentType, uniqueCode string) ([]TraderWeeklyProfitAndLoss, error) { +func (e *Exchange) GetWeeklyTraderProfitAndLoss(ctx context.Context, instrumentType, uniqueCode string) ([]TraderWeeklyProfitAndLoss, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -3897,12 +3897,12 @@ func (ok *Okx) GetWeeklyTraderProfitAndLoss(ctx context.Context, instrumentType, params.Set("instType", instrumentType) } var resp []TraderWeeklyProfitAndLoss - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderWeeklyPNLEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-weekly-pnl", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderWeeklyPNLEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-weekly-pnl", params), nil, &resp, request.UnauthenticatedRequest) } // GetDailyLeadTraderPNL retrieve lead trader daily pnl. Results are returned in counter chronological order. // Last days "1": last 7 days "2": last 30 days "3": last 90 days "4": last 365 days -func (ok *Okx) GetDailyLeadTraderPNL(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]TraderWeeklyProfitAndLoss, error) { +func (e *Exchange) GetDailyLeadTraderPNL(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]TraderWeeklyProfitAndLoss, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -3916,11 +3916,11 @@ func (ok *Okx) GetDailyLeadTraderPNL(ctx context.Context, instrumentType, unique params.Set("instType", instrumentType) } var resp []TraderWeeklyProfitAndLoss - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderDailyPNLEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-weekly-pnl", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderDailyPNLEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-weekly-pnl", params), nil, &resp, request.UnauthenticatedRequest) } // GetLeadTraderStats retrieves key data related to lead trader performance -func (ok *Okx) GetLeadTraderStats(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]LeadTraderStat, error) { +func (e *Exchange) GetLeadTraderStats(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]LeadTraderStat, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -3934,11 +3934,11 @@ func (ok *Okx) GetLeadTraderStats(ctx context.Context, instrumentType, uniqueCod params.Set("instType", instrumentType) } var resp []LeadTraderStat - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderStatsEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-stats", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderStatsEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-stats", params), nil, &resp, request.UnauthenticatedRequest) } // GetLeadTraderCurrencyPreferences retrieves the most frequently traded crypto of this lead trader. Results are sorted by ratio from large to small -func (ok *Okx) GetLeadTraderCurrencyPreferences(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]LeadTraderCurrencyPreference, error) { +func (e *Exchange) GetLeadTraderCurrencyPreferences(ctx context.Context, instrumentType, uniqueCode, lastDays string) ([]LeadTraderCurrencyPreference, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -3952,12 +3952,12 @@ func (ok *Okx) GetLeadTraderCurrencyPreferences(ctx context.Context, instrumentT params.Set("instType", instrumentType) } var resp []LeadTraderCurrencyPreference - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderCurrencyPreferencesEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-preference-currency", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderCurrencyPreferencesEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-preference-currency", params), nil, &resp, request.UnauthenticatedRequest) } // GetLeadTraderCurrentLeadPositions get current leading positions of lead trader // Instrument type "SPOT" "SWAP" -func (ok *Okx) GetLeadTraderCurrentLeadPositions(ctx context.Context, instrumentType, uniqueCode, afterSubPositionID, +func (e *Exchange) GetLeadTraderCurrentLeadPositions(ctx context.Context, instrumentType, uniqueCode, afterSubPositionID, beforeSubPositionID string, limit int64, ) ([]LeadTraderCurrentLeadPosition, error) { if uniqueCode == "" { @@ -3978,11 +3978,11 @@ func (ok *Okx) GetLeadTraderCurrentLeadPositions(ctx context.Context, instrument params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []LeadTraderCurrentLeadPosition - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTraderCurrentLeadPositionsEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-current-subpositions", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTraderCurrentLeadPositionsEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-current-subpositions", params), nil, &resp, request.UnauthenticatedRequest) } // GetLeadTraderLeadPositionHistory retrieve the lead trader completed leading position of the last 3 months. Returns reverse chronological order with subPosId -func (ok *Okx) GetLeadTraderLeadPositionHistory(ctx context.Context, instrumentType, uniqueCode, afterSubPositionID, beforeSubPositionID string, limit int64) ([]LeadPosition, error) { +func (e *Exchange) GetLeadTraderLeadPositionHistory(ctx context.Context, instrumentType, uniqueCode, afterSubPositionID, beforeSubPositionID string, limit int64) ([]LeadPosition, error) { if uniqueCode == "" { return nil, errUniqueCodeRequired } @@ -4001,13 +4001,13 @@ func (ok *Okx) GetLeadTraderLeadPositionHistory(ctx context.Context, instrumentT params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []LeadPosition - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderLeadPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-subpositions-history", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLeadTraderLeadPositionHistoryEPL, http.MethodGet, common.EncodeURLValues("copytrading/public-subpositions-history", params), nil, &resp, request.UnauthenticatedRequest) } // ****************************************** Earn ************************************************** // GetOffers retrieves list of offers for different protocols -func (ok *Okx) GetOffers(ctx context.Context, productID, protocolType string, ccy currency.Code) ([]Offer, error) { +func (e *Exchange) GetOffers(ctx context.Context, productID, protocolType string, ccy currency.Code) ([]Offer, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) @@ -4019,11 +4019,11 @@ func (ok *Okx) GetOffers(ctx context.Context, productID, protocolType string, cc params.Set("ccy", ccy.String()) } var resp []Offer - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOfferEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/offers", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOfferEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/offers", params), nil, &resp, request.AuthenticatedRequest) } // Purchase invest on specific product -func (ok *Okx) Purchase(ctx context.Context, arg *PurchaseRequestParam) (*OrderIDResponse, error) { +func (e *Exchange) Purchase(ctx context.Context, arg *PurchaseRequestParam) (*OrderIDResponse, error) { if arg == nil { return nil, common.ErrNilPointer } @@ -4039,11 +4039,11 @@ func (ok *Okx) Purchase(ctx context.Context, arg *PurchaseRequestParam) (*OrderI } } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, purchaseEPL, http.MethodPost, "finance/staking-defi/purchase", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, purchaseEPL, http.MethodPost, "finance/staking-defi/purchase", &arg, &resp, request.AuthenticatedRequest) } // Redeem redemption of investment -func (ok *Okx) Redeem(ctx context.Context, arg *RedeemRequestParam) (*OrderIDResponse, error) { +func (e *Exchange) Redeem(ctx context.Context, arg *RedeemRequestParam) (*OrderIDResponse, error) { if *arg == (RedeemRequestParam{}) { return nil, common.ErrEmptyParams } @@ -4054,12 +4054,12 @@ func (ok *Okx) Redeem(ctx context.Context, arg *RedeemRequestParam) (*OrderIDRes return nil, errInvalidProtocolType } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, redeemEPL, http.MethodPost, "finance/staking-defi/redeem", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, redeemEPL, http.MethodPost, "finance/staking-defi/redeem", &arg, &resp, request.AuthenticatedRequest) } // CancelPurchaseOrRedemption cancels Purchases or Redemptions // after cancelling, returning funds will go to the funding account -func (ok *Okx) CancelPurchaseOrRedemption(ctx context.Context, arg *CancelFundingParam) (*OrderIDResponse, error) { +func (e *Exchange) CancelPurchaseOrRedemption(ctx context.Context, arg *CancelFundingParam) (*OrderIDResponse, error) { if *arg == (CancelFundingParam{}) { return nil, common.ErrEmptyParams } @@ -4070,11 +4070,11 @@ func (ok *Okx) CancelPurchaseOrRedemption(ctx context.Context, arg *CancelFundin return nil, errInvalidProtocolType } var resp *OrderIDResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelPurchaseOrRedemptionEPL, http.MethodPost, "finance/staking-defi/cancel", &arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelPurchaseOrRedemptionEPL, http.MethodPost, "finance/staking-defi/cancel", &arg, &resp, request.AuthenticatedRequest) } // GetEarnActiveOrders retrieves active orders -func (ok *Okx) GetEarnActiveOrders(ctx context.Context, productID, protocolType, state string, ccy currency.Code) ([]ActiveFundingOrder, error) { +func (e *Exchange) GetEarnActiveOrders(ctx context.Context, productID, protocolType, state string, ccy currency.Code) ([]ActiveFundingOrder, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) @@ -4094,12 +4094,12 @@ func (ok *Okx) GetEarnActiveOrders(ctx context.Context, productID, protocolType, params.Set("state", state) } var resp []ActiveFundingOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEarnActiveOrdersEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/orders-active", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEarnActiveOrdersEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/orders-active", params), nil, &resp, request.AuthenticatedRequest) } // GetFundingOrderHistory retrieves funding order history // valid protocol types are 'staking' and 'defi' -func (ok *Okx) GetFundingOrderHistory(ctx context.Context, productID, protocolType string, ccy currency.Code, after, before time.Time, limit int64) ([]ActiveFundingOrder, error) { +func (e *Exchange) GetFundingOrderHistory(ctx context.Context, productID, protocolType string, ccy currency.Code, after, before time.Time, limit int64) ([]ActiveFundingOrder, error) { params := url.Values{} if productID != "" { params.Set("productId", productID) @@ -4120,49 +4120,49 @@ func (ok *Okx) GetFundingOrderHistory(ctx context.Context, productID, protocolTy params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []ActiveFundingOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFundingOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/orders-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFundingOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/orders-history", params), nil, &resp, request.AuthenticatedRequest) } // **************************************************************** ETH Staking **************************************************************** // GetProductInfo retrieves ETH staking products -func (ok *Okx) GetProductInfo(ctx context.Context) (*ProductInfo, error) { +func (e *Exchange) GetProductInfo(ctx context.Context) (*ProductInfo, error) { var resp *ProductInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getProductInfoEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getProductInfoEPL, http.MethodGet, "finance/staking-defi/eth/product-info", nil, &resp, request.AuthenticatedRequest) } // PurchaseETHStaking staking ETH for BETH // Only the assets in the funding account can be used -func (ok *Okx) PurchaseETHStaking(ctx context.Context, amount float64) error { +func (e *Exchange) PurchaseETHStaking(ctx context.Context, amount float64) error { if amount <= 0 { return order.ErrAmountBelowMin } var resp []string - return ok.SendHTTPRequest(ctx, exchange.RestSpot, purchaseETHStakingEPL, http.MethodPost, "finance/staking-defi/eth/purchase", map[string]string{"amt": strconv.FormatFloat(amount, 'f', -1, 64)}, &resp, request.AuthenticatedRequest) + return e.SendHTTPRequest(ctx, exchange.RestSpot, purchaseETHStakingEPL, http.MethodPost, "finance/staking-defi/eth/purchase", map[string]string{"amt": strconv.FormatFloat(amount, 'f', -1, 64)}, &resp, request.AuthenticatedRequest) } // RedeemETHStaking only the assets in the funding account can be used. If your BETH is in your trading account, you can make funding transfer first -func (ok *Okx) RedeemETHStaking(ctx context.Context, amount float64) error { +func (e *Exchange) RedeemETHStaking(ctx context.Context, amount float64) error { if amount <= 0 { return order.ErrAmountBelowMin } var resp []string - return ok.SendHTTPRequest(ctx, exchange.RestSpot, redeemETHStakingEPL, http.MethodPost, "finance/staking-defi/eth/redeem", + return e.SendHTTPRequest(ctx, exchange.RestSpot, redeemETHStakingEPL, http.MethodPost, "finance/staking-defi/eth/redeem", map[string]string{"amt": strconv.FormatFloat(amount, 'f', -1, 64)}, &resp, request.AuthenticatedRequest) } // GetBETHAssetsBalance balance is a snapshot summarized all BETH assets in trading and funding accounts. Also, the snapshot updates hourly -func (ok *Okx) GetBETHAssetsBalance(ctx context.Context) (*BETHAssetsBalance, error) { +func (e *Exchange) GetBETHAssetsBalance(ctx context.Context) (*BETHAssetsBalance, error) { var resp *BETHAssetsBalance - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBETHBalanceEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBETHBalanceEPL, http.MethodGet, "finance/staking-defi/eth/balance", nil, &resp, request.AuthenticatedRequest) } // GetPurchaseAndRedeemHistory retrieves purchase and redeem history // kind possible values are 'purchase' and 'redeem' // Status 'pending' 'success' 'failed' -func (ok *Okx) GetPurchaseAndRedeemHistory(ctx context.Context, kind, status string, after, before time.Time, limit int64) ([]PurchaseRedeemHistory, error) { +func (e *Exchange) GetPurchaseAndRedeemHistory(ctx context.Context, kind, status string, after, before time.Time, limit int64) ([]PurchaseRedeemHistory, error) { if kind == "" { return nil, fmt.Errorf("%w, possible values are 'purchase' and 'redeem'", errLendingTermIsRequired) } @@ -4181,21 +4181,21 @@ func (ok *Okx) GetPurchaseAndRedeemHistory(ctx context.Context, kind, status str params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PurchaseRedeemHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPurchaseRedeemHistoryEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPurchaseRedeemHistoryEPL, http.MethodGet, common.EncodeURLValues("finance/staking-defi/eth/purchase-redeem-history", params), nil, &resp, request.AuthenticatedRequest) } // GetAPYHistory retrieves Annual percentage yield(APY) history -func (ok *Okx) GetAPYHistory(ctx context.Context, days int64) ([]APYItem, error) { +func (e *Exchange) GetAPYHistory(ctx context.Context, days int64) ([]APYItem, error) { if days == 0 || days > 365 { return nil, errors.New("field days is required; possible values from 1 to 365") } var resp []APYItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAPYHistoryEPL, http.MethodGet, fmt.Sprintf("finance/staking-defi/eth/apy-history?days=%d", days), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAPYHistoryEPL, http.MethodGet, fmt.Sprintf("finance/staking-defi/eth/apy-history?days=%d", days), nil, &resp, request.UnauthenticatedRequest) } // GetTickers retrieves the latest price snapshots best bid/ ask price, and trading volume in the last 24 hours -func (ok *Okx) GetTickers(ctx context.Context, instType, uly, instFamily string) ([]TickerResponse, error) { +func (e *Exchange) GetTickers(ctx context.Context, instType, uly, instFamily string) ([]TickerResponse, error) { if instType == "" { return nil, errInvalidInstrumentType } @@ -4208,22 +4208,22 @@ func (ok *Okx) GetTickers(ctx context.Context, instType, uly, instFamily string) params.Set("uly", uly) } var response []TickerResponse - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTickersEPL, http.MethodGet, common.EncodeURLValues("market/tickers", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getTickersEPL, http.MethodGet, common.EncodeURLValues("market/tickers", params), nil, &response, request.UnauthenticatedRequest) } // GetTicker retrieves the latest price snapshot, best bid/ask price, and trading volume in the last 24 hours -func (ok *Okx) GetTicker(ctx context.Context, instrumentID string) (*TickerResponse, error) { +func (e *Exchange) GetTicker(ctx context.Context, instrumentID string) (*TickerResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp *TickerResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTickerEPL, http.MethodGet, common.EncodeURLValues("market/ticker", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTickerEPL, http.MethodGet, common.EncodeURLValues("market/ticker", params), nil, &resp, request.UnauthenticatedRequest) } // GetPremiumHistory returns premium data in the past 6 months -func (ok *Okx) GetPremiumHistory(ctx context.Context, instrumentID string, after, before time.Time, limit int64) ([]PremiumInfo, error) { +func (e *Exchange) GetPremiumHistory(ctx context.Context, instrumentID string, after, before time.Time, limit int64) ([]PremiumInfo, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4241,11 +4241,11 @@ func (ok *Okx) GetPremiumHistory(ctx context.Context, instrumentID string, after params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []PremiumInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPremiumHistoryEPL, http.MethodGet, common.EncodeURLValues("public/premium-history", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getPremiumHistoryEPL, http.MethodGet, common.EncodeURLValues("public/premium-history", params), nil, &resp, request.UnauthenticatedRequest) } // GetIndexTickers Retrieves index tickers -func (ok *Okx) GetIndexTickers(ctx context.Context, quoteCurrency currency.Code, instID string) ([]IndexTicker, error) { +func (e *Exchange) GetIndexTickers(ctx context.Context, quoteCurrency currency.Code, instID string) ([]IndexTicker, error) { if instID == "" && quoteCurrency.IsEmpty() { return nil, fmt.Errorf("%w, QuoteCurrency or InstrumentID is required", errEitherInstIDOrCcyIsRequired) } @@ -4257,7 +4257,7 @@ func (ok *Okx) GetIndexTickers(ctx context.Context, quoteCurrency currency.Code, params.Set("instId", instID) } var resp []IndexTicker - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getIndexTickersEPL, http.MethodGet, common.EncodeURLValues("market/index-tickers", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getIndexTickersEPL, http.MethodGet, common.EncodeURLValues("market/index-tickers", params), nil, &resp, request.UnauthenticatedRequest) } // GetInstrumentTypeFromAssetItem returns a string representation of asset.Item; which is an equivalent term for InstrumentType in Okx exchange @@ -4273,11 +4273,11 @@ func GetInstrumentTypeFromAssetItem(a asset.Item) string { } // GetUnderlying returns the instrument ID for the corresponding asset pairs and asset type( Instrument Type ) -func (ok *Okx) GetUnderlying(pair currency.Pair, a asset.Item) (string, error) { +func (e *Exchange) GetUnderlying(pair currency.Pair, a asset.Item) (string, error) { if !pair.IsPopulated() { return "", currency.ErrCurrencyPairsEmpty } - format, err := ok.GetPairFormat(a, false) + format, err := e.GetPairFormat(a, false) if err != nil { return "", err } @@ -4285,7 +4285,7 @@ func (ok *Okx) GetUnderlying(pair currency.Pair, a asset.Item) (string, error) { } // GetPairFromInstrumentID returns a currency pair give an instrument ID and asset Item, which represents the instrument type -func (ok *Okx) GetPairFromInstrumentID(instrumentID string) (currency.Pair, error) { +func (e *Exchange) GetPairFromInstrumentID(instrumentID string) (currency.Pair, error) { codes := strings.Split(instrumentID, currency.DashDelimiter) if len(codes) >= 2 { instrumentID = codes[0] + currency.DashDelimiter + strings.Join(codes[1:], currency.DashDelimiter) @@ -4294,7 +4294,7 @@ func (ok *Okx) GetPairFromInstrumentID(instrumentID string) (currency.Pair, erro } // GetOrderBookDepth returns the recent order asks and bids before specified timestamp -func (ok *Okx) GetOrderBookDepth(ctx context.Context, instrumentID string, depth int64) (*OrderBookResponseDetail, error) { +func (e *Exchange) GetOrderBookDepth(ctx context.Context, instrumentID string, depth int64) (*OrderBookResponseDetail, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4304,7 +4304,7 @@ func (ok *Okx) GetOrderBookDepth(ctx context.Context, instrumentID string, depth params.Set("sz", strconv.FormatInt(depth, 10)) } var resp *OrderBookResponseDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOrderBookEPL, http.MethodGet, common.EncodeURLValues("market/books", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOrderBookEPL, http.MethodGet, common.EncodeURLValues("market/books", params), nil, &resp, request.UnauthenticatedRequest) } // IntervalFromString returns a kline.Interval instance from string @@ -4362,37 +4362,37 @@ func IntervalFromString(interval kline.Interval, appendUTC bool) string { } // GetCandlesticks retrieve the candlestick charts. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar -func (ok *Okx) GetCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { - return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/candles", getCandlesticksEPL) +func (e *Exchange) GetCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { + return e.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/candles", getCandlesticksEPL) } // GetCandlesticksHistory retrieve history candlestick charts from recent years -func (ok *Okx) GetCandlesticksHistory(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { - return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/history-candles", getCandlestickHistoryEPL) +func (e *Exchange) GetCandlesticksHistory(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { + return e.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/history-candles", getCandlestickHistoryEPL) } // GetIndexCandlesticks retrieve the candlestick charts of the index. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar. // the response is a list of Candlestick data -func (ok *Okx) GetIndexCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { - return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/index-candles", getIndexCandlesticksEPL) +func (e *Exchange) GetIndexCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { + return e.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/index-candles", getIndexCandlesticksEPL) } // GetMarkPriceCandlesticks retrieve the candlestick charts of mark price. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar -func (ok *Okx) GetMarkPriceCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { - return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/mark-price-candles", getCandlestickHistoryEPL) +func (e *Exchange) GetMarkPriceCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) { + return e.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, "market/mark-price-candles", getCandlestickHistoryEPL) } // GetHistoricIndexCandlesticksHistory retrieve the candlestick charts of the index from recent years -func (ok *Okx) GetHistoricIndexCandlesticksHistory(ctx context.Context, instrumentID string, after, before time.Time, bar kline.Interval, limit int64) ([]CandlestickHistoryItem, error) { - return ok.getHistoricCandlesticks(ctx, instrumentID, "market/history-index-candles", after, before, bar, limit, getIndexCandlesticksHistoryEPL) +func (e *Exchange) GetHistoricIndexCandlesticksHistory(ctx context.Context, instrumentID string, after, before time.Time, bar kline.Interval, limit int64) ([]CandlestickHistoryItem, error) { + return e.getHistoricCandlesticks(ctx, instrumentID, "market/history-index-candles", after, before, bar, limit, getIndexCandlesticksHistoryEPL) } // GetMarkPriceCandlestickHistory retrieve the candlestick charts of the mark price from recent years -func (ok *Okx) GetMarkPriceCandlestickHistory(ctx context.Context, instrumentID string, after, before time.Time, bar kline.Interval, limit int64) ([]CandlestickHistoryItem, error) { - return ok.getHistoricCandlesticks(ctx, instrumentID, "market/history-mark-price-candles", after, before, bar, limit, getMarkPriceCandlesticksHistoryEPL) +func (e *Exchange) GetMarkPriceCandlestickHistory(ctx context.Context, instrumentID string, after, before time.Time, bar kline.Interval, limit int64) ([]CandlestickHistoryItem, error) { + return e.getHistoricCandlesticks(ctx, instrumentID, "market/history-mark-price-candles", after, before, bar, limit, getMarkPriceCandlesticksHistoryEPL) } -func (ok *Okx) getHistoricCandlesticks(ctx context.Context, instrumentID, path string, after, before time.Time, bar kline.Interval, limit int64, epl request.EndpointLimit) ([]CandlestickHistoryItem, error) { +func (e *Exchange) getHistoricCandlesticks(ctx context.Context, instrumentID, path string, after, before time.Time, bar kline.Interval, limit int64, epl request.EndpointLimit) ([]CandlestickHistoryItem, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4412,11 +4412,11 @@ func (ok *Okx) getHistoricCandlesticks(ctx context.Context, instrumentID, path s params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []CandlestickHistoryItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(path, params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, epl, http.MethodGet, common.EncodeURLValues(path, params), nil, &resp, request.UnauthenticatedRequest) } // GetEconomicCalendarData retrieves the macro-economic calendar data within 3 months. Historical data from 3 months ago is only available to users with trading fee tier VIP1 and above -func (ok *Okx) GetEconomicCalendarData(ctx context.Context, region, importance string, before, after time.Time, limit int64) ([]EconomicCalendar, error) { +func (e *Exchange) GetEconomicCalendarData(ctx context.Context, region, importance string, before, after time.Time, limit int64) ([]EconomicCalendar, error) { params := url.Values{} if region != "" { params.Set("region", region) @@ -4434,11 +4434,11 @@ func (ok *Okx) GetEconomicCalendarData(ctx context.Context, region, importance s params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []EconomicCalendar - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEconomicCalendarEPL, http.MethodGet, common.EncodeURLValues("public/economic-calendar", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEconomicCalendarEPL, http.MethodGet, common.EncodeURLValues("public/economic-calendar", params), nil, &resp, request.AuthenticatedRequest) } // GetCandlestickData handles fetching the data for both the default GetCandlesticks, GetCandlesticksHistory, and GetIndexCandlesticks() methods -func (ok *Okx) GetCandlestickData(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64, route string, rateLimit request.EndpointLimit) ([]CandleStick, error) { +func (e *Exchange) GetCandlestickData(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64, route string, rateLimit request.EndpointLimit) ([]CandleStick, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4456,11 +4456,11 @@ func (ok *Okx) GetCandlestickData(ctx context.Context, instrumentID string, inte params.Set("bar", bar) } var resp []CandleStick - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rateLimit, http.MethodGet, common.EncodeURLValues(route, params), nil, &resp, request.UnauthenticatedRequest) } // GetTrades retrieve the recent transactions of an instrument -func (ok *Okx) GetTrades(ctx context.Context, instrumentID string, limit int64) ([]TradeResponse, error) { +func (e *Exchange) GetTrades(ctx context.Context, instrumentID string, limit int64) ([]TradeResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4470,11 +4470,11 @@ func (ok *Okx) GetTrades(ctx context.Context, instrumentID string, limit int64) params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []TradeResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTradesRequestEPL, http.MethodGet, common.EncodeURLValues("market/trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTradesRequestEPL, http.MethodGet, common.EncodeURLValues("market/trades", params), nil, &resp, request.UnauthenticatedRequest) } // GetTradesHistory retrieves the recent transactions of an instrument from the last 3 months with pagination -func (ok *Okx) GetTradesHistory(ctx context.Context, instrumentID, before, after string, limit int64) ([]TradeResponse, error) { +func (e *Exchange) GetTradesHistory(ctx context.Context, instrumentID, before, after string, limit int64) ([]TradeResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -4490,21 +4490,21 @@ func (ok *Okx) GetTradesHistory(ctx context.Context, instrumentID, before, after params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []TradeResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTradesHistoryEPL, http.MethodGet, common.EncodeURLValues("market/history-trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTradesHistoryEPL, http.MethodGet, common.EncodeURLValues("market/history-trades", params), nil, &resp, request.UnauthenticatedRequest) } // GetOptionTradesByInstrumentFamily retrieve the recent transactions of an instrument under same instFamily. The maximum is 100 -func (ok *Okx) GetOptionTradesByInstrumentFamily(ctx context.Context, instrumentFamily string) ([]InstrumentFamilyTrade, error) { +func (e *Exchange) GetOptionTradesByInstrumentFamily(ctx context.Context, instrumentFamily string) ([]InstrumentFamilyTrade, error) { if instrumentFamily == "" { return nil, errInstrumentFamilyRequired } var resp []InstrumentFamilyTrade - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, optionInstrumentTradeFamilyEPL, http.MethodGet, "market/option/instrument-family-trades?instFamily="+instrumentFamily, nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, optionInstrumentTradeFamilyEPL, http.MethodGet, "market/option/instrument-family-trades?instFamily="+instrumentFamily, nil, &resp, request.UnauthenticatedRequest) } // GetOptionTrades retrieves option trades // Option type, 'C': Call 'P': put -func (ok *Okx) GetOptionTrades(ctx context.Context, instrumentID, instrumentFamily, optionType string) ([]OptionTrade, error) { +func (e *Exchange) GetOptionTrades(ctx context.Context, instrumentID, instrumentFamily, optionType string) ([]OptionTrade, error) { if instrumentID == "" && instrumentFamily == "" { return nil, errInstrumentIDorFamilyRequired } @@ -4519,37 +4519,37 @@ func (ok *Okx) GetOptionTrades(ctx context.Context, instrumentID, instrumentFami params.Set("optType", optionType) } var resp []OptionTrade - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, optionTradesEPL, http.MethodGet, common.EncodeURLValues("public/option-trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, optionTradesEPL, http.MethodGet, common.EncodeURLValues("public/option-trades", params), nil, &resp, request.UnauthenticatedRequest) } // Get24HTotalVolume The 24-hour trading volume is calculated on a rolling basis, using USD as the pricing unit -func (ok *Okx) Get24HTotalVolume(ctx context.Context) (*TradingVolumeIn24HR, error) { +func (e *Exchange) Get24HTotalVolume(ctx context.Context) (*TradingVolumeIn24HR, error) { var resp *TradingVolumeIn24HR - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, get24HTotalVolumeEPL, http.MethodGet, "market/platform-24-volume", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, get24HTotalVolumeEPL, http.MethodGet, "market/platform-24-volume", nil, &resp, request.UnauthenticatedRequest) } // GetOracle Get the crypto price of signing using Open Oracle smart contract -func (ok *Okx) GetOracle(ctx context.Context) (*OracleSmartContractResponse, error) { +func (e *Exchange) GetOracle(ctx context.Context) (*OracleSmartContractResponse, error) { var resp *OracleSmartContractResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOracleEPL, http.MethodGet, "market/open-oracle", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOracleEPL, http.MethodGet, "market/open-oracle", nil, &resp, request.UnauthenticatedRequest) } // GetExchangeRate this interface provides the average exchange rate data for 2 weeks // from USD to CNY -func (ok *Okx) GetExchangeRate(ctx context.Context) (*UsdCnyExchangeRate, error) { +func (e *Exchange) GetExchangeRate(ctx context.Context) (*UsdCnyExchangeRate, error) { var resp *UsdCnyExchangeRate - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getExchangeRateRequestEPL, http.MethodGet, "market/exchange-rate", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getExchangeRateRequestEPL, http.MethodGet, "market/exchange-rate", nil, &resp, request.UnauthenticatedRequest) } // GetIndexComponents returns the index component information data on the market -func (ok *Okx) GetIndexComponents(ctx context.Context, index string) (*IndexComponent, error) { +func (e *Exchange) GetIndexComponents(ctx context.Context, index string) (*IndexComponent, error) { if index == "" { return nil, errIndexComponentNotFound } params := url.Values{} params.Set("index", index) var resp *IndexComponent - err := ok.SendHTTPRequest(ctx, exchange.RestSpot, getIndexComponentsEPL, http.MethodGet, common.EncodeURLValues("market/index-components", params), nil, &resp, request.UnauthenticatedRequest) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, getIndexComponentsEPL, http.MethodGet, common.EncodeURLValues("market/index-components", params), nil, &resp, request.UnauthenticatedRequest) if err != nil { return nil, err } @@ -4561,7 +4561,7 @@ func (ok *Okx) GetIndexComponents(ctx context.Context, index string) (*IndexComp // GetBlockTickers retrieves the latest block trading volume in the last 24 hours. // Instrument Type Is Mandatory, and Underlying is Optional -func (ok *Okx) GetBlockTickers(ctx context.Context, instrumentType, underlying string) ([]BlockTicker, error) { +func (e *Exchange) GetBlockTickers(ctx context.Context, instrumentType, underlying string) ([]BlockTicker, error) { instrumentType = strings.ToUpper(instrumentType) if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) @@ -4572,29 +4572,29 @@ func (ok *Okx) GetBlockTickers(ctx context.Context, instrumentType, underlying s params.Set("uly", underlying) } var resp []BlockTicker - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTickersEPL, http.MethodGet, common.EncodeURLValues("market/block-tickers", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTickersEPL, http.MethodGet, common.EncodeURLValues("market/block-tickers", params), nil, &resp, request.UnauthenticatedRequest) } // GetBlockTicker retrieves the latest block trading volume in the last 24 hours -func (ok *Okx) GetBlockTicker(ctx context.Context, instrumentID string) (*BlockTicker, error) { +func (e *Exchange) GetBlockTicker(ctx context.Context, instrumentID string) (*BlockTicker, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp *BlockTicker - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTickersEPL, http.MethodGet, common.EncodeURLValues("market/block-ticker", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTickersEPL, http.MethodGet, common.EncodeURLValues("market/block-ticker", params), nil, &resp, request.UnauthenticatedRequest) } // GetPublicBlockTrades retrieves the recent block trading transactions of an instrument. Descending order by tradeId -func (ok *Okx) GetPublicBlockTrades(ctx context.Context, instrumentID string) ([]BlockTrade, error) { +func (e *Exchange) GetPublicBlockTrades(ctx context.Context, instrumentID string) ([]BlockTrade, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp []BlockTrade - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTradesEPL, http.MethodGet, common.EncodeURLValues("public/block-trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getBlockTradesEPL, http.MethodGet, common.EncodeURLValues("public/block-trades", params), nil, &resp, request.UnauthenticatedRequest) } // ********************************************* Spread Trading *********************************************** @@ -4602,16 +4602,16 @@ func (ok *Okx) GetPublicBlockTrades(ctx context.Context, instrumentID string) ([ // Spread Trading: As Introduced in the Okx exchange. URL: https://www.okx.com/docs-v5/en/#spread-trading-introduction // PlaceSpreadOrder places new spread order -func (ok *Okx) PlaceSpreadOrder(ctx context.Context, arg *SpreadOrderParam) (*SpreadOrderResponse, error) { - err := ok.validatePlaceSpreadOrderParam(arg) +func (e *Exchange) PlaceSpreadOrder(ctx context.Context, arg *SpreadOrderParam) (*SpreadOrderResponse, error) { + err := e.validatePlaceSpreadOrderParam(arg) if err != nil { return nil, err } var resp *SpreadOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeSpreadOrderEPL, http.MethodPost, "sprd/order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeSpreadOrderEPL, http.MethodPost, "sprd/order", arg, &resp, request.AuthenticatedRequest) } -func (ok *Okx) validatePlaceSpreadOrderParam(arg *SpreadOrderParam) error { +func (e *Exchange) validatePlaceSpreadOrderParam(arg *SpreadOrderParam) error { if *arg == (SpreadOrderParam{}) { return common.ErrEmptyParams } @@ -4637,7 +4637,7 @@ func (ok *Okx) validatePlaceSpreadOrderParam(arg *SpreadOrderParam) error { } // CancelSpreadOrder cancels an incomplete spread order -func (ok *Okx) CancelSpreadOrder(ctx context.Context, orderID, clientOrderID string) (*SpreadOrderResponse, error) { +func (e *Exchange) CancelSpreadOrder(ctx context.Context, orderID, clientOrderID string) (*SpreadOrderResponse, error) { if orderID == "" && clientOrderID == "" { return nil, order.ErrOrderIDNotSet } @@ -4649,13 +4649,13 @@ func (ok *Okx) CancelSpreadOrder(ctx context.Context, orderID, clientOrderID str arg["clOrdId"] = clientOrderID } var resp *SpreadOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelSpreadOrderEPL, http.MethodPost, "sprd/cancel-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelSpreadOrderEPL, http.MethodPost, "sprd/cancel-order", arg, &resp, request.AuthenticatedRequest) } // CancelAllSpreadOrders cancels all spread orders and return success message // spreadID is optional // the function returns success status and error message -func (ok *Okx) CancelAllSpreadOrders(ctx context.Context, spreadID string) (bool, error) { +func (e *Exchange) CancelAllSpreadOrders(ctx context.Context, spreadID string) (bool, error) { arg := make(map[string]string, 1) if spreadID != "" { arg["sprdId"] = spreadID @@ -4663,11 +4663,11 @@ func (ok *Okx) CancelAllSpreadOrders(ctx context.Context, spreadID string) (bool resp := &struct { Result bool `json:"result"` }{} - return resp.Result, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllSpreadOrderEPL, http.MethodPost, "sprd/mass-cancel", arg, resp, request.AuthenticatedRequest) + return resp.Result, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllSpreadOrderEPL, http.MethodPost, "sprd/mass-cancel", arg, resp, request.AuthenticatedRequest) } // AmendSpreadOrder amends incomplete spread order -func (ok *Okx) AmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderParam) (*SpreadOrderResponse, error) { +func (e *Exchange) AmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderParam) (*SpreadOrderResponse, error) { if *arg == (AmendSpreadOrderParam{}) { return nil, common.ErrEmptyParams } @@ -4678,11 +4678,11 @@ func (ok *Okx) AmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderParam) return nil, errSizeOrPriceIsRequired } var resp *SpreadOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendSpreadOrderEPL, http.MethodPost, "sprd/amend-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, amendSpreadOrderEPL, http.MethodPost, "sprd/amend-order", arg, &resp, request.AuthenticatedRequest) } // GetSpreadOrderDetails retrieves spread order details -func (ok *Okx) GetSpreadOrderDetails(ctx context.Context, orderID, clientOrderID string) (*SpreadOrder, error) { +func (e *Exchange) GetSpreadOrderDetails(ctx context.Context, orderID, clientOrderID string) (*SpreadOrder, error) { if orderID == "" && clientOrderID == "" { return nil, order.ErrOrderIDNotSet } @@ -4694,11 +4694,11 @@ func (ok *Okx) GetSpreadOrderDetails(ctx context.Context, orderID, clientOrderID params.Set("clOrdId", clientOrderID) } var resp *SpreadOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("sprd/order", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderDetailsEPL, http.MethodGet, common.EncodeURLValues("sprd/order", params), nil, &resp, request.AuthenticatedRequest) } // GetActiveSpreadOrders retrieves list of incomplete spread orders -func (ok *Okx) GetActiveSpreadOrders(ctx context.Context, spreadID, orderType, state, beginID, endID string, limit int64) ([]SpreadOrder, error) { +func (e *Exchange) GetActiveSpreadOrders(ctx context.Context, spreadID, orderType, state, beginID, endID string, limit int64) ([]SpreadOrder, error) { params := url.Values{} if spreadID != "" { params.Set("sprdId", spreadID) @@ -4719,11 +4719,11 @@ func (ok *Okx) GetActiveSpreadOrders(ctx context.Context, spreadID, orderType, s params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SpreadOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getActiveSpreadOrdersEPL, http.MethodGet, common.EncodeURLValues("sprd/orders-pending", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getActiveSpreadOrdersEPL, http.MethodGet, common.EncodeURLValues("sprd/orders-pending", params), nil, &resp, request.AuthenticatedRequest) } // GetCompletedSpreadOrdersLast7Days retrieve the completed order data for the last 7 days, and the incomplete orders (filledSz =0 & state = canceled) that have been canceled are only reserved for 2 hours. Results are returned in counter chronological order -func (ok *Okx) GetCompletedSpreadOrdersLast7Days(ctx context.Context, spreadID, orderType, state, beginID, endID string, begin, end time.Time, limit int64) ([]SpreadOrder, error) { +func (e *Exchange) GetCompletedSpreadOrdersLast7Days(ctx context.Context, spreadID, orderType, state, beginID, endID string, begin, end time.Time, limit int64) ([]SpreadOrder, error) { params := url.Values{} if spreadID != "" { params.Set("sprdId", spreadID) @@ -4750,11 +4750,11 @@ func (ok *Okx) GetCompletedSpreadOrdersLast7Days(ctx context.Context, spreadID, params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SpreadOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrders7DaysEPL, http.MethodGet, common.EncodeURLValues("sprd/orders-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrders7DaysEPL, http.MethodGet, common.EncodeURLValues("sprd/orders-history", params), nil, &resp, request.AuthenticatedRequest) } // GetSpreadTradesOfLast7Days retrieve historical transaction details for the last 7 days. Results are returned in counter chronological order -func (ok *Okx) GetSpreadTradesOfLast7Days(ctx context.Context, spreadID, tradeID, orderID, beginID, endID string, begin, end time.Time, limit int64) ([]SpreadTrade, error) { +func (e *Exchange) GetSpreadTradesOfLast7Days(ctx context.Context, spreadID, tradeID, orderID, beginID, endID string, begin, end time.Time, limit int64) ([]SpreadTrade, error) { params := url.Values{} if spreadID != "" { params.Set("sprdId", spreadID) @@ -4781,11 +4781,11 @@ func (ok *Okx) GetSpreadTradesOfLast7Days(ctx context.Context, spreadID, tradeID params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []SpreadTrade - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderTradesEPL, http.MethodGet, common.EncodeURLValues("sprd/trades", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderTradesEPL, http.MethodGet, common.EncodeURLValues("sprd/trades", params), nil, &resp, request.AuthenticatedRequest) } // GetPublicSpreads retrieve all available spreads based on the request parameters -func (ok *Okx) GetPublicSpreads(ctx context.Context, baseCurrency, instrumentID, spreadID, state string) ([]SpreadInstrument, error) { +func (e *Exchange) GetPublicSpreads(ctx context.Context, baseCurrency, instrumentID, spreadID, state string) ([]SpreadInstrument, error) { params := url.Values{} if baseCurrency != "" { params.Set("baseCcy", baseCurrency) @@ -4800,11 +4800,11 @@ func (ok *Okx) GetPublicSpreads(ctx context.Context, baseCurrency, instrumentID, params.Set("state", state) } var resp []SpreadInstrument - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadsEPL, http.MethodGet, common.EncodeURLValues("sprd/spreads", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadsEPL, http.MethodGet, common.EncodeURLValues("sprd/spreads", params), nil, &resp, request.UnauthenticatedRequest) } // GetPublicSpreadOrderBooks retrieve the order book of the spread -func (ok *Okx) GetPublicSpreadOrderBooks(ctx context.Context, spreadID string, orderbookSize int64) ([]SpreadOrderbook, error) { +func (e *Exchange) GetPublicSpreadOrderBooks(ctx context.Context, spreadID string, orderbookSize int64) ([]SpreadOrderbook, error) { if spreadID == "" { return nil, fmt.Errorf("%w, spread ID missing", errMissingInstrumentID) } @@ -4814,32 +4814,32 @@ func (ok *Okx) GetPublicSpreadOrderBooks(ctx context.Context, spreadID string, o params.Set("size", strconv.FormatInt(orderbookSize, 10)) } var resp []SpreadOrderbook - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderbookEPL, http.MethodGet, common.EncodeURLValues("sprd/books", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadOrderbookEPL, http.MethodGet, common.EncodeURLValues("sprd/books", params), nil, &resp, request.UnauthenticatedRequest) } // GetPublicSpreadTickers retrieve the latest price snapshot, best bid/ask price, and trading volume in the last 24 hours -func (ok *Okx) GetPublicSpreadTickers(ctx context.Context, spreadID string) ([]SpreadTicker, error) { +func (e *Exchange) GetPublicSpreadTickers(ctx context.Context, spreadID string) ([]SpreadTicker, error) { if spreadID == "" { return nil, fmt.Errorf("%w, spread ID is required", errMissingInstrumentID) } params := url.Values{} params.Set("sprdId", spreadID) var resp []SpreadTicker - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadTickerEPL, http.MethodGet, common.EncodeURLValues("sprd/ticker", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadTickerEPL, http.MethodGet, common.EncodeURLValues("sprd/ticker", params), nil, &resp, request.UnauthenticatedRequest) } // GetPublicSpreadTrades retrieve the recent transactions of an instrument (at most 500 records per request). Results are returned in counter chronological order -func (ok *Okx) GetPublicSpreadTrades(ctx context.Context, spreadID string) ([]SpreadPublicTradeItem, error) { +func (e *Exchange) GetPublicSpreadTrades(ctx context.Context, spreadID string) ([]SpreadPublicTradeItem, error) { params := url.Values{} if spreadID != "" { params.Set("sprdId", spreadID) } var resp []SpreadPublicTradeItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadPublicTradesEPL, http.MethodGet, common.EncodeURLValues("sprd/public-trades", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadPublicTradesEPL, http.MethodGet, common.EncodeURLValues("sprd/public-trades", params), nil, &resp, request.UnauthenticatedRequest) } // GetSpreadCandlesticks retrieves candlestick charts for a given spread instrument -func (ok *Okx) GetSpreadCandlesticks(ctx context.Context, spreadID string, interval kline.Interval, before, after time.Time, limit uint64) ([]SpreadCandlestick, error) { +func (e *Exchange) GetSpreadCandlesticks(ctx context.Context, spreadID string, interval kline.Interval, before, after time.Time, limit uint64) ([]SpreadCandlestick, error) { if spreadID == "" { return nil, fmt.Errorf("%w, spread ID is required", errMissingInstrumentID) } @@ -4858,11 +4858,11 @@ func (ok *Okx) GetSpreadCandlesticks(ctx context.Context, spreadID string, inter params.Set("limit", strconv.FormatUint(limit, 10)) } var resp []SpreadCandlestick - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadCandlesticksEPL, http.MethodGet, common.EncodeURLValues("market/sprd-candles", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadCandlesticksEPL, http.MethodGet, common.EncodeURLValues("market/sprd-candles", params), nil, &resp, request.UnauthenticatedRequest) } // GetSpreadCandlesticksHistory retrieves candlestick chart history for a given spread instrument for a period of up to 3 months -func (ok *Okx) GetSpreadCandlesticksHistory(ctx context.Context, spreadID string, interval kline.Interval, before, after time.Time, limit uint64) ([]SpreadCandlestick, error) { +func (e *Exchange) GetSpreadCandlesticksHistory(ctx context.Context, spreadID string, interval kline.Interval, before, after time.Time, limit uint64) ([]SpreadCandlestick, error) { if spreadID == "" { return nil, fmt.Errorf("%w, spread ID is required", errMissingInstrumentID) } @@ -4881,11 +4881,11 @@ func (ok *Okx) GetSpreadCandlesticksHistory(ctx context.Context, spreadID string params.Set("limit", strconv.FormatUint(limit, 10)) } var resp []SpreadCandlestick - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadCandlesticksHistoryEPL, http.MethodGet, common.EncodeURLValues("market/sprd-history-candles", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSpreadCandlesticksHistoryEPL, http.MethodGet, common.EncodeURLValues("market/sprd-history-candles", params), nil, &resp, request.UnauthenticatedRequest) } // CancelAllSpreadOrdersAfterCountdown cancel all pending orders after the countdown timeout. Only applicable to spread trading -func (ok *Okx) CancelAllSpreadOrdersAfterCountdown(ctx context.Context, timeoutDuration int64) (*SpreadOrderCancellationResponse, error) { +func (e *Exchange) CancelAllSpreadOrdersAfterCountdown(ctx context.Context, timeoutDuration int64) (*SpreadOrderCancellationResponse, error) { if (timeoutDuration != 0) && (timeoutDuration < 10 || timeoutDuration > 120) { return nil, fmt.Errorf("%w, range of value can be 0, [10, 120]", errCountdownTimeoutRequired) } @@ -4895,13 +4895,13 @@ func (ok *Okx) CancelAllSpreadOrdersAfterCountdown(ctx context.Context, timeoutD TimeOut: timeoutDuration, } var resp *SpreadOrderCancellationResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllSpreadOrdersAfterEPL, http.MethodPost, "sprd/cancel-all-after", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelAllSpreadOrdersAfterEPL, http.MethodPost, "sprd/cancel-all-after", arg, &resp, request.AuthenticatedRequest) } /************************************ Public Data Endpoints *************************************************/ // GetInstruments retrieve a list of instruments with open contracts -func (ok *Okx) GetInstruments(ctx context.Context, arg *InstrumentsFetchParams) ([]Instrument, error) { +func (e *Exchange) GetInstruments(ctx context.Context, arg *InstrumentsFetchParams) ([]Instrument, error) { if arg.InstrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -4922,12 +4922,12 @@ func (ok *Okx) GetInstruments(ctx context.Context, arg *InstrumentsFetchParams) params.Set("instId", arg.InstrumentID) } var resp []Instrument - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInstrumentsEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getInstrumentsEPL, http.MethodGet, common.EncodeURLValues("public/instruments", params), nil, &resp, request.UnauthenticatedRequest) } // GetDeliveryHistory retrieves the estimated delivery price of the last 3 months, which will only have a return value one hour before the delivery/exercise -func (ok *Okx) GetDeliveryHistory(ctx context.Context, instrumentType, underlying, instrumentFamily string, after, before time.Time, limit int64) ([]DeliveryHistory, error) { +func (e *Exchange) GetDeliveryHistory(ctx context.Context, instrumentType, underlying, instrumentFamily string, after, before time.Time, limit int64) ([]DeliveryHistory, error) { if instrumentType == "" { return nil, errInvalidInstrumentType } @@ -4958,12 +4958,12 @@ func (ok *Okx) GetDeliveryHistory(ctx context.Context, instrumentType, underlyin params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []DeliveryHistory - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDeliveryExerciseHistoryEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDeliveryExerciseHistoryEPL, http.MethodGet, common.EncodeURLValues("public/delivery-exercise-history", params), nil, &resp, request.UnauthenticatedRequest) } // GetOpenInterestData retrieves the total open interest for contracts on OKX -func (ok *Okx) GetOpenInterestData(ctx context.Context, instType, uly, instrumentFamily, instID string) ([]OpenInterest, error) { +func (e *Exchange) GetOpenInterestData(ctx context.Context, instType, uly, instrumentFamily, instID string) ([]OpenInterest, error) { if instType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -4983,22 +4983,22 @@ func (ok *Okx) GetOpenInterestData(ctx context.Context, instType, uly, instrumen params.Set("instId", instID) } var resp []OpenInterest - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestEPL, http.MethodGet, common.EncodeURLValues("public/open-interest", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestEPL, http.MethodGet, common.EncodeURLValues("public/open-interest", params), nil, &resp, request.UnauthenticatedRequest) } // GetSingleFundingRate returns the latest funding rate -func (ok *Okx) GetSingleFundingRate(ctx context.Context, instrumentID string) (*FundingRateResponse, error) { +func (e *Exchange) GetSingleFundingRate(ctx context.Context, instrumentID string) (*FundingRateResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp *FundingRateResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFundingEPL, http.MethodGet, common.EncodeURLValues("public/funding-rate", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFundingEPL, http.MethodGet, common.EncodeURLValues("public/funding-rate", params), nil, &resp, request.UnauthenticatedRequest) } // GetFundingRateHistory retrieves funding rate history. This endpoint can retrieve data from the last 3 months -func (ok *Okx) GetFundingRateHistory(ctx context.Context, instrumentID string, before, after time.Time, limit int64) ([]FundingRateResponse, error) { +func (e *Exchange) GetFundingRateHistory(ctx context.Context, instrumentID string, before, after time.Time, limit int64) ([]FundingRateResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -5014,22 +5014,22 @@ func (ok *Okx) GetFundingRateHistory(ctx context.Context, instrumentID string, b params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []FundingRateResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFundingRateHistoryEPL, http.MethodGet, common.EncodeURLValues("public/funding-rate-history", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFundingRateHistoryEPL, http.MethodGet, common.EncodeURLValues("public/funding-rate-history", params), nil, &resp, request.UnauthenticatedRequest) } // GetLimitPrice retrieves the highest buy limit and lowest sell limit of the instrument -func (ok *Okx) GetLimitPrice(ctx context.Context, instrumentID string) (*LimitPriceResponse, error) { +func (e *Exchange) GetLimitPrice(ctx context.Context, instrumentID string) (*LimitPriceResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp *LimitPriceResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLimitPriceEPL, http.MethodGet, common.EncodeURLValues("public/price-limit", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLimitPriceEPL, http.MethodGet, common.EncodeURLValues("public/price-limit", params), nil, &resp, request.UnauthenticatedRequest) } // GetOptionMarketData retrieves option market data -func (ok *Okx) GetOptionMarketData(ctx context.Context, underlying, instrumentFamily string, expTime time.Time) ([]OptionMarketDataResponse, error) { +func (e *Exchange) GetOptionMarketData(ctx context.Context, underlying, instrumentFamily string, expTime time.Time) ([]OptionMarketDataResponse, error) { if underlying == "" && instrumentFamily == "" { return nil, errInstrumentFamilyOrUnderlyingRequired } @@ -5044,22 +5044,22 @@ func (ok *Okx) GetOptionMarketData(ctx context.Context, underlying, instrumentFa params.Set("expTime", fmt.Sprintf("%d%d%d", expTime.Year(), expTime.Month(), expTime.Day())) } var resp []OptionMarketDataResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOptionMarketDateEPL, http.MethodGet, common.EncodeURLValues("public/opt-summary", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOptionMarketDateEPL, http.MethodGet, common.EncodeURLValues("public/opt-summary", params), nil, &resp, request.UnauthenticatedRequest) } // GetEstimatedDeliveryPrice retrieves the estimated delivery price which will only have a return value one hour before the delivery/exercise -func (ok *Okx) GetEstimatedDeliveryPrice(ctx context.Context, instrumentID string) ([]DeliveryEstimatedPrice, error) { +func (e *Exchange) GetEstimatedDeliveryPrice(ctx context.Context, instrumentID string) ([]DeliveryEstimatedPrice, error) { if instrumentID == "" { return nil, errMissingInstrumentID } params := url.Values{} params.Set("instId", instrumentID) var resp []DeliveryEstimatedPrice - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEstimatedDeliveryPriceEPL, http.MethodGet, common.EncodeURLValues("public/estimated-price", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEstimatedDeliveryPriceEPL, http.MethodGet, common.EncodeURLValues("public/estimated-price", params), nil, &resp, request.UnauthenticatedRequest) } // GetDiscountRateAndInterestFreeQuota retrieves discount rate level and interest-free quota -func (ok *Okx) GetDiscountRateAndInterestFreeQuota(ctx context.Context, ccy currency.Code, discountLevel int8) ([]DiscountRate, error) { +func (e *Exchange) GetDiscountRateAndInterestFreeQuota(ctx context.Context, ccy currency.Code, discountLevel int8) ([]DiscountRate, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5068,17 +5068,17 @@ func (ok *Okx) GetDiscountRateAndInterestFreeQuota(ctx context.Context, ccy curr params.Set("discountLv", strconv.FormatInt(int64(discountLevel), 10)) } var response []DiscountRate - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDiscountRateAndInterestFreeQuotaEPL, http.MethodGet, common.EncodeURLValues("public/discount-rate-interest-free-quota", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getDiscountRateAndInterestFreeQuotaEPL, http.MethodGet, common.EncodeURLValues("public/discount-rate-interest-free-quota", params), nil, &response, request.UnauthenticatedRequest) } // GetSystemTime retrieve API server time -func (ok *Okx) GetSystemTime(ctx context.Context) (types.Time, error) { +func (e *Exchange) GetSystemTime(ctx context.Context) (types.Time, error) { resp := &tsResp{} - return resp.Timestamp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSystemTimeEPL, http.MethodGet, "public/time", nil, resp, request.UnauthenticatedRequest) + return resp.Timestamp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSystemTimeEPL, http.MethodGet, "public/time", nil, resp, request.UnauthenticatedRequest) } // GetLiquidationOrders retrieves information on liquidation orders in the last day -func (ok *Okx) GetLiquidationOrders(ctx context.Context, arg *LiquidationOrderRequestParams) (*LiquidationOrder, error) { +func (e *Exchange) GetLiquidationOrders(ctx context.Context, arg *LiquidationOrderRequestParams) (*LiquidationOrder, error) { arg.InstrumentType = strings.ToUpper(arg.InstrumentType) if arg.InstrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) @@ -5113,11 +5113,11 @@ func (ok *Okx) GetLiquidationOrders(ctx context.Context, arg *LiquidationOrderRe params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp *LiquidationOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLiquidationOrdersEPL, http.MethodGet, common.EncodeURLValues("public/liquidation-orders", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getLiquidationOrdersEPL, http.MethodGet, common.EncodeURLValues("public/liquidation-orders", params), nil, &resp, request.UnauthenticatedRequest) } // GetMarkPrice retrieve mark price -func (ok *Okx) GetMarkPrice(ctx context.Context, instrumentType, underlying, instrumentFamily, instrumentID string) ([]MarkPrice, error) { +func (e *Exchange) GetMarkPrice(ctx context.Context, instrumentType, underlying, instrumentFamily, instrumentID string) ([]MarkPrice, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -5133,11 +5133,11 @@ func (ok *Okx) GetMarkPrice(ctx context.Context, instrumentType, underlying, ins params.Set("instId", instrumentID) } var response []MarkPrice - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMarkPriceEPL, http.MethodGet, common.EncodeURLValues("public/mark-price", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getMarkPriceEPL, http.MethodGet, common.EncodeURLValues("public/mark-price", params), nil, &response, request.UnauthenticatedRequest) } // GetPositionTiers retrieves position tiers information,maximum leverage depends on your borrowings and margin ratio -func (ok *Okx) GetPositionTiers(ctx context.Context, instrumentType, tradeMode, underlying, instrumentFamily, instrumentID, tiers string, ccy currency.Code) ([]PositionTiers, error) { +func (e *Exchange) GetPositionTiers(ctx context.Context, instrumentType, tradeMode, underlying, instrumentFamily, instrumentID, tiers string, ccy currency.Code) ([]PositionTiers, error) { instrumentType = strings.ToUpper(instrumentType) if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) @@ -5180,23 +5180,23 @@ func (ok *Okx) GetPositionTiers(ctx context.Context, instrumentType, tradeMode, params.Set("tiers", tiers) } var response []PositionTiers - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPositionTiersEPL, http.MethodGet, common.EncodeURLValues("public/position-tiers", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getPositionTiersEPL, http.MethodGet, common.EncodeURLValues("public/position-tiers", params), nil, &response, request.UnauthenticatedRequest) } // GetInterestRateAndLoanQuota retrieves an interest rate and loan quota information for various currencies -func (ok *Okx) GetInterestRateAndLoanQuota(ctx context.Context) ([]InterestRateLoanQuotaItem, error) { +func (e *Exchange) GetInterestRateAndLoanQuota(ctx context.Context) ([]InterestRateLoanQuotaItem, error) { var resp []InterestRateLoanQuotaItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateAndLoanQuotaEPL, http.MethodGet, "public/interest-rate-loan-quota", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateAndLoanQuotaEPL, http.MethodGet, "public/interest-rate-loan-quota", nil, &resp, request.UnauthenticatedRequest) } // GetInterestRateAndLoanQuotaForVIPLoans retrieves an interest rate and loan quota information for VIP users of various currencies -func (ok *Okx) GetInterestRateAndLoanQuotaForVIPLoans(ctx context.Context) ([]VIPInterestRateAndLoanQuotaInformation, error) { +func (e *Exchange) GetInterestRateAndLoanQuotaForVIPLoans(ctx context.Context) ([]VIPInterestRateAndLoanQuotaInformation, error) { var response []VIPInterestRateAndLoanQuotaInformation - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateAndLoanQuoteForVIPLoansEPL, http.MethodGet, "public/vip-interest-rate-loan-quota", nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getInterestRateAndLoanQuoteForVIPLoansEPL, http.MethodGet, "public/vip-interest-rate-loan-quota", nil, &response, request.UnauthenticatedRequest) } // GetPublicUnderlyings returns list of underlyings for various instrument types -func (ok *Okx) GetPublicUnderlyings(ctx context.Context, instrumentType string) ([]string, error) { +func (e *Exchange) GetPublicUnderlyings(ctx context.Context, instrumentType string) ([]string, error) { instrumentType = strings.ToUpper(instrumentType) if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) @@ -5204,11 +5204,11 @@ func (ok *Okx) GetPublicUnderlyings(ctx context.Context, instrumentType string) params := url.Values{} params.Set("instType", strings.ToUpper(instrumentType)) var resp []string - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getUnderlyingEPL, http.MethodGet, common.EncodeURLValues("public/underlying", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getUnderlyingEPL, http.MethodGet, common.EncodeURLValues("public/underlying", params), nil, &resp, request.UnauthenticatedRequest) } // GetInsuranceFundInformation returns insurance fund balance information -func (ok *Okx) GetInsuranceFundInformation(ctx context.Context, arg *InsuranceFundInformationRequestParams) (*InsuranceFundInformation, error) { +func (e *Exchange) GetInsuranceFundInformation(ctx context.Context, arg *InsuranceFundInformationRequestParams) (*InsuranceFundInformation, error) { if *arg == (InsuranceFundInformationRequestParams{}) { return nil, common.ErrEmptyParams } @@ -5246,11 +5246,11 @@ func (ok *Okx) GetInsuranceFundInformation(ctx context.Context, arg *InsuranceFu params.Set("limit", strconv.FormatInt(arg.Limit, 10)) } var resp *InsuranceFundInformation - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getInsuranceFundEPL, http.MethodGet, common.EncodeURLValues("public/insurance-fund", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getInsuranceFundEPL, http.MethodGet, common.EncodeURLValues("public/insurance-fund", params), nil, &resp, request.UnauthenticatedRequest) } // CurrencyUnitConvert convert currency to contract, or contract to currency -func (ok *Okx) CurrencyUnitConvert(ctx context.Context, instrumentID string, quantity, orderPrice float64, convertType uint64, unitOfCcy currency.Code, operationTypeOpen bool) (*UnitConvertResponse, error) { +func (e *Exchange) CurrencyUnitConvert(ctx context.Context, instrumentID string, quantity, orderPrice float64, convertType uint64, unitOfCcy currency.Code, operationTypeOpen bool) (*UnitConvertResponse, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -5279,13 +5279,13 @@ func (ok *Okx) CurrencyUnitConvert(ctx context.Context, instrumentID string, qua params.Set("opType", "close") } var resp *UnitConvertResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, unitConvertEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, unitConvertEPL, http.MethodGet, common.EncodeURLValues("public/convert-contract-coin", params), nil, &resp, request.UnauthenticatedRequest) } // GetOptionsTickBands retrieves option tick bands information. // Instrument type OPTION -func (ok *Okx) GetOptionsTickBands(ctx context.Context, instrumentType, instrumentFamily string) ([]OptionTickBand, error) { +func (e *Exchange) GetOptionsTickBands(ctx context.Context, instrumentType, instrumentFamily string) ([]OptionTickBand, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -5295,20 +5295,20 @@ func (ok *Okx) GetOptionsTickBands(ctx context.Context, instrumentType, instrume params.Set("instFamily", instrumentFamily) } var resp []OptionTickBand - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, optionTickBandsEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, optionTickBandsEPL, http.MethodGet, common.EncodeURLValues("public/instrument-tick-bands", params), nil, &resp, request.UnauthenticatedRequest) } // Trading Data Endpoints // GetSupportCoins retrieves the currencies supported by the trading data endpoints -func (ok *Okx) GetSupportCoins(ctx context.Context) (*SupportedCoinsData, error) { +func (e *Exchange) GetSupportCoins(ctx context.Context) (*SupportedCoinsData, error) { var resp *SupportedCoinsData - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getSupportCoinEPL, http.MethodGet, "rubik/stat/trading-data/support-coin", nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getSupportCoinEPL, http.MethodGet, "rubik/stat/trading-data/support-coin", nil, &resp, request.UnauthenticatedRequest) } // GetTakerVolume retrieves the taker volume for both buyers and sellers -func (ok *Okx) GetTakerVolume(ctx context.Context, ccy currency.Code, instrumentType, instrumentFamily string, begin, end time.Time, period kline.Interval) ([]TakerVolume, error) { +func (e *Exchange) GetTakerVolume(ctx context.Context, ccy currency.Code, instrumentType, instrumentFamily string, begin, end time.Time, period kline.Interval) ([]TakerVolume, error) { if instrumentType == "" { return nil, fmt.Errorf("%w, empty instrument type", errInvalidInstrumentType) } @@ -5331,11 +5331,11 @@ func (ok *Okx) GetTakerVolume(ctx context.Context, ccy currency.Code, instrument params.Set("end", strconv.FormatInt(end.UnixMilli(), 10)) } var response []TakerVolume - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTakerVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/taker-volume", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getTakerVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/taker-volume", params), nil, &response, request.UnauthenticatedRequest) } // GetMarginLendingRatio retrieves the ratio of cumulative amount between currency margin quote currency and base currency -func (ok *Okx) GetMarginLendingRatio(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]MarginLendRatioItem, error) { +func (e *Exchange) GetMarginLendingRatio(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]MarginLendRatioItem, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5351,11 +5351,11 @@ func (ok *Okx) GetMarginLendingRatio(ctx context.Context, ccy currency.Code, beg params.Set("period", interval) } var response []MarginLendRatioItem - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getMarginLendingRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/margin/loan-ratio", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getMarginLendingRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/margin/loan-ratio", params), nil, &response, request.UnauthenticatedRequest) } // GetLongShortRatio retrieves the ratio of users with net long vs net short positions for futures and perpetual swaps -func (ok *Okx) GetLongShortRatio(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]LongShortRatio, error) { +func (e *Exchange) GetLongShortRatio(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]LongShortRatio, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5371,11 +5371,11 @@ func (ok *Okx) GetLongShortRatio(ctx context.Context, ccy currency.Code, begin, params.Set("period", interval) } var response []LongShortRatio - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getLongShortRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/contracts/long-short-account-ratio", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getLongShortRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/contracts/long-short-account-ratio", params), nil, &response, request.UnauthenticatedRequest) } // GetContractsOpenInterestAndVolume retrieves the open interest and trading volume for futures and perpetual swaps -func (ok *Okx) GetContractsOpenInterestAndVolume(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]OpenInterestVolume, error) { +func (e *Exchange) GetContractsOpenInterestAndVolume(ctx context.Context, ccy currency.Code, begin, end time.Time, period kline.Interval) ([]OpenInterestVolume, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5391,11 +5391,11 @@ func (ok *Okx) GetContractsOpenInterestAndVolume(ctx context.Context, ccy curren params.Set("period", interval) } var response []OpenInterestVolume - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getContractsOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/contracts/open-interest-volume", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getContractsOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/contracts/open-interest-volume", params), nil, &response, request.UnauthenticatedRequest) } // GetOptionsOpenInterestAndVolume retrieves the open interest and trading volume for options -func (ok *Okx) GetOptionsOpenInterestAndVolume(ctx context.Context, ccy currency.Code, period kline.Interval) ([]OpenInterestVolume, error) { +func (e *Exchange) GetOptionsOpenInterestAndVolume(ctx context.Context, ccy currency.Code, period kline.Interval) ([]OpenInterestVolume, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5405,11 +5405,11 @@ func (ok *Okx) GetOptionsOpenInterestAndVolume(ctx context.Context, ccy currency params.Set("period", interval) } var response []OpenInterestVolume - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOptionsOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getOptionsOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume", params), nil, &response, request.UnauthenticatedRequest) } // GetPutCallRatio retrieves the open interest ration and trading volume ratio of calls vs puts -func (ok *Okx) GetPutCallRatio(ctx context.Context, ccy currency.Code, period kline.Interval) ([]OpenInterestVolumeRatio, error) { +func (e *Exchange) GetPutCallRatio(ctx context.Context, ccy currency.Code, period kline.Interval) ([]OpenInterestVolumeRatio, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5419,11 +5419,11 @@ func (ok *Okx) GetPutCallRatio(ctx context.Context, ccy currency.Code, period kl params.Set("period", interval) } var response []OpenInterestVolumeRatio - return response, ok.SendHTTPRequest(ctx, exchange.RestSpot, getPutCallRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-ratio", params), nil, &response, request.UnauthenticatedRequest) + return response, e.SendHTTPRequest(ctx, exchange.RestSpot, getPutCallRatioEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-ratio", params), nil, &response, request.UnauthenticatedRequest) } // GetOpenInterestAndVolumeExpiry retrieves the open interest and trading volume of calls and puts for each upcoming expiration -func (ok *Okx) GetOpenInterestAndVolumeExpiry(ctx context.Context, ccy currency.Code, period kline.Interval) ([]ExpiryOpenInterestAndVolume, error) { +func (e *Exchange) GetOpenInterestAndVolumeExpiry(ctx context.Context, ccy currency.Code, period kline.Interval) ([]ExpiryOpenInterestAndVolume, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5433,11 +5433,11 @@ func (ok *Okx) GetOpenInterestAndVolumeExpiry(ctx context.Context, ccy currency. params.Set("period", interval) } var resp []ExpiryOpenInterestAndVolume - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-expiry", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-expiry", params), nil, &resp, request.UnauthenticatedRequest) } // GetOpenInterestAndVolumeStrike retrieves the taker volume for both buyers and sellers of calls and puts -func (ok *Okx) GetOpenInterestAndVolumeStrike(ctx context.Context, ccy currency.Code, +func (e *Exchange) GetOpenInterestAndVolumeStrike(ctx context.Context, ccy currency.Code, expTime time.Time, period kline.Interval, ) ([]StrikeOpenInterestAndVolume, error) { if expTime.IsZero() { @@ -5453,12 +5453,12 @@ func (ok *Okx) GetOpenInterestAndVolumeStrike(ctx context.Context, ccy currency. params.Set("period", interval) } var resp []StrikeOpenInterestAndVolume - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-strike", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getOpenInterestAndVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/open-interest-volume-strike", params), nil, &resp, request.UnauthenticatedRequest) } // GetTakerFlow shows the relative buy/sell volume for calls and puts // It shows whether traders are bullish or bearish on price and volatility -func (ok *Okx) GetTakerFlow(ctx context.Context, ccy currency.Code, period kline.Interval) (*CurrencyTakerFlow, error) { +func (e *Exchange) GetTakerFlow(ctx context.Context, ccy currency.Code, period kline.Interval) (*CurrencyTakerFlow, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5468,7 +5468,7 @@ func (ok *Okx) GetTakerFlow(ctx context.Context, ccy currency.Code, period kline params.Set("period", interval) } var resp *CurrencyTakerFlow - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getTakerFlowEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/taker-block-volume", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getTakerFlowEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/option/taker-block-volume", params), nil, &resp, request.UnauthenticatedRequest) } // ********************************************************** Affiliate ********************************************************************** @@ -5479,40 +5479,40 @@ func (ok *Okx) GetTakerFlow(ctx context.Context, ccy currency.Code, period kline // We will reach out to you through your BD to provide more comprehensive API support // GetInviteesDetail retrieves affiliate invitees details -func (ok *Okx) GetInviteesDetail(ctx context.Context, uid string) (*AffilateInviteesDetail, error) { +func (e *Exchange) GetInviteesDetail(ctx context.Context, uid string) (*AffilateInviteesDetail, error) { if uid == "" { return nil, errUserIDRequired } var resp *AffilateInviteesDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAffilateInviteesDetailEPL, http.MethodGet, "affiliate/invitee/detail?uid="+uid, nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAffilateInviteesDetailEPL, http.MethodGet, "affiliate/invitee/detail?uid="+uid, nil, &resp, request.AuthenticatedRequest) } // GetUserAffiliateRebateInformation this endpoint is used to get the user's affiliate rebate information for affiliate -func (ok *Okx) GetUserAffiliateRebateInformation(ctx context.Context, apiKey string) (*AffilateRebateInfo, error) { +func (e *Exchange) GetUserAffiliateRebateInformation(ctx context.Context, apiKey string) (*AffilateRebateInfo, error) { if apiKey == "" { return nil, errInvalidAPIKey } var resp *AffilateRebateInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getUserAffiliateRebateInformationEPL, http.MethodGet, "users/partner/if-rebate?apiKey="+apiKey, nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getUserAffiliateRebateInformationEPL, http.MethodGet, "users/partner/if-rebate?apiKey="+apiKey, nil, &resp, request.AuthenticatedRequest) } // Status // SystemStatusResponse retrieves the system status. // state supports valid values 'scheduled', 'ongoing', 'pre_open', 'completed', and 'canceled' -func (ok *Okx) SystemStatusResponse(ctx context.Context, state string) ([]SystemStatusResponse, error) { +func (e *Exchange) SystemStatusResponse(ctx context.Context, state string) ([]SystemStatusResponse, error) { params := url.Values{} if state != "" { params.Set("state", state) } var resp []SystemStatusResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEventStatusEPL, http.MethodGet, common.EncodeURLValues("system/status", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getEventStatusEPL, http.MethodGet, common.EncodeURLValues("system/status", params), nil, &resp, request.UnauthenticatedRequest) } // ------------------------------------------------------- Lending Orders ------------------------------------------------------ // PlaceLendingOrder places a lending order -func (ok *Okx) PlaceLendingOrder(ctx context.Context, arg *LendingOrderParam) (*LendingOrderResponse, error) { +func (e *Exchange) PlaceLendingOrder(ctx context.Context, arg *LendingOrderParam) (*LendingOrderResponse, error) { if *arg == (LendingOrderParam{}) { return nil, common.ErrEmptyParams } @@ -5529,11 +5529,11 @@ func (ok *Okx) PlaceLendingOrder(ctx context.Context, arg *LendingOrderParam) (* return nil, errLendingTermIsRequired } var resp *LendingOrderResponse - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, placeLendingOrderEPL, http.MethodPost, "finance/fixed-loan/lending-order", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, placeLendingOrderEPL, http.MethodPost, "finance/fixed-loan/lending-order", arg, &resp, request.AuthenticatedRequest) } // AmendLendingOrder amends a lending order -func (ok *Okx) AmendLendingOrder(ctx context.Context, orderID string, changeAmount, rate float64, autoRenewal bool) (string, error) { +func (e *Exchange) AmendLendingOrder(ctx context.Context, orderID string, changeAmount, rate float64, autoRenewal bool) (string, error) { if orderID == "" { return "", order.ErrOrderIDNotSet } @@ -5549,14 +5549,14 @@ func (ok *Okx) AmendLendingOrder(ctx context.Context, orderID string, changeAmou AutoRenewal: autoRenewal, } var resp OrderIDResponse - return resp.OrderID, ok.SendHTTPRequest(ctx, exchange.RestSpot, amendLendingOrderEPL, http.MethodPost, "finance/fixed-loan/amend-lending-order", arg, &resp, request.AuthenticatedRequest) + return resp.OrderID, e.SendHTTPRequest(ctx, exchange.RestSpot, amendLendingOrderEPL, http.MethodPost, "finance/fixed-loan/amend-lending-order", arg, &resp, request.AuthenticatedRequest) } // Note: the documentation for Amending lending order has similar url, request method, and parameters to the placing order. Therefore, the implementation is skipped for now. // GetLendingOrders retrieves list of lending orders. // State: possible values are 'pending', 'earning', 'expired', 'settled' -func (ok *Okx) GetLendingOrders(ctx context.Context, orderID, state string, ccy currency.Code, startAt, endAt time.Time, limit int64) ([]LendingOrderDetail, error) { +func (e *Exchange) GetLendingOrders(ctx context.Context, orderID, state string, ccy currency.Code, startAt, endAt time.Time, limit int64) ([]LendingOrderDetail, error) { params := url.Values{} if orderID != "" { params.Set("ordId", orderID) @@ -5579,12 +5579,12 @@ func (ok *Okx) GetLendingOrders(ctx context.Context, orderID, state string, ccy params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []LendingOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, lendingOrderListEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, lendingOrderListEPL, http.MethodGet, common.EncodeURLValues("finance/fixed-loan/lending-orders-list", params), nil, &resp, request.AuthenticatedRequest) } // GetLendingSubOrderList retrieves a lending sub-orders list -func (ok *Okx) GetLendingSubOrderList(ctx context.Context, orderID, state string, startAt, endAt time.Time, limit int64) ([]LendingSubOrder, error) { +func (e *Exchange) GetLendingSubOrderList(ctx context.Context, orderID, state string, startAt, endAt time.Time, limit int64) ([]LendingSubOrder, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } @@ -5605,13 +5605,13 @@ func (ok *Okx) GetLendingSubOrderList(ctx context.Context, orderID, state string params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []LendingSubOrder - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, lendingSubOrderListEPL, http.MethodGet, common.EncodeURLValues("finance/fixed-loan/lending-sub-orders", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, lendingSubOrderListEPL, http.MethodGet, common.EncodeURLValues("finance/fixed-loan/lending-sub-orders", params), nil, &resp, request.AuthenticatedRequest) } // Trading Statistics endpoints // GetFuturesContractsOpenInterestHistory retrieve the contract open interest statistics of futures and perp. This endpoint returns a maximum of 1440 records -func (ok *Okx) GetFuturesContractsOpenInterestHistory(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]ContractOpenInterestHistoryItem, error) { +func (e *Exchange) GetFuturesContractsOpenInterestHistory(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]ContractOpenInterestHistoryItem, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -5630,13 +5630,13 @@ func (ok *Okx) GetFuturesContractsOpenInterestHistory(ctx context.Context, instr params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []ContractOpenInterestHistoryItem - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rubikGetContractOpenInterestHistoryEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rubikGetContractOpenInterestHistoryEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/contracts/open-interest-history", params), nil, &resp, request.UnauthenticatedRequest) } // GetFuturesContractTakerVolume retrieve the contract taker volume for both buyers and sellers. This endpoint returns a maximum of 1440 records. // The unit of buy/sell volume, the default is 1. '0': Crypto '1': Contracts '2': U -func (ok *Okx) GetFuturesContractTakerVolume(ctx context.Context, instrumentID string, period kline.Interval, unit, limit int64, startAt, endAt time.Time) ([]ContractTakerVolume, error) { +func (e *Exchange) GetFuturesContractTakerVolume(ctx context.Context, instrumentID string, period kline.Interval, unit, limit int64, startAt, endAt time.Time) ([]ContractTakerVolume, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -5658,27 +5658,27 @@ func (ok *Okx) GetFuturesContractTakerVolume(ctx context.Context, instrumentID s params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []ContractTakerVolume - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rubikContractTakerVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/taker-volume-contract", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rubikContractTakerVolumeEPL, http.MethodGet, common.EncodeURLValues("rubik/stat/taker-volume-contract", params), nil, &resp, request.UnauthenticatedRequest) } // GetFuturesContractLongShortAccountRatio retrieve the account long/short ratio of a contract. This endpoint returns a maximum of 1440 records -func (ok *Okx) GetFuturesContractLongShortAccountRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { - return ok.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-account-ratio-contract", period, startAt, endAt, limit) +func (e *Exchange) GetFuturesContractLongShortAccountRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { + return e.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-account-ratio-contract", period, startAt, endAt, limit) } // GetTopTradersFuturesContractLongShortAccountRatio retrieve the account net long/short ratio of a contract for top traders. // Top traders refer to the top 5% of traders with the largest open position value. // This endpoint returns a maximum of 1440 records -func (ok *Okx) GetTopTradersFuturesContractLongShortAccountRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { - return ok.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-account-ratio-contract-top-trader", period, startAt, endAt, limit) +func (e *Exchange) GetTopTradersFuturesContractLongShortAccountRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { + return e.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-account-ratio-contract-top-trader", period, startAt, endAt, limit) } // GetTopTradersFuturesContractLongShortPositionRatio retrieve the position long/short ratio of a contract for top traders. Top traders refer to the top 5% of traders with the largest open position value. This endpoint returns a maximum of 1440 records -func (ok *Okx) GetTopTradersFuturesContractLongShortPositionRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { - return ok.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-position-ratio-contract-top-trader", period, startAt, endAt, limit) +func (e *Exchange) GetTopTradersFuturesContractLongShortPositionRatio(ctx context.Context, instrumentID string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { + return e.getTopTradersFuturesContractLongShortRatio(ctx, instrumentID, "rubik/stat/contracts/long-short-position-ratio-contract-top-trader", period, startAt, endAt, limit) } -func (ok *Okx) getTopTradersFuturesContractLongShortRatio(ctx context.Context, instrumentID, path string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { +func (e *Exchange) getTopTradersFuturesContractLongShortRatio(ctx context.Context, instrumentID, path string, period kline.Interval, startAt, endAt time.Time, limit int64) ([]TopTraderContractsLongShortRatio, error) { if instrumentID == "" { return nil, errMissingInstrumentID } @@ -5697,7 +5697,7 @@ func (ok *Okx) getTopTradersFuturesContractLongShortRatio(ctx context.Context, i params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []TopTraderContractsLongShortRatio - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, rubikTopTradersContractLongShortRatioEPL, http.MethodGet, common.EncodeURLValues(path, params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, rubikTopTradersContractLongShortRatioEPL, http.MethodGet, common.EncodeURLValues(path, params), nil, &resp, request.UnauthenticatedRequest) } // GetAnnouncements get announcements, the response is sorted by pTime with the most recent first. The sort will not be affected if the announcement is updated. Every page has 20 records @@ -5705,7 +5705,7 @@ func (ok *Okx) getTopTradersFuturesContractLongShortRatio(ctx context.Context, i // There are differences between public endpoint and private endpoint. // For public endpoint, the response is restricted based on your request IP. // For private endpoint, the response is restricted based on your country of residence -func (ok *Okx) GetAnnouncements(ctx context.Context, announcementType string, page int64) (*AnnouncementDetail, error) { +func (e *Exchange) GetAnnouncements(ctx context.Context, announcementType string, page int64) (*AnnouncementDetail, error) { params := url.Values{} if announcementType != "" { params.Set("annType", announcementType) @@ -5714,34 +5714,34 @@ func (ok *Okx) GetAnnouncements(ctx context.Context, announcementType string, pa params.Set("page", strconv.FormatInt(page, 10)) } var resp *AnnouncementDetail - if ok.AreCredentialsValid(ctx) { - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementsEPL, http.MethodGet, common.EncodeURLValues("support/announcements", params), nil, &resp, request.AuthenticatedRequest) + if e.AreCredentialsValid(ctx) { + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementsEPL, http.MethodGet, common.EncodeURLValues("support/announcements", params), nil, &resp, request.AuthenticatedRequest) } - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementsEPL, http.MethodGet, common.EncodeURLValues("support/announcements", params), nil, &resp, request.UnauthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementsEPL, http.MethodGet, common.EncodeURLValues("support/announcements", params), nil, &resp, request.UnauthenticatedRequest) } // GetAnnouncementTypes represents a list of announcement types -func (ok *Okx) GetAnnouncementTypes(ctx context.Context) ([]AnnouncementTypeInfo, error) { +func (e *Exchange) GetAnnouncementTypes(ctx context.Context) ([]AnnouncementTypeInfo, error) { var resp []AnnouncementTypeInfo - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementTypeEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getAnnouncementTypeEPL, http.MethodGet, "support/announcement-types", nil, &resp, request.UnauthenticatedRequest) } // Fiat endpoints // GetDepositOrderDetail retrieves fiat deposit order detail -func (ok *Okx) GetDepositOrderDetail(ctx context.Context, orderID string) (*FiatOrderDetail, error) { +func (e *Exchange) GetDepositOrderDetail(ctx context.Context, orderID string) (*FiatOrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } params := url.Values{} params.Set("ordID", orderID) var resp *FiatOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDepositOrderDetailEPL, http.MethodGet, common.EncodeURLValues("fiat/deposit", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDepositOrderDetailEPL, http.MethodGet, common.EncodeURLValues("fiat/deposit", params), nil, &resp, request.AuthenticatedRequest) } // GetFiatDepositOrderHistory retrieves fiat deposit order history -func (ok *Okx) GetFiatDepositOrderHistory(ctx context.Context, ccy currency.Code, paymentMethod, state string, after, before time.Time, limit int64) ([]FiatOrderDetail, error) { +func (e *Exchange) GetFiatDepositOrderHistory(ctx context.Context, ccy currency.Code, paymentMethod, state string, after, before time.Time, limit int64) ([]FiatOrderDetail, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5764,23 +5764,23 @@ func (ok *Okx) GetFiatDepositOrderHistory(ctx context.Context, ccy currency.Code params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []FiatOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getDepositOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("fiat/deposit-order-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getDepositOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("fiat/deposit-order-history", params), nil, &resp, request.AuthenticatedRequest) } // GetWithdrawalOrderDetail retrieves fiat withdrawal order detail -func (ok *Okx) GetWithdrawalOrderDetail(ctx context.Context, orderID string) (*FiatOrderDetail, error) { +func (e *Exchange) GetWithdrawalOrderDetail(ctx context.Context, orderID string) (*FiatOrderDetail, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } params := url.Values{} params.Set("ordId", orderID) var resp *FiatOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalOrderDetailEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalOrderDetailEPL, http.MethodGet, common.EncodeURLValues("fiat/withdrawal", params), &map[string]string{"ordId": orderID}, &resp, request.AuthenticatedRequest) } // GetFiatWithdrawalOrderHistory retrieves fiat withdrawal order history -func (ok *Okx) GetFiatWithdrawalOrderHistory(ctx context.Context, ccy currency.Code, paymentMethod, state string, after, before time.Time, limit int64) ([]FiatOrderDetail, error) { +func (e *Exchange) GetFiatWithdrawalOrderHistory(ctx context.Context, ccy currency.Code, paymentMethod, state string, after, before time.Time, limit int64) ([]FiatOrderDetail, error) { params := url.Values{} if !ccy.IsEmpty() { params.Set("ccy", ccy.String()) @@ -5803,20 +5803,20 @@ func (ok *Okx) GetFiatWithdrawalOrderHistory(ctx context.Context, ccy currency.C params.Set("limit", strconv.FormatInt(limit, 10)) } var resp []FiatOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFiatWithdrawalOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("fiat/withdrawal-order-history", params), nil, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFiatWithdrawalOrderHistoryEPL, http.MethodGet, common.EncodeURLValues("fiat/withdrawal-order-history", params), nil, &resp, request.AuthenticatedRequest) } // CancelWithdrawalOrder cancel a pending fiat withdrawal order, currently only applicable to TRY -func (ok *Okx) CancelWithdrawalOrder(ctx context.Context, orderID string) (*OrderIDAndState, error) { +func (e *Exchange) CancelWithdrawalOrder(ctx context.Context, orderID string) (*OrderIDAndState, error) { if orderID == "" { return nil, order.ErrOrderIDNotSet } var resp *OrderIDAndState - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalOrderEPL, http.MethodPost, "fiat/cancel-withdrawal", &map[string]string{"ordId": orderID}, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, cancelWithdrawalOrderEPL, http.MethodPost, "fiat/cancel-withdrawal", &map[string]string{"ordId": orderID}, &resp, request.AuthenticatedRequest) } // CreateWithdrawalOrder initiate a fiat withdrawal request (Authenticated endpoint, Only for API keys with "Withdrawal" access) -func (ok *Okx) CreateWithdrawalOrder(ctx context.Context, ccy currency.Code, paymentAccountID, paymentMethod, clientID string, amount float64) (*FiatOrderDetail, error) { +func (e *Exchange) CreateWithdrawalOrder(ctx context.Context, ccy currency.Code, paymentAccountID, paymentMethod, clientID string, amount float64) (*FiatOrderDetail, error) { if paymentAccountID == "" { return nil, fmt.Errorf("%w, payment account ID is required", errIDNotSet) } @@ -5846,30 +5846,30 @@ func (ok *Okx) CreateWithdrawalOrder(ctx context.Context, ccy currency.Code, pay Currency: ccy.String(), } var resp *FiatOrderDetail - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, createWithdrawalOrderEPL, http.MethodPost, "fiat/create-withdrawal", arg, &resp, request.AuthenticatedRequest) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, createWithdrawalOrderEPL, http.MethodPost, "fiat/create-withdrawal", arg, &resp, request.AuthenticatedRequest) } // GetFiatWithdrawalPaymentMethods to display all the available fiat withdrawal payment methods -func (ok *Okx) GetFiatWithdrawalPaymentMethods(ctx context.Context, ccy currency.Code) (*FiatWithdrawalPaymentMethods, error) { +func (e *Exchange) GetFiatWithdrawalPaymentMethods(ctx context.Context, ccy currency.Code) (*FiatWithdrawalPaymentMethods, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("ccy", ccy.String()) var resp *FiatWithdrawalPaymentMethods - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalPaymentMethodsEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getWithdrawalPaymentMethodsEPL, http.MethodGet, common.EncodeURLValues("fiat/withdrawal-payment-methods", params), nil, &resp, request.AuthenticatedRequest) } // GetFiatDepositPaymentMethods to display all the available fiat deposit payment methods -func (ok *Okx) GetFiatDepositPaymentMethods(ctx context.Context, ccy currency.Code) (*FiatDepositPaymentMethods, error) { +func (e *Exchange) GetFiatDepositPaymentMethods(ctx context.Context, ccy currency.Code) (*FiatDepositPaymentMethods, error) { if ccy.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } params := url.Values{} params.Set("ccy", ccy.String()) var resp *FiatDepositPaymentMethods - return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getFiatDepositPaymentMethodsEPL, http.MethodGet, + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, getFiatDepositPaymentMethodsEPL, http.MethodGet, common.EncodeURLValues("fiat/deposit-payment-methods", params), nil, &resp, request.AuthenticatedRequest) } @@ -5879,8 +5879,8 @@ URL arguments must be encoded in the request path result must be a pointer The response will be unmarshalled first into []any{result}, which matches most APIs, and fallback to directly into result */ -func (ok *Okx) SendHTTPRequest(ctx context.Context, ep exchange.URL, f request.EndpointLimit, httpMethod, requestPath string, data, result any, requestType request.AuthType) (err error) { - endpoint, err := ok.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, f request.EndpointLimit, httpMethod, requestPath string, data, result any, requestType request.AuthType) (err error) { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -5903,7 +5903,7 @@ func (ok *Okx) SendHTTPRequest(ctx context.Context, ep exchange.URL, f request.E headers["x-simulated-trading"] = "1" } if requestType == request.AuthenticatedRequest { - creds, err := ok.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return nil, err } @@ -5924,12 +5924,12 @@ func (ok *Okx) SendHTTPRequest(ctx context.Context, ep exchange.URL, f request.E Headers: headers, Body: bytes.NewBuffer(payload), Result: &resp, - Verbose: ok.Verbose, - HTTPDebugging: ok.HTTPDebugging, - HTTPRecording: ok.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil } - if err := ok.SendPayload(ctx, f, newRequest, requestType); err != nil { + if err := e.SendPayload(ctx, f, newRequest, requestType); err != nil { return err } if resp.Code.Int64() != 0 { diff --git a/exchanges/okx/okx_business_websocket.go b/exchanges/okx/okx_business_websocket.go index e0557ed7f90..2f3ace0bdca 100644 --- a/exchanges/okx/okx_business_websocket.go +++ b/exchanges/okx/okx_business_websocket.go @@ -44,50 +44,50 @@ var ( ) // WsConnectBusiness connects to a business websocket channel. -func (ok *Okx) WsConnectBusiness(ctx context.Context) error { - if !ok.Websocket.IsEnabled() || !ok.IsEnabled() { +func (e *Exchange) WsConnectBusiness(ctx context.Context) error { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer dialer.ReadBufferSize = 8192 dialer.WriteBufferSize = 8192 - ok.Websocket.Conn.SetURL(okxBusinessWebsocketURL) - err := ok.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + e.Websocket.Conn.SetURL(okxBusinessWebsocketURL) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - ok.Websocket.Wg.Add(1) - go ok.wsReadData(ctx, ok.Websocket.Conn) - if ok.Verbose { + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, e.Websocket.Conn) + if e.Verbose { log.Debugf(log.ExchangeSys, "Successful connection to %v\n", - ok.Websocket.GetWebsocketURL()) + e.Websocket.GetWebsocketURL()) } - ok.Websocket.Conn.SetupPingHandler(request.UnAuth, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.UnAuth, websocket.PingHandler{ MessageType: gws.TextMessage, Message: pingMsg, Delay: time.Second * 20, }) - if ok.Websocket.CanUseAuthenticatedEndpoints() { - err = ok.WsSpreadAuth(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.WsSpreadAuth(ctx) if err != nil { log.Errorf(log.ExchangeSys, "Error connecting auth socket: %s\n", err.Error()) - ok.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } return nil } // WsSpreadAuth will connect to Okx's Private websocket connection and Authenticate with a login payload. -func (ok *Okx) WsSpreadAuth(ctx context.Context) error { - if !ok.Websocket.CanUseAuthenticatedEndpoints() { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", ok.Name) +func (e *Exchange) WsSpreadAuth(ctx context.Context) error { + if !e.Websocket.CanUseAuthenticatedEndpoints() { + return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", e.Name) } - creds, err := ok.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ok.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) ts := time.Now().Unix() signPath := "/users/self/verify" hmac, err := crypto.GetHMAC(crypto.HashSHA256, @@ -105,15 +105,15 @@ func (ok *Okx) WsSpreadAuth(ctx context.Context) error { Sign: base64.StdEncoding.EncodeToString(hmac), }, } - return ok.SendAuthenticatedWebsocketRequest(ctx, request.Unset, "login-response", operationLogin, args, nil) + return e.SendAuthenticatedWebsocketRequest(ctx, request.Unset, "login-response", operationLogin, args, nil) } // GenerateDefaultBusinessSubscriptions returns a list of default subscriptions to business websocket. -func (ok *Okx) GenerateDefaultBusinessSubscriptions() ([]subscription.Subscription, error) { +func (e *Exchange) GenerateDefaultBusinessSubscriptions() ([]subscription.Subscription, error) { var subs []string var subscriptions []subscription.Subscription subs = append(subs, defaultBusinessSubscribedChannels...) - if ok.Websocket.CanUseAuthenticatedEndpoints() { + if e.Websocket.CanUseAuthenticatedEndpoints() { subs = append(subs, defaultBusinessAuthChannels...) } for c := range subs { @@ -124,7 +124,7 @@ func (ok *Okx) GenerateDefaultBusinessSubscriptions() ([]subscription.Subscripti okxSpreadOrderbook, okxSpreadPublicTrades, okxSpreadPublicTicker: - pairs, err := ok.GetEnabledPairs(asset.Spread) + pairs, err := e.GetEnabledPairs(asset.Spread) if err != nil { return nil, err } @@ -137,7 +137,7 @@ func (ok *Okx) GenerateDefaultBusinessSubscriptions() ([]subscription.Subscripti } case channelPublicBlockTrades, channelBlockTickers: - pairs, err := ok.GetEnabledPairs(asset.PerpetualSwap) + pairs, err := e.GetEnabledPairs(asset.PerpetualSwap) if err != nil { return nil, err } @@ -158,18 +158,18 @@ func (ok *Okx) GenerateDefaultBusinessSubscriptions() ([]subscription.Subscripti } // BusinessSubscribe sends a websocket subscription request to several channels to receive data. -func (ok *Okx) BusinessSubscribe(ctx context.Context, channelsToSubscribe subscription.List) error { - return ok.handleBusinessSubscription(ctx, operationSubscribe, channelsToSubscribe) +func (e *Exchange) BusinessSubscribe(ctx context.Context, channelsToSubscribe subscription.List) error { + return e.handleBusinessSubscription(ctx, operationSubscribe, channelsToSubscribe) } // BusinessUnsubscribe sends a websocket unsubscription request to several channels to receive data. -func (ok *Okx) BusinessUnsubscribe(ctx context.Context, channelsToUnsubscribe subscription.List) error { - return ok.handleBusinessSubscription(ctx, operationUnsubscribe, channelsToUnsubscribe) +func (e *Exchange) BusinessUnsubscribe(ctx context.Context, channelsToUnsubscribe subscription.List) error { + return e.handleBusinessSubscription(ctx, operationUnsubscribe, channelsToUnsubscribe) } // handleBusinessSubscription sends a subscription and unsubscription information thought the business websocket endpoint. // as of the okx, exchange this endpoint sends subscription and unsubscription messages but with a list of json objects. -func (ok *Okx) handleBusinessSubscription(ctx context.Context, operation string, subscriptions subscription.List) error { +func (e *Exchange) handleBusinessSubscription(ctx context.Context, operation string, subscriptions subscription.List) error { wsSubscriptionReq := WSSubscriptionInformationList{Operation: operation} var channels subscription.List var authChannels subscription.List @@ -210,14 +210,14 @@ func (ok *Okx) handleBusinessSubscription(ctx context.Context, operation string, } if len(chunk) > maxConnByteLen { i-- - err = ok.Websocket.Conn.SendJSONMessage(ctx, request.UnAuth, wsSubscriptionReq) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.UnAuth, wsSubscriptionReq) if err != nil { return err } if operation == operationUnsubscribe { - err = ok.Websocket.RemoveSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channels...) } else { - err = ok.Websocket.AddSuccessfulSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channels...) } if err != nil { return err @@ -227,17 +227,17 @@ func (ok *Okx) handleBusinessSubscription(ctx context.Context, operation string, continue } } - err = ok.Websocket.Conn.SendJSONMessage(ctx, request.UnAuth, wsSubscriptionReq) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.UnAuth, wsSubscriptionReq) if err != nil { return err } if operation == operationUnsubscribe { channels = append(channels, authChannels...) - err = ok.Websocket.RemoveSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channels...) } else { channels = append(channels, authChannels...) - err = ok.Websocket.AddSuccessfulSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channels...) } return err } diff --git a/exchanges/okx/okx_test.go b/exchanges/okx/okx_test.go index 7a16a9011d5..c71ee817ed5 100644 --- a/exchanges/okx/okx_test.go +++ b/exchanges/okx/okx_test.go @@ -47,7 +47,7 @@ const ( ) var ( - ok = &Okx{} + e *Exchange leadTraderUniqueID string loadLeadTraderOnce sync.Once @@ -60,16 +60,16 @@ var ( ) func TestMain(m *testing.M) { - ok = new(Okx) - if err := testexch.Setup(ok); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Okx Setup error: %s", err) } if apiKey != "" && apiSecret != "" && passphrase != "" { - ok.API.AuthenticatedSupport = true - ok.API.AuthenticatedWebsocketSupport = true - ok.SetCredentials(apiKey, apiSecret, passphrase, "", "", "") - ok.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials(apiKey, apiSecret, passphrase, "", "", "") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) } os.Exit(m.Run()) @@ -83,7 +83,7 @@ func syncLeadTraderUniqueID(t *testing.T) error { } loadLeadTraderOnce.Do(func() { - result, err := ok.GetLeadTradersRanks(contextGenerate(), &LeadTraderRanksRequest{ + result, err := e.GetLeadTradersRanks(contextGenerate(), &LeadTraderRanksRequest{ InstrumentType: instTypeSwap, SortType: "pnl_ratio", HasVacancy: true, @@ -117,125 +117,125 @@ func contextGenerate() context.Context { func TestGetTickers(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) - pairs, err := ok.GetAvailablePairs(asset.Options) + testexch.UpdatePairsOnce(t, e) + pairs, err := e.GetAvailablePairs(asset.Options) require.NoError(t, err, "GetAvailablePairs must not error") require.NotEmpty(t, pairs, "GetAvailablePairs must not return empty pairs") - instFamily, err := ok.instrumentFamilyFromInstID(instTypeOption, pairs[0].String()) + instFamily, err := e.instrumentFamilyFromInstID(instTypeOption, pairs[0].String()) require.NoError(t, err, "instrumentFamilyFromInstID must not error") - _, err = ok.GetTickers(contextGenerate(), "", "", instFamily) + _, err = e.GetTickers(contextGenerate(), "", "", instFamily) require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetTickers(contextGenerate(), instTypeOption, "", instFamily) + result, err := e.GetTickers(contextGenerate(), instTypeOption, "", instFamily) require.NoError(t, err) assert.NotNil(t, result) } func TestGetIndexTicker(t *testing.T) { t.Parallel() - _, err := ok.GetIndexTickers(contextGenerate(), currency.EMPTYCODE, "") + _, err := e.GetIndexTickers(contextGenerate(), currency.EMPTYCODE, "") require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired) - result, err := ok.GetIndexTickers(contextGenerate(), currency.USDT, "") + result, err := e.GetIndexTickers(contextGenerate(), currency.USDT, "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetTicker(t *testing.T) { t.Parallel() - _, err := ok.GetTicker(contextGenerate(), "") + _, err := e.GetTicker(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetTicker(contextGenerate(), perpetualSwapPair.String()) + result, err := e.GetTicker(contextGenerate(), perpetualSwapPair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPremiumHistory(t *testing.T) { t.Parallel() - _, err := ok.GetPremiumHistory(contextGenerate(), "", time.Time{}, time.Time{}, 10) + _, err := e.GetPremiumHistory(contextGenerate(), "", time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetPremiumHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, 10) + result, err := e.GetPremiumHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderBookDepth(t *testing.T) { t.Parallel() - _, err := ok.GetOrderBookDepth(contextGenerate(), "", 400) + _, err := e.GetOrderBookDepth(contextGenerate(), "", 400) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetOrderBookDepth(contextGenerate(), mainPair.String(), 400) + result, err := e.GetOrderBookDepth(contextGenerate(), mainPair.String(), 400) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCandlesticks(t *testing.T) { t.Parallel() - _, err := ok.GetCandlesticks(contextGenerate(), "", kline.OneHour, time.Now().Add(-time.Minute*2), time.Now(), 2) + _, err := e.GetCandlesticks(contextGenerate(), "", kline.OneHour, time.Now().Add(-time.Minute*2), time.Now(), 2) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetCandlesticks(contextGenerate(), mainPair.String(), kline.OneHour, time.Now().Add(-time.Hour), time.Now(), 2) + result, err := e.GetCandlesticks(contextGenerate(), mainPair.String(), kline.OneHour, time.Now().Add(-time.Hour), time.Now(), 2) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCandlesticksHistory(t *testing.T) { t.Parallel() - _, err := ok.GetCandlesticksHistory(contextGenerate(), "", kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3) + _, err := e.GetCandlesticksHistory(contextGenerate(), "", kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetCandlesticksHistory(contextGenerate(), mainPair.String(), kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3) + result, err := e.GetCandlesticksHistory(contextGenerate(), mainPair.String(), kline.OneHour, time.Unix(time.Now().Unix()-int64(time.Minute), 3), time.Now(), 3) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTrades(t *testing.T) { t.Parallel() - _, err := ok.GetTrades(contextGenerate(), "", 3) + _, err := e.GetTrades(contextGenerate(), "", 3) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetTrades(contextGenerate(), mainPair.String(), 3) + result, err := e.GetTrades(contextGenerate(), mainPair.String(), 3) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := ok.GetTradesHistory(contextGenerate(), "", "", "", 2) + _, err := e.GetTradesHistory(contextGenerate(), "", "", "", 2) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetTradesHistory(contextGenerate(), mainPair.String(), "", "", 2) + result, err := e.GetTradesHistory(contextGenerate(), mainPair.String(), "", "", 2) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOptionTradesByInstrumentFamily(t *testing.T) { t.Parallel() - _, err := ok.GetOptionTradesByInstrumentFamily(contextGenerate(), "") + _, err := e.GetOptionTradesByInstrumentFamily(contextGenerate(), "") require.ErrorIs(t, err, errInstrumentFamilyRequired) - result, err := ok.GetOptionTradesByInstrumentFamily(contextGenerate(), optionsPair.String()) + result, err := e.GetOptionTradesByInstrumentFamily(contextGenerate(), optionsPair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOptionTrades(t *testing.T) { t.Parallel() - _, err := ok.GetOptionTrades(contextGenerate(), "", "", "C") + _, err := e.GetOptionTrades(contextGenerate(), "", "", "C") require.ErrorIs(t, err, errInstrumentIDorFamilyRequired) - result, err := ok.GetOptionTrades(contextGenerate(), "", optionsPair.String(), "C") + result, err := e.GetOptionTrades(contextGenerate(), "", optionsPair.String(), "C") require.NoError(t, err) assert.NotNil(t, result) } func TestGet24HTotalVolume(t *testing.T) { t.Parallel() - result, err := ok.Get24HTotalVolume(contextGenerate()) + result, err := e.Get24HTotalVolume(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } @@ -243,24 +243,24 @@ func TestGet24HTotalVolume(t *testing.T) { func TestGetOracle(t *testing.T) { t.Parallel() t.Skip("Skipping test: The server endpoint has a rate-limiting issue that needs to be fixed.") - result, err := ok.GetOracle(contextGenerate()) + result, err := e.GetOracle(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetExchangeRate(t *testing.T) { t.Parallel() - result, err := ok.GetExchangeRate(contextGenerate()) + result, err := e.GetExchangeRate(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetIndexComponents(t *testing.T) { t.Parallel() - _, err := ok.GetIndexComponents(contextGenerate(), "") + _, err := e.GetIndexComponents(contextGenerate(), "") require.ErrorIs(t, err, errIndexComponentNotFound) - result, err := ok.GetIndexComponents(contextGenerate(), mainPair.String()) + result, err := e.GetIndexComponents(contextGenerate(), mainPair.String()) require.NoError(t, err) require.NotNil(t, result) assert.NotEmpty(t, result.Index, "Index should not be empty") @@ -269,71 +269,71 @@ func TestGetIndexComponents(t *testing.T) { func TestGetBlockTickers(t *testing.T) { t.Parallel() - _, err := ok.GetBlockTickers(contextGenerate(), "", "") + _, err := e.GetBlockTickers(contextGenerate(), "", "") require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetBlockTickers(contextGenerate(), "SWAP", "") + result, err := e.GetBlockTickers(contextGenerate(), "SWAP", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetBlockTicker(t *testing.T) { t.Parallel() - _, err := ok.GetBlockTicker(contextGenerate(), "") + _, err := e.GetBlockTicker(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetBlockTicker(contextGenerate(), mainPair.String()) + result, err := e.GetBlockTicker(contextGenerate(), mainPair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetBlockTrade(t *testing.T) { t.Parallel() - _, err := ok.GetPublicBlockTrades(contextGenerate(), "") + _, err := e.GetPublicBlockTrades(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - trades, err := ok.GetPublicBlockTrades(contextGenerate(), mainPair.String()) + trades, err := e.GetPublicBlockTrades(contextGenerate(), mainPair.String()) require.NoError(t, err) if assert.NotEmpty(t, trades, "Should get some block trades") { trade := trades[0] assert.Equal(t, mainPair.String(), trade.InstrumentID, "InstrumentID should have correct value") assert.NotEmpty(t, trade.TradeID, "TradeID should not be empty") - assert.Positive(t, trade.Price, "Price should have a positive value") - assert.Positive(t, trade.Size, "Size should have a positive value") + assert.Positive(t, trade.Price.Float64(), "Price should have a positive value") + assert.Positive(t, trade.Size.Float64(), "Size should have a positive value") assert.Contains(t, []order.Side{order.Buy, order.Sell}, trade.Side, "Side should be a side") assert.WithinRange(t, trade.Timestamp.Time(), time.Now().Add(time.Hour*-24*90), time.Now(), "Timestamp should be within last 90 days") } - testexch.UpdatePairsOnce(t, ok) + testexch.UpdatePairsOnce(t, e) - pairs, err := ok.GetAvailablePairs(asset.Options) + pairs, err := e.GetAvailablePairs(asset.Options) require.NoError(t, err) require.NotEmpty(t, pairs) - publicTrades, err := ok.GetPublicRFQTrades(contextGenerate(), "", "", 100) + publicTrades, err := e.GetPublicRFQTrades(contextGenerate(), "", "", 100) require.NoError(t, err) tested := false LOOP: for _, trade := range publicTrades { for _, leg := range trade.Legs { - p, err := ok.MatchSymbolWithAvailablePairs(leg.InstrumentID, asset.Options, true) + p, err := e.MatchSymbolWithAvailablePairs(leg.InstrumentID, asset.Options, true) if err != nil { continue } - trades, err = ok.GetPublicBlockTrades(contextGenerate(), p.String()) + trades, err = e.GetPublicBlockTrades(contextGenerate(), p.String()) require.NoError(t, err, "GetBlockTrades must not error on Options") for _, trade := range trades { assert.Equal(t, p.String(), trade.InstrumentID, "InstrumentID should have correct value") assert.NotEmpty(t, trade.TradeID, "TradeID should not be empty") - assert.Positive(t, trade.Price, "Price should have a positive value") - assert.Positive(t, trade.Size, "Size should have a positive value") + assert.Positive(t, trade.Price.Float64(), "Price should have a positive value") + assert.Positive(t, trade.Size.Float64(), "Size should have a positive value") assert.Contains(t, []order.Side{order.Buy, order.Sell}, trade.Side, "Side should be a side") - assert.Positive(t, trade.FillVolatility, "FillVolatility should have a positive value") - assert.Positive(t, trade.ForwardPrice, "ForwardPrice should have a positive value") - assert.Positive(t, trade.IndexPrice, "IndexPrice should have a positive value") - assert.Positive(t, trade.MarkPrice, "MarkPrice should have a positive value") + assert.Positive(t, trade.FillVolatility.Float64(), "FillVolatility should have a positive value") + assert.Positive(t, trade.ForwardPrice.Float64(), "ForwardPrice should have a positive value") + assert.Positive(t, trade.IndexPrice.Float64(), "IndexPrice should have a positive value") + assert.Positive(t, trade.MarkPrice.Float64(), "MarkPrice should have a positive value") assert.NotEmpty(t, trade.Timestamp, "Timestamp should not be empty") tested = true break LOOP @@ -345,28 +345,28 @@ LOOP: func TestGetInstrument(t *testing.T) { t.Parallel() - _, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{Underlying: mainPair.String()}) + _, err := e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{Underlying: mainPair.String()}) assert.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ + _, err = e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ InstrumentType: instTypeOption, Underlying: "", }) assert.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - resp, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ + resp, err := e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ InstrumentType: instTypeFutures, Underlying: "SOL-USD", }) require.NoError(t, err) assert.Empty(t, resp, "Should get back no instruments for SOL-USD futures") - result, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ + result, err := e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ InstrumentType: instTypeSpot, }) require.NoError(t, err) assert.NotNil(t, result) - _, err = ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ + _, err = e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ InstrumentType: instTypeSwap, Underlying: mainPair.String(), }) @@ -376,47 +376,47 @@ func TestGetInstrument(t *testing.T) { func TestGetDeliveryHistory(t *testing.T) { t.Parallel() - _, err := ok.GetDeliveryHistory(contextGenerate(), "", mainPair.String(), "", time.Time{}, time.Time{}, 3) + _, err := e.GetDeliveryHistory(contextGenerate(), "", mainPair.String(), "", time.Time{}, time.Time{}, 3) require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, "", "", time.Time{}, time.Time{}, 3) + _, err = e.GetDeliveryHistory(contextGenerate(), instTypeFutures, "", "", time.Time{}, time.Time{}, 3) require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - _, err = ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, mainPair.String(), "", time.Time{}, time.Time{}, 345) + _, err = e.GetDeliveryHistory(contextGenerate(), instTypeFutures, mainPair.String(), "", time.Time{}, time.Time{}, 345) require.ErrorIs(t, err, errLimitValueExceedsMaxOf100) - result, err := ok.GetDeliveryHistory(contextGenerate(), instTypeFutures, mainPair.String(), "", time.Time{}, time.Time{}, 3) + result, err := e.GetDeliveryHistory(contextGenerate(), instTypeFutures, mainPair.String(), "", time.Time{}, time.Time{}, 3) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenInterestData(t *testing.T) { t.Parallel() - _, err := ok.GetOpenInterestData(contextGenerate(), "", mainPair.String(), "", "") + _, err := e.GetOpenInterestData(contextGenerate(), "", mainPair.String(), "", "") require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetOpenInterestData(contextGenerate(), instTypeOption, "", "", "") + _, err = e.GetOpenInterestData(contextGenerate(), instTypeOption, "", "", "") require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - testexch.UpdatePairsOnce(t, ok) - p, err := ok.GetAvailablePairs(asset.Options) + testexch.UpdatePairsOnce(t, e) + p, err := e.GetAvailablePairs(asset.Options) require.NoError(t, err, "GetAvailablePairs must not error") require.NotEmpty(t, p, "GetAvailablePairs must not return empty pairs") - uly, err := ok.underlyingFromInstID(instTypeOption, p[0].String()) + uly, err := e.underlyingFromInstID(instTypeOption, p[0].String()) require.NoError(t, err) - result, err := ok.GetOpenInterestData(contextGenerate(), instTypeOption, uly, optionsPair.String(), p[0].String()) + result, err := e.GetOpenInterestData(contextGenerate(), instTypeOption, uly, optionsPair.String(), p[0].String()) require.NoError(t, err) assert.NotNil(t, result) } // Only being used for testing purposes and unexported -func (ok *Okx) underlyingFromInstID(instrumentType, instID string) (string, error) { - ok.instrumentsInfoMapLock.Lock() - defer ok.instrumentsInfoMapLock.Unlock() +func (e *Exchange) underlyingFromInstID(instrumentType, instID string) (string, error) { + e.instrumentsInfoMapLock.Lock() + defer e.instrumentsInfoMapLock.Unlock() if instrumentType != "" { - insts, okay := ok.instrumentsInfoMap[instrumentType] + insts, okay := e.instrumentsInfoMap[instrumentType] if !okay { return "", errInvalidInstrumentType } @@ -426,7 +426,7 @@ func (ok *Okx) underlyingFromInstID(instrumentType, instID string) (string, erro } } } else { - for _, insts := range ok.instrumentsInfoMap { + for _, insts := range e.instrumentsInfoMap { for a := range insts { if insts[a].InstrumentID.String() == instID { return insts[a].Underlying, nil @@ -439,69 +439,69 @@ func (ok *Okx) underlyingFromInstID(instrumentType, instID string) (string, erro func TestGetSingleFundingRate(t *testing.T) { t.Parallel() - _, err := ok.GetSingleFundingRate(contextGenerate(), "") + _, err := e.GetSingleFundingRate(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetSingleFundingRate(contextGenerate(), perpetualSwapPair.String()) + result, err := e.GetSingleFundingRate(contextGenerate(), perpetualSwapPair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingRateHistory(t *testing.T) { t.Parallel() - _, err := ok.GetFundingRateHistory(contextGenerate(), "", time.Time{}, time.Time{}, 2) + _, err := e.GetFundingRateHistory(contextGenerate(), "", time.Time{}, time.Time{}, 2) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetFundingRateHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, 2) + result, err := e.GetFundingRateHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, 2) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLimitPrice(t *testing.T) { t.Parallel() - _, err := ok.GetLimitPrice(contextGenerate(), "") + _, err := e.GetLimitPrice(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetLimitPrice(contextGenerate(), perpetualSwapPair.String()) + result, err := e.GetLimitPrice(contextGenerate(), perpetualSwapPair.String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOptionMarketData(t *testing.T) { t.Parallel() - _, err := ok.GetOptionMarketData(contextGenerate(), "", "", time.Time{}) + _, err := e.GetOptionMarketData(contextGenerate(), "", "", time.Time{}) require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - result, err := ok.GetOptionMarketData(contextGenerate(), "BTC-USD", "", time.Time{}) + result, err := e.GetOptionMarketData(contextGenerate(), "BTC-USD", "", time.Time{}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetEstimatedDeliveryPrice(t *testing.T) { t.Parallel() - _, err := ok.GetEstimatedDeliveryPrice(contextGenerate(), "") + _, err := e.GetEstimatedDeliveryPrice(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - testexch.UpdatePairsOnce(t, ok) - p, err := ok.GetAvailablePairs(asset.Futures) + testexch.UpdatePairsOnce(t, e) + p, err := e.GetAvailablePairs(asset.Futures) require.NoError(t, err, "GetAvailablePairs must not error") require.NotEmpty(t, p, "GetAvailablePairs must not return empty pairs") - result, err := ok.GetEstimatedDeliveryPrice(contextGenerate(), p[0].String()) + result, err := e.GetEstimatedDeliveryPrice(contextGenerate(), p[0].String()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetDiscountRateAndInterestFreeQuota(t *testing.T) { t.Parallel() - result, err := ok.GetDiscountRateAndInterestFreeQuota(contextGenerate(), currency.EMPTYCODE, 0) + result, err := e.GetDiscountRateAndInterestFreeQuota(contextGenerate(), currency.EMPTYCODE, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSystemTime(t *testing.T) { t.Parallel() - result, err := ok.GetSystemTime(contextGenerate()) + result, err := e.GetSystemTime(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) assert.False(t, result.Time().IsZero(), "GetSystemTime should not return a zero time") @@ -510,7 +510,7 @@ func TestGetSystemTime(t *testing.T) { func TestGetLiquidationOrders(t *testing.T) { t.Parallel() - result, err := ok.GetLiquidationOrders(contextGenerate(), &LiquidationOrderRequestParams{ + result, err := e.GetLiquidationOrders(contextGenerate(), &LiquidationOrderRequestParams{ InstrumentType: instTypeMargin, Underlying: mainPair.String(), Currency: currency.BTC, @@ -522,53 +522,53 @@ func TestGetLiquidationOrders(t *testing.T) { func TestGetMarkPrice(t *testing.T) { t.Parallel() - _, err := ok.GetMarkPrice(contextGenerate(), "", "", "", mainPair.String()) + _, err := e.GetMarkPrice(contextGenerate(), "", "", "", mainPair.String()) require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetMarkPrice(contextGenerate(), "MARGIN", "", "", "") + result, err := e.GetMarkPrice(contextGenerate(), "MARGIN", "", "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetPositionTiers(t *testing.T) { t.Parallel() - _, err := ok.GetPositionTiers(contextGenerate(), "", "cross", mainPair.String(), "", "", "", currency.ETH) + _, err := e.GetPositionTiers(contextGenerate(), "", "cross", mainPair.String(), "", "", "", currency.ETH) require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "", mainPair.String(), "", "", "", currency.ETH) + _, err = e.GetPositionTiers(contextGenerate(), instTypeFutures, "", mainPair.String(), "", "", "", currency.ETH) require.ErrorIs(t, err, errInvalidTradeMode) - _, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", "", "", "", "", currency.EMPTYCODE) + _, err = e.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", "", "", "", "", currency.EMPTYCODE) require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - _, err = ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", mainPair.String(), "", "", "", currency.EMPTYCODE) + _, err = e.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", mainPair.String(), "", "", "", currency.EMPTYCODE) require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired) - result, err := ok.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", mainPair.String(), "", "", "", currency.ETH) + result, err := e.GetPositionTiers(contextGenerate(), instTypeFutures, "cross", mainPair.String(), "", "", "", currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } func TestGetInterestRateAndLoanQuota(t *testing.T) { t.Parallel() - result, err := ok.GetInterestRateAndLoanQuota(contextGenerate()) + result, err := e.GetInterestRateAndLoanQuota(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetInterestRateAndLoanQuotaForVIPLoans(t *testing.T) { t.Parallel() - result, err := ok.GetInterestRateAndLoanQuotaForVIPLoans(contextGenerate()) + result, err := e.GetInterestRateAndLoanQuotaForVIPLoans(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicUnderlyings(t *testing.T) { t.Parallel() - _, err := ok.GetPublicUnderlyings(contextGenerate(), "") + _, err := e.GetPublicUnderlyings(contextGenerate(), "") require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetPublicUnderlyings(contextGenerate(), instTypeFutures) + result, err := e.GetPublicUnderlyings(contextGenerate(), instTypeFutures) require.NoError(t, err) require.NotNil(t, result) assert.NotEmpty(t, result) @@ -576,19 +576,19 @@ func TestGetPublicUnderlyings(t *testing.T) { func TestGetInsuranceFundInformation(t *testing.T) { t.Parallel() - _, err := ok.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{}) + _, err := e.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &InsuranceFundInformationRequestParams{Limit: 2} - _, err = ok.GetInsuranceFundInformation(contextGenerate(), arg) + _, err = e.GetInsuranceFundInformation(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidInstrumentType) arg.InstrumentType = instTypeSwap - _, err = ok.GetInsuranceFundInformation(contextGenerate(), arg) + _, err = e.GetInsuranceFundInformation(contextGenerate(), arg) require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) arg.Underlying = mainPair.String() - r, err := ok.GetInsuranceFundInformation(contextGenerate(), arg) + r, err := e.GetInsuranceFundInformation(contextGenerate(), arg) assert.NoError(t, err) assert.Positive(t, r.Total, "Total should be positive") assert.NotEmpty(t, r.Details, "Should have some details") @@ -598,7 +598,7 @@ func TestGetInsuranceFundInformation(t *testing.T) { assert.Positive(t, d.Timestamp, "Timestamp should be positive") } - r, err = ok.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{ + r, err = e.GetInsuranceFundInformation(contextGenerate(), &InsuranceFundInformationRequestParams{ InstrumentType: instTypeFutures, Underlying: mainPair.String(), Limit: 2, @@ -615,13 +615,13 @@ func TestGetInsuranceFundInformation(t *testing.T) { func TestCurrencyUnitConvert(t *testing.T) { t.Parallel() - _, err := ok.CurrencyUnitConvert(contextGenerate(), "", 1, 3500, 1, currency.EMPTYCODE, false) + _, err := e.CurrencyUnitConvert(contextGenerate(), "", 1, 3500, 1, currency.EMPTYCODE, false) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.CurrencyUnitConvert(contextGenerate(), perpetualSwapPair.String(), 0, 3500, 1, currency.EMPTYCODE, false) + _, err = e.CurrencyUnitConvert(contextGenerate(), perpetualSwapPair.String(), 0, 3500, 1, currency.EMPTYCODE, false) require.ErrorIs(t, err, errMissingQuantity) - result, err := ok.CurrencyUnitConvert(contextGenerate(), perpetualSwapPair.String(), 1, 3500, 1, currency.EMPTYCODE, false) + result, err := e.CurrencyUnitConvert(contextGenerate(), perpetualSwapPair.String(), 1, 3500, 1, currency.EMPTYCODE, false) require.NoError(t, err) assert.NotNil(t, result) } @@ -629,7 +629,7 @@ func TestCurrencyUnitConvert(t *testing.T) { // Trading related endpoints test functions. func TestGetSupportCoins(t *testing.T) { t.Parallel() - result, err := ok.GetSupportCoins(contextGenerate()) + result, err := e.GetSupportCoins(contextGenerate()) require.NoError(t, err) require.NotNil(t, result) assert.NotEmpty(t, result.Spot, "SupportedCoins Spot should not be empty") @@ -637,62 +637,62 @@ func TestGetSupportCoins(t *testing.T) { func TestGetTakerVolume(t *testing.T) { t.Parallel() - _, err := ok.GetTakerVolume(contextGenerate(), currency.BTC, "", "", time.Time{}, time.Time{}, kline.OneDay) + _, err := e.GetTakerVolume(contextGenerate(), currency.BTC, "", "", time.Time{}, time.Time{}, kline.OneDay) require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetTakerVolume(contextGenerate(), currency.BTC, instTypeSpot, "", time.Time{}, time.Time{}, kline.OneDay) + result, err := e.GetTakerVolume(contextGenerate(), currency.BTC, instTypeSpot, "", time.Time{}, time.Time{}, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMarginLendingRatio(t *testing.T) { t.Parallel() - result, err := ok.GetMarginLendingRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.FiveMin) + result, err := e.GetMarginLendingRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.FiveMin) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLongShortRatio(t *testing.T) { t.Parallel() - result, err := ok.GetLongShortRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay) + result, err := e.GetLongShortRatio(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetContractsOpenInterestAndVolume(t *testing.T) { t.Parallel() - result, err := ok.GetContractsOpenInterestAndVolume(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay) + result, err := e.GetContractsOpenInterestAndVolume(contextGenerate(), currency.BTC, time.Time{}, time.Time{}, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOptionsOpenInterestAndVolume(t *testing.T) { t.Parallel() - result, err := ok.GetOptionsOpenInterestAndVolume(contextGenerate(), currency.BTC, kline.OneDay) + result, err := e.GetOptionsOpenInterestAndVolume(contextGenerate(), currency.BTC, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPutCallRatio(t *testing.T) { t.Parallel() - result, err := ok.GetPutCallRatio(contextGenerate(), currency.BTC, kline.OneDay) + result, err := e.GetPutCallRatio(contextGenerate(), currency.BTC, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenInterestAndVolumeExpiry(t *testing.T) { t.Parallel() - result, err := ok.GetOpenInterestAndVolumeExpiry(contextGenerate(), currency.BTC, kline.OneDay) + result, err := e.GetOpenInterestAndVolumeExpiry(contextGenerate(), currency.BTC, kline.OneDay) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenInterestAndVolumeStrike(t *testing.T) { t.Parallel() - _, err := ok.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, time.Time{}, kline.OneDay) + _, err := e.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, time.Time{}, kline.OneDay) require.ErrorIs(t, err, errMissingExpiryTimeParameter) - instruments, err := ok.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ + instruments, err := e.GetInstruments(contextGenerate(), &InstrumentsFetchParams{ InstrumentType: instTypeOption, Underlying: optionsPair.String(), }) @@ -707,14 +707,14 @@ func TestGetOpenInterestAndVolumeStrike(t *testing.T) { break } require.NotZero(t, selectedExpTime, "GetInstruments must return an instrument with a non-zero expiry time") - result, err := ok.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, selectedExpTime, kline.OneDay) + result, err := e.GetOpenInterestAndVolumeStrike(contextGenerate(), currency.BTC, selectedExpTime, kline.OneDay) require.NoErrorf(t, err, "GetOpenInterestAndVolumeStrike with expiry %s for currency %s must not error", selectedExpTime, currency.BTC) assert.NotNilf(t, result, "GetOpenInterestAndVolumeStrike with expiry %s for currency %s should return a non-nil result", selectedExpTime, currency.BTC) } func TestGetTakerFlow(t *testing.T) { t.Parallel() - result, err := ok.GetTakerFlow(contextGenerate(), currency.BTC, kline.OneDay) + result, err := e.GetTakerFlow(contextGenerate(), currency.BTC, kline.OneDay) require.NoError(t, err) require.NotNil(t, result) assert.False(t, result.Timestamp.Time().IsZero(), "Timestamp should not be zero") @@ -722,48 +722,48 @@ func TestGetTakerFlow(t *testing.T) { func TestPlaceOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceOrder(contextGenerate(), nil) + _, err := e.PlaceOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) arg := &PlaceOrderRequestParam{ ReduceOnly: true, AssetType: asset.Margin, } - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Buy.Lower() arg.TradeMode = "abc" - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = "cross" - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = order.Limit.String() - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.AssetType = asset.Futures - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.PositionSide = "long" - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 1 arg.TargetCurrency = "abcd" - _, err = ok.PlaceOrder(contextGenerate(), arg) + _, err = e.PlaceOrder(contextGenerate(), arg) require.ErrorIs(t, err, errCurrencyQuantityTypeRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{ InstrumentID: "BTC-USDC", TradeMode: "cross", Side: order.Buy.String(), @@ -776,7 +776,7 @@ func TestPlaceOrder(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{ + result, err = e.PlaceOrder(contextGenerate(), &PlaceOrderRequestParam{ InstrumentID: "BTC-USDC", TradeMode: "cross", Side: order.Buy.Lower(), @@ -805,57 +805,57 @@ func TestPlaceMultipleOrders(t *testing.T) { err := json.Unmarshal([]byte(placeMultipleOrderParamsJSON), ¶ms) assert.NoError(t, err) - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{}) require.ErrorIs(t, err, order.ErrSubmissionIsNil) arg := PlaceOrderRequestParam{ ReduceOnly: true, } - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "buy" arg.TradeMode = "abc" - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = "cross" - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = orderLimit - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.AssetType = asset.Futures - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.PositionSide = "long" - _, err = ok.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) + _, err = e.PlaceMultipleOrders(contextGenerate(), []PlaceOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceMultipleOrders(contextGenerate(), params) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceMultipleOrders(contextGenerate(), params) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelSingleOrder(t *testing.T) { t.Parallel() - _, err := ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{}) + _, err := e.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{OrderID: "12321312312"}) + _, err = e.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{OrderID: "12321312312"}) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{InstrumentID: mainPair.String()}) + _, err = e.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{InstrumentID: mainPair.String()}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelSingleOrder(contextGenerate(), + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelSingleOrder(contextGenerate(), &CancelOrderRequestParam{ InstrumentID: mainPair.String(), OrderID: "2510789768709120", @@ -866,18 +866,18 @@ func TestCancelSingleOrder(t *testing.T) { func TestCancelMultipleOrders(t *testing.T) { t.Parallel() - _, err := ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{}) + _, err := e.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := CancelOrderRequestParam{} - _, err = ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg}) + _, err = e.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg}) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg}) + _, err = e.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{arg}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMultipleOrders(contextGenerate(), []CancelOrderRequestParam{ { InstrumentID: mainPair.String(), OrderID: "2510789768709120", @@ -889,23 +889,23 @@ func TestCancelMultipleOrders(t *testing.T) { func TestAmendOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendOrder(contextGenerate(), nil) + _, err := e.AmendOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) arg := &AmendOrderRequestParams{} - _, err = ok.AmendOrder(contextGenerate(), arg) + _, err = e.AmendOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.AmendOrder(contextGenerate(), arg) + _, err = e.AmendOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrOrderIDNotSet) arg.OrderID = "1234" - _, err = ok.AmendOrder(contextGenerate(), arg) + _, err = e.AmendOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendOrder(contextGenerate(), &AmendOrderRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendOrder(contextGenerate(), &AmendOrderRequestParams{ InstrumentID: mainPair.String(), OrderID: "2510789768709120", NewPrice: 1233324.332, @@ -916,25 +916,25 @@ func TestAmendOrder(t *testing.T) { func TestAmendMultipleOrders(t *testing.T) { t.Parallel() - _, err := ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{}) + _, err := e.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := AmendOrderRequestParams{ NewPriceInUSD: 1233, } - _, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) + _, err = e.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) + _, err = e.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) arg.ClientOrderID = "123212" - _, err = ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) + _, err = e.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{arg}) require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendMultipleOrders(contextGenerate(), []AmendOrderRequestParams{{ InstrumentID: mainPair.String(), OrderID: "2510789768709120", NewPrice: 1233324.332, @@ -945,15 +945,15 @@ func TestAmendMultipleOrders(t *testing.T) { func TestClosePositions(t *testing.T) { t.Parallel() - _, err := ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{}) + _, err := e.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{MarginMode: "cross"}) + _, err = e.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{MarginMode: "cross"}) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{InstrumentID: mainPair.String(), MarginMode: "abc"}) + _, err = e.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{InstrumentID: mainPair.String(), MarginMode: "abc"}) require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ClosePositions(contextGenerate(), &ClosePositionsRequestParams{ InstrumentID: mainPair.String(), MarginMode: "cross", Currency: "BTC", @@ -964,142 +964,142 @@ func TestClosePositions(t *testing.T) { func TestGetOrderDetail(t *testing.T) { t.Parallel() - _, err := ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{}) + _, err := e.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{}) assert.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{OrderID: "1234"}) + _, err = e.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{OrderID: "1234"}) assert.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: mainPair.String()}) + _, err = e.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: mainPair.String()}) assert.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: "SUI-USDT", OrderID: "1974857619964870656"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderDetail(contextGenerate(), &OrderDetailRequestParam{InstrumentID: "SUI-USDT", OrderID: "1974857619964870656"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOrderList(t *testing.T) { t.Parallel() - _, err := ok.GetOrderList(contextGenerate(), &OrderListRequestParams{}) + _, err := e.GetOrderList(contextGenerate(), &OrderListRequestParams{}) assert.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOrderList(contextGenerate(), &OrderListRequestParams{Limit: 1}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderList(contextGenerate(), &OrderListRequestParams{Limit: 1}) require.NoError(t, err) assert.NotNil(t, result) } func TestGet7DayOrderHistory(t *testing.T) { t.Parallel() - _, err := ok.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{}, "", request.UnAuth) + _, err := e.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{}, "", request.UnAuth) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{Category: "abc"}, "", request.UnAuth) + _, err = e.getOrderHistory(contextGenerate(), &OrderHistoryRequestParams{Category: "abc"}, "", request.UnAuth) require.ErrorIs(t, err, errInvalidInstrumentType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.Get7DayOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.Get7DayOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}}) require.NoError(t, err) require.NotNil(t, result) } func TestGet3MonthOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.Get3MonthOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.Get3MonthOrderHistory(contextGenerate(), &OrderHistoryRequestParams{OrderListRequestParams: OrderListRequestParams{InstrumentType: "MARGIN"}}) require.NoError(t, err) assert.NotNil(t, result) } func TestTransactionHistory(t *testing.T) { t.Parallel() - _, err := ok.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{}, "", request.UnAuth) + _, err := e.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{}, "", request.UnAuth) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{Limit: 10}, "", request.UnAuth) + _, err = e.getTransactionDetails(contextGenerate(), &TransactionDetailRequestParams{Limit: 10}, "", request.UnAuth) require.ErrorIs(t, err, errInvalidInstrumentType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetTransactionDetailsLast3Days(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN", Limit: 1}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTransactionDetailsLast3Days(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN", Limit: 1}) require.NoError(t, err) require.NotNil(t, result) } func TestGetTransactionDetailsLast3Months(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetTransactionDetailsLast3Months(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTransactionDetailsLast3Months(contextGenerate(), &TransactionDetailRequestParams{InstrumentType: "MARGIN"}) require.NoError(t, err) assert.NotNil(t, result) } func TestPlaceAlgoOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceAlgoOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceAlgoOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &AlgoOrderParams{ ReduceOnly: true, } arg.OrderType = "conditional" - _, err = ok.PlaceAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = TradeModeCross - _, err = ok.PlaceAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Sell.Lower() arg.OrderType = "" - _, err = ok.PlaceAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = "limit" - _, err = ok.PlaceAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) } func TestStopOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &AlgoOrderParams{ ReduceOnly: true, } arg.OrderType = "conditional" - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.TakeProfitTriggerPrice = 123 - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrUnknownPriceType) arg.TakeProfitTriggerPriceType = "last_price" arg.AlgoClientOrderID = "12345" - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = TradeModeCross - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Sell.Lower() arg.OrderType = "" - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = "limit" - _, err = ok.PlaceStopOrder(contextGenerate(), arg) + _, err = e.PlaceStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceStopOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", TakeProfitTriggerPriceType: "index", InstrumentID: mainPair.String(), @@ -1116,18 +1116,18 @@ func TestStopOrder(t *testing.T) { func TestPlaceIcebergOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) + _, err = e.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg"}) + _, err = e.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg"}) require.ErrorIs(t, err, errMissingSizeLimit) - _, err = ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg", SizeLimit: 123}) + _, err = e.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{OrderType: "iceberg", SizeLimit: 123}) require.ErrorIs(t, err, errInvalidPriceLimit) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceIcebergOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", LimitPrice: 100.22, SizeLimit: 9999.9, @@ -1144,24 +1144,24 @@ func TestPlaceIcebergOrder(t *testing.T) { func TestPlaceTWAPOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) + _, err = e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{OrderType: "twap"}) + _, err = e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{OrderType: "twap"}) require.ErrorIs(t, err, errMissingSizeLimit) - _, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap"}) + _, err = e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap"}) require.ErrorIs(t, err, errInvalidPriceLimit) - _, err = ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap", LimitPrice: 1234.5}) + _, err = e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{SizeLimit: 2, OrderType: "twap", LimitPrice: 1234.5}) require.ErrorIs(t, err, errMissingIntervalValue) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceTWAPOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", InstrumentID: mainPair.String(), LimitPrice: 100.22, @@ -1179,13 +1179,13 @@ func TestPlaceTWAPOrder(t *testing.T) { func TestPlaceTakeProfitStopLossOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) + _, err = e.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ReduceOnly: true}) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{OrderType: "conditional"}) + _, err = e.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{OrderType: "conditional"}) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ + _, err = e.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ OrderType: "conditional", StopLossTriggerPrice: 1234, StopLossTriggerPriceType: "abcd", @@ -1193,8 +1193,8 @@ func TestPlaceTakeProfitStopLossOrder(t *testing.T) { require.ErrorIs(t, err, order.ErrUnknownPriceType) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceTakeProfitStopLossOrder(contextGenerate(), &AlgoOrderParams{ OrderType: "conditional", StopLossTriggerPrice: 1234, StopLossTriggerPriceType: "last", @@ -1214,39 +1214,39 @@ func TestPlaceTakeProfitStopLossOrder(t *testing.T) { func TestPlaceChaseAlgoOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &AlgoOrderParams{ ReduceOnly: true, } - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = orderChase arg.MaxChaseType = "percentage" - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errPriceTrackingNotSet) arg.MaxChaseType = "percentage" arg.MaxChaseValue = .5 - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = "cross" - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Sell.Lower() - _, err = ok.PlaceChaseAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceChaseAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceChaseAlgoOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", InstrumentID: mainPair.String(), LimitPrice: 100.22, @@ -1263,21 +1263,21 @@ func TestPlaceChaseAlgoOrder(t *testing.T) { func TestTriggerAlgoOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234"}) + _, err = e.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234"}) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger"}) + _, err = e.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger"}) require.ErrorIs(t, err, order.ErrPriceBelowMin) - _, err = ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger", TriggerPrice: 123., TriggerPriceType: "abcd"}) + _, err = e.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{AlgoClientOrderID: "1234", OrderType: "trigger", TriggerPrice: 123., TriggerPriceType: "abcd"}) require.ErrorIs(t, err, order.ErrUnknownPriceType) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceTriggerAlgoOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", TriggerPriceType: "mark", TriggerPrice: 1234, @@ -1293,16 +1293,16 @@ func TestTriggerAlgoOrder(t *testing.T) { func TestPlaceTrailingStopOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{}) + _, err := e.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{}) assert.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2}) + _, err = e.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2}) assert.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2, OrderType: orderMoveOrderStop}) + _, err = e.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{Size: 2, OrderType: orderMoveOrderStop}) assert.ErrorIs(t, err, errPriceTrackingNotSet) // Offline error handling unit tests for the base function PlaceAlgoOrder are already covered within unit test TestPlaceAlgoOrder. - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceTrailingStopOrder(contextGenerate(), &AlgoOrderParams{ AlgoClientOrderID: "681096944655273984", CallbackRatio: 0.01, InstrumentID: mainPair.String(), OrderType: orderMoveOrderStop, Side: order.Buy.Lower(), TradeMode: "isolated", @@ -1315,20 +1315,20 @@ func TestPlaceTrailingStopOrder(t *testing.T) { func TestCancelAlgoOrder(t *testing.T) { t.Parallel() arg := AlgoOrderCancelParams{} - _, err := ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) + _, err := e.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) require.ErrorIs(t, err, common.ErrEmptyParams) arg.AlgoOrderID = "90994943" - _, err = ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) + _, err = e.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() arg.AlgoOrderID = "" - _, err = ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) + _, err = e.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{arg}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{ { InstrumentID: mainPair.String(), AlgoOrderID: "90994943", @@ -1340,17 +1340,17 @@ func TestCancelAlgoOrder(t *testing.T) { func TestCancelAdvanceAlgoOrder(t *testing.T) { t.Parallel() - _, err := ok.CancelAdvanceAlgoOrder(contextGenerate(), nil) + _, err := e.CancelAdvanceAlgoOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{}}) + _, err = e.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{}}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{InstrumentID: "90994943"}}) + _, err = e.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{InstrumentID: "90994943"}}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{AlgoOrderID: "90994943"}}) + _, err = e.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{AlgoOrderID: "90994943"}}) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAdvanceAlgoOrder(contextGenerate(), []AlgoOrderCancelParams{{ InstrumentID: mainPair.String(), AlgoOrderID: "90994943", }}) @@ -1360,83 +1360,83 @@ func TestCancelAdvanceAlgoOrder(t *testing.T) { func TestGetAlgoOrderList(t *testing.T) { t.Parallel() - _, err := ok.GetAlgoOrderList(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 1) + _, err := e.GetAlgoOrderList(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 1) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAlgoOrderList(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAlgoOrderList(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAlgoOrderHistory(t *testing.T) { t.Parallel() - _, err := ok.GetAlgoOrderHistory(contextGenerate(), "", "effective", "", "", "", time.Time{}, time.Time{}, 1) + _, err := e.GetAlgoOrderHistory(contextGenerate(), "", "effective", "", "", "", time.Time{}, time.Time{}, 1) require.ErrorIs(t, err, order.ErrTypeIsInvalid) - _, err = ok.GetAlgoOrderHistory(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1) + _, err = e.GetAlgoOrderHistory(contextGenerate(), "conditional", "", "", "", "", time.Time{}, time.Time{}, 1) require.ErrorIs(t, err, errMissingEitherAlgoIDOrState) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAlgoOrderHistory(contextGenerate(), "conditional", "effective", "", "", "", time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAlgoOrderHistory(contextGenerate(), "conditional", "effective", "", "", "", time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetEasyConvertCurrencyList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetEasyConvertCurrencyList(contextGenerate(), "1") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEasyConvertCurrencyList(contextGenerate(), "1") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOneClickRepayCurrencyList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOneClickRepayCurrencyList(contextGenerate(), "cross") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOneClickRepayCurrencyList(contextGenerate(), "cross") require.NoError(t, err) assert.NotNil(t, result) } func TestPlaceEasyConvert(t *testing.T) { t.Parallel() - _, err := ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{}) + _, err := e.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}}) + _, err = e.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}, ToCurrency: "USDT"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceEasyConvert(contextGenerate(), PlaceEasyConvertParam{FromCurrency: []string{"BTC"}, ToCurrency: "USDT"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetEasyConvertHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetEasyConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEasyConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetOneClickRepayHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOneClickRepayHistory(contextGenerate(), time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOneClickRepayHistory(contextGenerate(), time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestTradeOneClickRepay(t *testing.T) { t.Parallel() - _, err := ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{}, RepayCurrency: "USDT"}) + _, err := e.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{}, RepayCurrency: "USDT"}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{"BTC"}, RepayCurrency: ""}) + _, err = e.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{DebtCurrency: []string{"BTC"}, RepayCurrency: ""}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.TradeOneClickRepay(contextGenerate(), TradeOneClickRepayParam{ DebtCurrency: []string{"BTC"}, RepayCurrency: "USDT", }) @@ -1446,8 +1446,8 @@ func TestTradeOneClickRepay(t *testing.T) { func TestGetCounterparties(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCounterparties(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCounterparties(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } @@ -1460,98 +1460,98 @@ func TestCreateRFQ(t *testing.T) { err := json.Unmarshal([]byte(createRFQInputJSON), &input) require.NoError(t, err) - _, err = ok.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{}}) + _, err = e.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{}}) require.ErrorIs(t, err, errInvalidCounterParties) - _, err = ok.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{"Trader1"}}) + _, err = e.CreateRFQ(contextGenerate(), &CreateRFQInput{CounterParties: []string{"Trader1"}}) require.ErrorIs(t, err, errMissingLegs) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CreateRFQ(contextGenerate(), input) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateRFQ(contextGenerate(), input) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelRFQ(t *testing.T) { t.Parallel() - _, err := ok.CancelRFQ(contextGenerate(), "", "") + _, err := e.CancelRFQ(contextGenerate(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelRFQ(contextGenerate(), "", "somersdjskfjsdkfjxvxv") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelRFQ(contextGenerate(), "", "somersdjskfjsdkfjxvxv") require.NoError(t, err) assert.NotNil(t, result) } func TestMultipleCancelRFQ(t *testing.T) { t.Parallel() - _, err := ok.CancelMultipleRFQs(contextGenerate(), nil) + _, err := e.CancelMultipleRFQs(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{}) + _, err = e.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{RFQIDs: make([]string, 100), ClientRFQIDs: make([]string, 100)}) + _, err = e.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{RFQIDs: make([]string, 100), ClientRFQIDs: make([]string, 100)}) require.ErrorIs(t, err, errMaxRFQOrdersToCancel) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{ClientRFQIDs: []string{"somersdjskfjsdkfjxvxv"}}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMultipleRFQs(contextGenerate(), &CancelRFQRequestsParam{ClientRFQIDs: []string{"somersdjskfjsdkfjxvxv"}}) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllRFQs(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllRFQs(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllRFQs(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestExecuteQuote(t *testing.T) { t.Parallel() - _, err := ok.ExecuteQuote(contextGenerate(), "", "") + _, err := e.ExecuteQuote(contextGenerate(), "", "") assert.ErrorIs(t, err, errMissingRFQIDOrQuoteID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ExecuteQuote(contextGenerate(), "22540", "84073") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ExecuteQuote(contextGenerate(), "22540", "84073") require.NoError(t, err) assert.NotNil(t, result) } func TestGetQuoteProducts(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetQuoteProducts(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetQuoteProducts(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestSetQuoteProducts(t *testing.T) { t.Parallel() - _, err := ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{}) + _, err := e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{{InstrumentType: "ABC"}}) + _, err = e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{{InstrumentType: "ABC"}}) require.ErrorIs(t, err, errInvalidInstrumentType) arg := SetQuoteProductParam{InstrumentType: "SWAP"} - _, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) + _, err = e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) require.ErrorIs(t, err, errMissingMakerInstrumentSettings) data := MakerInstrumentSetting{MaxBlockSize: 10000, MakerPriceBand: 5} arg.Data = []MakerInstrumentSetting{data} - _, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) + _, err = e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) require.ErrorIs(t, err, errInvalidUnderlying) arg.InstrumentType = "SPOT" data = MakerInstrumentSetting{Underlying: "BTC-USD", MaxBlockSize: 10000, MakerPriceBand: 5} arg.Data = []MakerInstrumentSetting{data} - _, err = ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) + _, err = e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{arg}) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetQuoteProducts(contextGenerate(), []SetQuoteProductParam{ { InstrumentType: "SWAP", Data: []MakerInstrumentSetting{ @@ -1572,51 +1572,51 @@ func TestSetQuoteProducts(t *testing.T) { func TestResetRFQMMPStatus(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ResetRFQMMPStatus(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ResetRFQMMPStatus(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestCreateQuote(t *testing.T) { t.Parallel() - _, err := ok.CreateQuote(contextGenerate(), nil) + _, err := e.CreateQuote(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) arg := &CreateQuoteParams{} - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, errMissingRFQID) arg.RFQID = "123456789" - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.QuoteSide = "sell" - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, errMissingLegs) subArg := QuoteLeg{} arg.Legs = []QuoteLeg{subArg} - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) subArg.InstrumentID = "SOL-USD-220909" arg.Legs = []QuoteLeg{subArg} - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, errMissingSizeOfQuote) subArg.SizeOfQuoteLeg = 2 arg.Legs = []QuoteLeg{subArg} - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, errMissingLegsQuotePrice) subArg.Price = 1234 arg.Legs = []QuoteLeg{subArg} - _, err = ok.CreateQuote(contextGenerate(), arg) + _, err = e.CreateQuote(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CreateQuote(contextGenerate(), &CreateQuoteParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateQuote(contextGenerate(), &CreateQuoteParams{ RFQID: "12345", QuoteSide: order.Buy.Lower(), Legs: []QuoteLeg{ @@ -1640,26 +1640,26 @@ func TestCreateQuote(t *testing.T) { func TestCancelQuote(t *testing.T) { t.Parallel() - _, err := ok.CancelQuote(contextGenerate(), "", "") + _, err := e.CancelQuote(contextGenerate(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelQuote(contextGenerate(), "1234", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelQuote(contextGenerate(), "1234", "") require.NoError(t, err) require.NotNil(t, result) - result, err = ok.CancelQuote(contextGenerate(), "", "1234") + result, err = e.CancelQuote(contextGenerate(), "", "1234") require.NoError(t, err) assert.NotNil(t, result) } func TestCancelMultipleQuote(t *testing.T) { t.Parallel() - _, err := ok.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{}) + _, err := e.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelMultipleQuote(contextGenerate(), CancelQuotesRequestParams{ QuoteIDs: []string{"1150", "1151", "1152"}, // Block trades require a minimum of $100,000 in assets in your trading account }) @@ -1669,19 +1669,19 @@ func TestCancelMultipleQuote(t *testing.T) { func TestCancelAllRFQQuotes(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - tt, err := ok.CancelAllRFQQuotes(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + tt, err := e.CancelAllRFQQuotes(contextGenerate()) require.NoError(t, err) assert.NotEmpty(t, tt) } func TestGetRFQs(t *testing.T) { t.Parallel() - _, err := ok.GetRFQs(contextGenerate(), &RFQRequestParams{}) + _, err := e.GetRFQs(contextGenerate(), &RFQRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRFQs(contextGenerate(), &RFQRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRFQs(contextGenerate(), &RFQRequestParams{ Limit: 1, }) require.NoError(t, err) @@ -1690,11 +1690,11 @@ func TestGetRFQs(t *testing.T) { func TestGetQuotes(t *testing.T) { t.Parallel() - _, err := ok.GetQuotes(contextGenerate(), &QuoteRequestParams{}) + _, err := e.GetQuotes(contextGenerate(), &QuoteRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetQuotes(contextGenerate(), &QuoteRequestParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetQuotes(contextGenerate(), &QuoteRequestParams{ Limit: 3, }) require.NoError(t, err) @@ -1703,81 +1703,81 @@ func TestGetQuotes(t *testing.T) { func TestGetRFQTrades(t *testing.T) { t.Parallel() - _, err := ok.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{}) + _, err := e.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{Limit: 1}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRFQTrades(contextGenerate(), &RFQTradesRequestParams{Limit: 1}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicRFQTrades(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetPublicRFQTrades(contextGenerate(), "", "", 3) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPublicRFQTrades(contextGenerate(), "", "", 3) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingCurrencies(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFundingCurrencies(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFundingCurrencies(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBalance(contextGenerate(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBalance(contextGenerate(), currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestGetNonTradableAssets(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetNonTradableAssets(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetNonTradableAssets(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountAssetValuation(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountAssetValuation(contextGenerate(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountAssetValuation(contextGenerate(), currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestFundingTransfer(t *testing.T) { t.Parallel() - _, err := ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{}) + _, err := e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{}) assert.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ + _, err = e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ BeneficiaryAccountType: "6", RemittingAccountType: "18", Currency: currency.BTC, }) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ + _, err = e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ Amount: 12.000, BeneficiaryAccountType: "6", RemittingAccountType: "18", Currency: currency.EMPTYCODE, }) assert.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ + _, err = e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ Amount: 12.000, BeneficiaryAccountType: "2", RemittingAccountType: "3", Currency: currency.BTC, }) assert.ErrorIs(t, err, errAddressRequired) - _, err = ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ + _, err = e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ Amount: 12.000, BeneficiaryAccountType: "2", RemittingAccountType: "18", Currency: currency.BTC, }) assert.ErrorIs(t, err, errAddressRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.FundingTransfer(contextGenerate(), &FundingTransferRequestInput{ Amount: 12.000, BeneficiaryAccountType: "6", RemittingAccountType: "18", @@ -1789,74 +1789,74 @@ func TestFundingTransfer(t *testing.T) { func TestGetFundsTransferState(t *testing.T) { t.Parallel() - _, err := ok.GetFundsTransferState(contextGenerate(), "", "", 1) + _, err := e.GetFundsTransferState(contextGenerate(), "", "", 1) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFundsTransferState(contextGenerate(), "754147", "1232", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFundsTransferState(contextGenerate(), "754147", "1232", 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAssetBillsDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAssetBillsDetails(contextGenerate(), currency.EMPTYCODE, "", time.Time{}, time.Time{}, 0, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAssetBillsDetails(contextGenerate(), currency.EMPTYCODE, "", time.Time{}, time.Time{}, 0, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLightningDeposits(t *testing.T) { t.Parallel() - _, err := ok.GetLightningDeposits(contextGenerate(), currency.EMPTYCODE, 1.00, 0) + _, err := e.GetLightningDeposits(contextGenerate(), currency.EMPTYCODE, 1.00, 0) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.GetLightningDeposits(contextGenerate(), currency.BTC, 0, 0) + _, err = e.GetLightningDeposits(contextGenerate(), currency.BTC, 0, 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLightningDeposits(contextGenerate(), currency.BTC, 1.00, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLightningDeposits(contextGenerate(), currency.BTC, 1.00, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrencyDepositAddress(t *testing.T) { t.Parallel() - _, err := ok.GetCurrencyDepositAddress(contextGenerate(), currency.EMPTYCODE) + _, err := e.GetCurrencyDepositAddress(contextGenerate(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCurrencyDepositAddress(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCurrencyDepositAddress(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCurrencyDepositHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCurrencyDepositHistory(contextGenerate(), currency.BTC, "", "", "", "271", time.Time{}, time.Time{}, 0, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCurrencyDepositHistory(contextGenerate(), currency.BTC, "", "", "", "271", time.Time{}, time.Time{}, 0, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestWithdrawal(t *testing.T) { t.Parallel() - _, err := ok.Withdrawal(contextGenerate(), &WithdrawalInput{}) + _, err := e.Withdrawal(contextGenerate(), &WithdrawalInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.EMPTYCODE, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) + _, err = e.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.EMPTYCODE, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) + _, err = e.Withdrawal(contextGenerate(), &WithdrawalInput{TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, ToAddress: core.BitcoinDonationAddress}) + _, err = e.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, ToAddress: core.BitcoinDonationAddress}) require.ErrorIs(t, err, errAddressRequired) - _, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4"}) + _, err = e.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4"}) require.ErrorIs(t, err, errAddressRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.Withdrawal(contextGenerate(), &WithdrawalInput{Amount: 0.1, TransactionFee: 0.00005, Currency: currency.BTC, WithdrawalDestination: "4", ToAddress: core.BitcoinDonationAddress}) require.NoError(t, err) assert.NotNil(t, result) - result, err = ok.Withdrawal(contextGenerate(), &WithdrawalInput{ + result, err = e.Withdrawal(contextGenerate(), &WithdrawalInput{ Amount: 0.1, WithdrawalDestination: "4", TransactionFee: 0.00005, @@ -1876,19 +1876,19 @@ func TestWithdrawal(t *testing.T) { func TestLightningWithdrawal(t *testing.T) { t.Parallel() - _, err := ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{}) + _, err := e.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{ + _, err = e.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{ Invoice: "lnbc100u1psnnvhtpp5yq2x3q5hhrzsuxpwx7ptphwzc4k4wk0j3stp0099968m44cyjg9sdqqcqzpgxqzjcsp5hz", Currency: currency.EMPTYCODE, }) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{Invoice: "", Currency: currency.BTC}) + _, err = e.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{Invoice: "", Currency: currency.BTC}) require.ErrorIs(t, err, errInvoiceTextMissing) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.LightningWithdrawal(contextGenerate(), &LightningWithdrawalRequestInput{ Currency: currency.BTC, Invoice: "lnbc100u1psnnvhtpp5yq2x3q5hhrzsuxpwx7ptphwzc4k4wk0j3stp0099968m44cyjg9sdqqcqzpgxqzjcsp5hz", }) @@ -1898,63 +1898,63 @@ func TestLightningWithdrawal(t *testing.T) { func TestCancelWithdrawal(t *testing.T) { t.Parallel() - _, err := ok.CancelWithdrawal(contextGenerate(), "") + _, err := e.CancelWithdrawal(contextGenerate(), "") require.ErrorIs(t, err, errMissingValidWithdrawalID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelWithdrawal(contextGenerate(), "fjasdfkjasdk") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelWithdrawal(contextGenerate(), "fjasdfkjasdk") require.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetWithdrawalHistory(contextGenerate(), currency.BTC, "", "", "", "", time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalHistory(contextGenerate(), currency.BTC, "", "", "", "", time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestSmallAssetsConvert(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SmallAssetsConvert(contextGenerate(), []string{"BTC", "USDT"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SmallAssetsConvert(contextGenerate(), []string{"BTC", "USDT"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSavingBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSavingBalance(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSavingBalance(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestSavingsPurchase(t *testing.T) { t.Parallel() - _, err := ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{}) + _, err := e.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &SavingsPurchaseRedemptionInput{Rate: 1} - _, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg) + _, err = e.SavingsPurchaseOrRedemption(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.Currency = currency.BTC - _, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg) + _, err = e.SavingsPurchaseOrRedemption(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 123.4 - _, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg) + _, err = e.SavingsPurchaseOrRedemption(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Rate = 0.001 arg.ActionType = "purchase" - _, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), arg) + _, err = e.SavingsPurchaseOrRedemption(contextGenerate(), arg) require.ErrorIs(t, err, errRateRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{ Amount: 123.4, Currency: currency.BTC, Rate: 1, @@ -1963,7 +1963,7 @@ func TestSavingsPurchase(t *testing.T) { require.NoError(t, err) require.NotNil(t, result) - result, err = ok.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{ + result, err = e.SavingsPurchaseOrRedemption(contextGenerate(), &SavingsPurchaseRedemptionInput{ Amount: 123.4, Currency: currency.BTC, Rate: 1, @@ -1975,115 +1975,115 @@ func TestSavingsPurchase(t *testing.T) { func TestSetLendingRate(t *testing.T) { t.Parallel() - _, err := ok.SetLendingRate(contextGenerate(), &LendingRate{}) + _, err := e.SetLendingRate(contextGenerate(), &LendingRate{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.EMPTYCODE, Rate: 2}) + _, err = e.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.EMPTYCODE, Rate: 2}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC}) + _, err = e.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC}) require.ErrorIs(t, err, errRateRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC, Rate: 2}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetLendingRate(contextGenerate(), &LendingRate{Currency: currency.BTC, Rate: 2}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLendingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLendingHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLendingHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicBorrowInfo(t *testing.T) { t.Parallel() - result, err := ok.GetPublicBorrowInfo(contextGenerate(), currency.EMPTYCODE) + result, err := e.GetPublicBorrowInfo(contextGenerate(), currency.EMPTYCODE) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.GetPublicBorrowInfo(contextGenerate(), currency.USDT) + result, err = e.GetPublicBorrowInfo(contextGenerate(), currency.USDT) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicBorrowHistory(t *testing.T) { t.Parallel() - result, err := ok.GetPublicBorrowHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1) + result, err := e.GetPublicBorrowHistory(contextGenerate(), currency.USDT, time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMonthlyStatement(t *testing.T) { t.Parallel() - _, err := ok.GetMonthlyStatement(contextGenerate(), "") + _, err := e.GetMonthlyStatement(contextGenerate(), "") require.ErrorIs(t, err, errMonthNameRequired) - _, err = ok.GetMonthlyStatement(contextGenerate(), "") + _, err = e.GetMonthlyStatement(contextGenerate(), "") require.ErrorIs(t, err, errMonthNameRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMonthlyStatement(contextGenerate(), "Jan") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMonthlyStatement(contextGenerate(), "Jan") require.NoError(t, err) assert.NotNil(t, result) } func TestApplyForMonthlyStatement(t *testing.T) { t.Parallel() - _, err := ok.ApplyForMonthlyStatement(contextGenerate(), "") + _, err := e.ApplyForMonthlyStatement(contextGenerate(), "") require.ErrorIs(t, err, errMonthNameRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ApplyForMonthlyStatement(contextGenerate(), "Jan") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ApplyForMonthlyStatement(contextGenerate(), "Jan") require.NoError(t, err) assert.NotNil(t, result) } func TestGetConvertCurrencies(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetConvertCurrencies(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetConvertCurrencies(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetConvertCurrencyPair(t *testing.T) { t.Parallel() - _, err := ok.GetConvertCurrencyPair(contextGenerate(), currency.EMPTYCODE, currency.BTC) + _, err := e.GetConvertCurrencyPair(contextGenerate(), currency.EMPTYCODE, currency.BTC) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.EMPTYCODE) + _, err = e.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetConvertCurrencyPair(contextGenerate(), currency.USDT, currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestEstimateQuote(t *testing.T) { t.Parallel() - _, err := ok.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{}) + _, err := e.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &EstimateQuoteRequestInput{Tag: "abcd"} - _, err = ok.EstimateQuote(contextGenerate(), arg) + _, err = e.EstimateQuote(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.BaseCurrency = currency.BTC - _, err = ok.EstimateQuote(contextGenerate(), arg) + _, err = e.EstimateQuote(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.QuoteCurrency = currency.BTC - _, err = ok.EstimateQuote(contextGenerate(), arg) + _, err = e.EstimateQuote(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Sell.Lower() - _, err = ok.EstimateQuote(contextGenerate(), arg) + _, err = e.EstimateQuote(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.RFQAmount = 30 - _, err = ok.EstimateQuote(contextGenerate(), arg) + _, err = e.EstimateQuote(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.EstimateQuote(contextGenerate(), &EstimateQuoteRequestInput{ BaseCurrency: currency.BTC, QuoteCurrency: currency.USDT, Side: order.Sell.Lower(), @@ -2096,34 +2096,34 @@ func TestEstimateQuote(t *testing.T) { func TestConvertTrade(t *testing.T) { t.Parallel() - _, err := ok.ConvertTrade(contextGenerate(), &ConvertTradeInput{}) + _, err := e.ConvertTrade(contextGenerate(), &ConvertTradeInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &ConvertTradeInput{Tag: "123"} - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.BaseCurrency = "BTC" - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.QuoteCurrency = "USDT" - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = order.Buy.Lower() - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Size = 2 - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.SizeCurrency = currency.USDT - _, err = ok.ConvertTrade(contextGenerate(), arg) + _, err = e.ConvertTrade(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ConvertTrade(contextGenerate(), &ConvertTradeInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ConvertTrade(contextGenerate(), &ConvertTradeInput{ BaseCurrency: "BTC", QuoteCurrency: "USDT", Side: order.Buy.Lower(), @@ -2137,51 +2137,51 @@ func TestConvertTrade(t *testing.T) { func TestGetConvertHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetConvertHistory(contextGenerate(), time.Time{}, time.Time{}, 1, "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetNonZeroAccountBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.AccountBalance(contextGenerate(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.AccountBalance(contextGenerate(), currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetPositions(contextGenerate(), "", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPositions(contextGenerate(), "", "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetPositionsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetPositionsHistory(contextGenerate(), "", "", "", "1234213123", 0, 1, time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPositionsHistory(contextGenerate(), "", "", "", "1234213123", 0, 1, time.Time{}, time.Time{}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountAndPositionRisk(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountAndPositionRisk(contextGenerate(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountAndPositionRisk(contextGenerate(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetBillsDetail(t *testing.T) { t.Parallel() - _, err := ok.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{}) + _, err := e.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBillsDetailLast7Days(contextGenerate(), &BillsDetailQueryParameter{ Limit: 3, }) require.NoError(t, err) @@ -2190,68 +2190,68 @@ func TestGetBillsDetail(t *testing.T) { func TestGetBillsDetail3Months(t *testing.T) { t.Parallel() - _, err := ok.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{}) + _, err := e.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{Limit: 3}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBillsDetail3Months(contextGenerate(), &BillsDetailQueryParameter{Limit: 3}) require.NoError(t, err) assert.NotNil(t, result) } func TestApplyBillDetails(t *testing.T) { t.Parallel() - _, err := ok.ApplyBillDetails(contextGenerate(), "", "Q2") + _, err := e.ApplyBillDetails(contextGenerate(), "", "Q2") require.ErrorIs(t, err, errYearRequired) - _, err = ok.ApplyBillDetails(contextGenerate(), "2023", "") + _, err = e.ApplyBillDetails(contextGenerate(), "2023", "") require.ErrorIs(t, err, errQuarterValueRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.ApplyBillDetails(contextGenerate(), "2023", "Q2") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ApplyBillDetails(contextGenerate(), "2023", "Q2") require.NoError(t, err) assert.NotNil(t, result) } func TestGetBillsHistoryArchive(t *testing.T) { t.Parallel() - _, err := ok.GetBillsHistoryArchive(contextGenerate(), "", "Q2") + _, err := e.GetBillsHistoryArchive(contextGenerate(), "", "Q2") require.ErrorIs(t, err, errYearRequired) - _, err = ok.GetBillsHistoryArchive(contextGenerate(), "2023", "") + _, err = e.GetBillsHistoryArchive(contextGenerate(), "2023", "") require.ErrorIs(t, err, errQuarterValueRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBillsHistoryArchive(contextGenerate(), "2023", "Q2") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBillsHistoryArchive(contextGenerate(), "2023", "Q2") require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountConfiguration(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountConfiguration(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountConfiguration(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestSetPositionMode(t *testing.T) { t.Parallel() - _, err := ok.SetPositionMode(contextGenerate(), "") + _, err := e.SetPositionMode(contextGenerate(), "") require.ErrorIs(t, err, errInvalidPositionMode) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.SetPositionMode(contextGenerate(), "net_mode") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.SetPositionMode(contextGenerate(), "net_mode") require.NoError(t, err) assert.NotNil(t, result) } func TestSetLeverageRate(t *testing.T) { t.Parallel() - _, err := ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{}) + _, err := e.SetLeverageRate(contextGenerate(), &SetLeverageInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{Leverage: 5, MarginMode: "isolated", AssetType: asset.PerpetualSwap}) + _, err = e.SetLeverageRate(contextGenerate(), &SetLeverageInput{Leverage: 5, MarginMode: "isolated", AssetType: asset.PerpetualSwap}) require.ErrorIs(t, err, errEitherInstIDOrCcyIsRequired) - _, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{ + _, err = e.SetLeverageRate(contextGenerate(), &SetLeverageInput{ Currency: currency.USDT, Leverage: 5, MarginMode: "isolated", @@ -2260,8 +2260,8 @@ func TestSetLeverageRate(t *testing.T) { }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - _, err = ok.SetLeverageRate(contextGenerate(), &SetLeverageInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err = e.SetLeverageRate(contextGenerate(), &SetLeverageInput{ Currency: currency.USDT, Leverage: 5, MarginMode: "cross", @@ -2272,53 +2272,53 @@ func TestSetLeverageRate(t *testing.T) { func TestGetMaximumBuySellAmountOROpenAmount(t *testing.T) { t.Parallel() - _, err := ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, "", "cross", "", 5, true) + _, err := e.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, "", "cross", "", 5, true) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, mainPair.String(), "", "", 5, true) + _, err = e.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, mainPair.String(), "", "", 5, true) require.ErrorIs(t, err, errInvalidTradeModeValue) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, mainPair.String(), "cross", "", 5, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaximumBuySellAmountOROpenAmount(contextGenerate(), currency.BTC, mainPair.String(), "cross", "", 5, true) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMaximumAvailableTradableAmount(t *testing.T) { t.Parallel() - _, err := ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, "", "cross", "", true, false, 123) + _, err := e.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, "", "cross", "", true, false, 123) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, mainPair.String(), "", "", true, false, 123) + _, err = e.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, mainPair.String(), "", "", true, false, 123) require.ErrorIs(t, err, errInvalidTradeModeValue) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, mainPair.String(), "cross", "", true, false, 123) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaximumAvailableTradableAmount(contextGenerate(), currency.BTC, mainPair.String(), "cross", "", true, false, 123) require.NoError(t, err) assert.NotNil(t, result) } func TestIncreaseDecreaseMargin(t *testing.T) { t.Parallel() - _, err := ok.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{}) + _, err := e.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &IncreaseDecreaseMarginInput{Currency: "USD"} - _, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg) + _, err = e.IncreaseDecreaseMargin(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg) + _, err = e.IncreaseDecreaseMargin(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.PositionSide = "long" - _, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg) + _, err = e.IncreaseDecreaseMargin(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.MarginBalanceType = "reduce" - _, err = ok.IncreaseDecreaseMargin(contextGenerate(), arg) + _, err = e.IncreaseDecreaseMargin(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.IncreaseDecreaseMargin(contextGenerate(), &IncreaseDecreaseMarginInput{ InstrumentID: mainPair.String(), PositionSide: "long", MarginBalanceType: "add", @@ -2331,281 +2331,281 @@ func TestIncreaseDecreaseMargin(t *testing.T) { func TestGetLeverageRate(t *testing.T) { t.Parallel() - _, err := ok.GetLeverageRate(contextGenerate(), "", "cross", currency.EMPTYCODE) + _, err := e.GetLeverageRate(contextGenerate(), "", "cross", currency.EMPTYCODE) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetLeverageRate(contextGenerate(), mainPair.String(), "", currency.EMPTYCODE) + _, err = e.GetLeverageRate(contextGenerate(), mainPair.String(), "", currency.EMPTYCODE) require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLeverageRate(contextGenerate(), mainPair.String(), "cross", currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeverageRate(contextGenerate(), mainPair.String(), "cross", currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMaximumLoanOfInstrument(t *testing.T) { t.Parallel() - _, err := ok.GetMaximumLoanOfInstrument(contextGenerate(), "", "isolated", currency.ZRX) + _, err := e.GetMaximumLoanOfInstrument(contextGenerate(), "", "isolated", currency.ZRX) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetMaximumLoanOfInstrument(contextGenerate(), "ZRX-BTC", "", currency.ZRX) + _, err = e.GetMaximumLoanOfInstrument(contextGenerate(), "ZRX-BTC", "", currency.ZRX) require.ErrorIs(t, err, margin.ErrInvalidMarginType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMaximumLoanOfInstrument(contextGenerate(), mainPair.String(), "isolated", currency.ZRX) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaximumLoanOfInstrument(contextGenerate(), mainPair.String(), "isolated", currency.ZRX) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTradeFee(t *testing.T) { t.Parallel() - _, err := ok.GetTradeFee(contextGenerate(), "", "", "", "", "") + _, err := e.GetTradeFee(contextGenerate(), "", "", "", "", "") require.ErrorIs(t, err, errInvalidInstrumentType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetTradeFee(contextGenerate(), instTypeSpot, "", "", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTradeFee(contextGenerate(), instTypeSpot, "", "", "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetInterestAccruedData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetInterestAccruedData(contextGenerate(), 0, 1, currency.EMPTYCODE, "", "", time.Time{}, time.Time{}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInterestAccruedData(contextGenerate(), 0, 1, currency.EMPTYCODE, "", "", time.Time{}, time.Time{}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetInterestRate(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetInterestRate(contextGenerate(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInterestRate(contextGenerate(), currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestSetGreeks(t *testing.T) { t.Parallel() - _, err := ok.SetGreeks(contextGenerate(), "") + _, err := e.SetGreeks(contextGenerate(), "") require.ErrorIs(t, err, errMissingValidGreeksType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetGreeks(contextGenerate(), "PA") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetGreeks(contextGenerate(), "PA") require.NoError(t, err) assert.NotNil(t, result) } func TestIsolatedMarginTradingSettings(t *testing.T) { t.Parallel() - _, err := ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{}) + _, err := e.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "", InstrumentType: "MARGIN"}) + _, err = e.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "", InstrumentType: "MARGIN"}) require.ErrorIs(t, err, errMissingIsolatedMarginTradingSetting) - _, err = ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: ""}) + _, err = e.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: ""}) require.ErrorIs(t, err, errInvalidInstrumentType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: "MARGIN"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.IsolatedMarginTradingSettings(contextGenerate(), &IsolatedMode{IsoMode: "autonomy", InstrumentType: "MARGIN"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetMaximumWithdrawals(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMaximumWithdrawals(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMaximumWithdrawals(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountRiskState(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountRiskState(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountRiskState(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestVIPLoansBorrowAndRepay(t *testing.T) { t.Parallel() - _, err := ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{}) + _, err := e.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.EMPTYCODE, Side: "borrow", Amount: 12}) + _, err = e.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.EMPTYCODE, Side: "borrow", Amount: 12}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "", Amount: 12}) + _, err = e.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "", Amount: 12}) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 0}) + _, err = e.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 0}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 12}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.VIPLoansBorrowAndRepay(contextGenerate(), &LoanBorrowAndReplayInput{Currency: currency.BTC, Side: "borrow", Amount: 12}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetBorrowAndRepayHistoryForVIPLoans(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBorrowAndRepayHistoryForVIPLoans(contextGenerate(), currency.EMPTYCODE, time.Time{}, time.Time{}, 3) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBorrowAndRepayHistoryForVIPLoans(contextGenerate(), currency.EMPTYCODE, time.Time{}, time.Time{}, 3) require.NoError(t, err) assert.NotNil(t, result) } func TestGetBorrowInterestAndLimit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBorrowInterestAndLimit(contextGenerate(), 1, currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBorrowInterestAndLimit(contextGenerate(), 1, currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFixedLoanBorrowLimit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFixedLoanBorrowLimit(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFixedLoanBorrowLimit(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFixedLoanBorrowQuote(t *testing.T) { t.Parallel() - _, err := ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "", "30D", "123423423", 1, .4) + _, err := e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "", "30D", "123423423", 1, .4) require.ErrorIs(t, err, errBorrowTypeRequired) - _, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.EMPTYCODE, "normal", "30D", "123423423", 1, .4) + _, err = e.GetFixedLoanBorrowQuote(contextGenerate(), currency.EMPTYCODE, "normal", "30D", "123423423", 1, .4) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "", 0, .4) + _, err = e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "", 0, .4) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, 0) + _, err = e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, 0) require.ErrorIs(t, err, errMaxRateRequired) - _, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "", "123423423", 1, .4) + _, err = e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "", "123423423", 1, .4) require.ErrorIs(t, err, errLendingTermIsRequired) - _, err = ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "reborrow", "30D", "", 1, .4) + _, err = e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "reborrow", "30D", "", 1, .4) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, .4) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFixedLoanBorrowQuote(contextGenerate(), currency.USDT, "normal", "30D", "123423423", 1, .4) require.NoError(t, err) assert.NotNil(t, result) } func TestPlaceFixedLoanBorrowingOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.EMPTYCODE, 1, .3, .2, "30D", false) + _, err := e.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.EMPTYCODE, 1, .3, .2, "30D", false) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 0, .3, .2, "30D", false) + _, err = e.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 0, .3, .2, "30D", false) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, 0, .2, "30D", false) + _, err = e.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, 0, .2, "30D", false) require.ErrorIs(t, err, errMaxRateRequired) - _, err = ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "", false) + _, err = e.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "", false) require.ErrorIs(t, err, errLendingTermIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "30D", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceFixedLoanBorrowingOrder(contextGenerate(), currency.USDT, 1, .3, .2, "30D", false) require.NoError(t, err) assert.NotNil(t, result) } func TestAmendFixedLoanBorrowingOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendFixedLoanBorrowingOrder(contextGenerate(), "", false, .4) + _, err := e.AmendFixedLoanBorrowingOrder(contextGenerate(), "", false, .4) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendFixedLoanBorrowingOrder(contextGenerate(), "12312312", false, .4) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendFixedLoanBorrowingOrder(contextGenerate(), "12312312", false, .4) require.NoError(t, err) assert.NotNil(t, result) } func TestManualRenewFixedLoanBorrowingOrder(t *testing.T) { t.Parallel() - _, err := ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "", .3) + _, err := e.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "", .3) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", 0) + _, err = e.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", 0) require.ErrorIs(t, err, errMaxRateRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", .3) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ManualRenewFixedLoanBorrowingOrder(contextGenerate(), "12312312", .3) require.NoError(t, err) assert.NotNil(t, result) } func TestRepayFixedLoanBorrowingOrder(t *testing.T) { t.Parallel() - _, err := ok.RepayFixedLoanBorrowingOrder(contextGenerate(), "") + _, err := e.RepayFixedLoanBorrowingOrder(contextGenerate(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.RepayFixedLoanBorrowingOrder(contextGenerate(), "12321") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.RepayFixedLoanBorrowingOrder(contextGenerate(), "12321") require.NoError(t, err) assert.NotNil(t, result) } func TestConvertFixedLoanToMarketLoan(t *testing.T) { t.Parallel() - _, err := ok.ConvertFixedLoanToMarketLoan(contextGenerate(), "") + _, err := e.ConvertFixedLoanToMarketLoan(contextGenerate(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ConvertFixedLoanToMarketLoan(contextGenerate(), "12321") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ConvertFixedLoanToMarketLoan(contextGenerate(), "12321") require.NoError(t, err) assert.NotNil(t, result) } func TestReduceLiabilitiesForFixedLoan(t *testing.T) { t.Parallel() - _, err := ok.ReduceLiabilitiesForFixedLoan(contextGenerate(), "", false) + _, err := e.ReduceLiabilitiesForFixedLoan(contextGenerate(), "", false) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ReduceLiabilitiesForFixedLoan(contextGenerate(), "123123", false) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ReduceLiabilitiesForFixedLoan(contextGenerate(), "123123", false) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFixedLoanBorrowOrderList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFixedLoanBorrowOrderList(contextGenerate(), currency.USDT, "1231231", "8", "30D", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFixedLoanBorrowOrderList(contextGenerate(), currency.USDT, "1231231", "8", "30D", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestManualBorrowOrRepay(t *testing.T) { t.Parallel() - _, err := ok.ManualBorrowOrRepay(contextGenerate(), currency.EMPTYCODE, "borrow", 1) + _, err := e.ManualBorrowOrRepay(contextGenerate(), currency.EMPTYCODE, "borrow", 1) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "", 1) + _, err = e.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "", 1) require.ErrorIs(t, err, errLendingSideRequired) - _, err = ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 0) + _, err = e.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ManualBorrowOrRepay(contextGenerate(), currency.USDT, "borrow", 1) require.NoError(t, err) assert.NotNil(t, result) } func TestSetAutoRepay(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetAutoRepay(contextGenerate(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetAutoRepay(contextGenerate(), true) require.NoError(t, err) assert.NotNil(t, result) } func TestGetBorrowRepayHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBorrowRepayHistory(contextGenerate(), currency.ETH, "auto_borrow", time.Time{}, time.Time{}, 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBorrowRepayHistory(contextGenerate(), currency.ETH, "auto_borrow", time.Time{}, time.Time{}, 100) require.NoError(t, err) assert.NotNil(t, result) } func TestNewPositionBuilder(t *testing.T) { t.Parallel() - _, err := ok.NewPositionBuilder(contextGenerate(), nil) + _, err := e.NewPositionBuilder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.NewPositionBuilder(contextGenerate(), &PositionBuilderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.NewPositionBuilder(contextGenerate(), &PositionBuilderParam{ InclRealPosAndEq: false, SimPos: []SimulatedPosition{ { @@ -2632,72 +2632,72 @@ func TestNewPositionBuilder(t *testing.T) { func TestSetRiskOffsetAmount(t *testing.T) { t.Parallel() - _, err := ok.SetRiskOffsetAmount(contextGenerate(), currency.EMPTYCODE, 123) + _, err := e.SetRiskOffsetAmount(contextGenerate(), currency.EMPTYCODE, 123) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 0) + _, err = e.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 123) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.SetRiskOffsetAmount(contextGenerate(), currency.USDT, 123) require.NoError(t, err) assert.NotNil(t, result) } func TestGetGreeks(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - _, err := ok.GetGreeks(contextGenerate(), currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetGreeks(contextGenerate(), currency.EMPTYCODE) assert.NoError(t, err) } func TestGetPMLimitation(t *testing.T) { t.Parallel() - _, err := ok.GetPMPositionLimitation(contextGenerate(), "", mainPair.String(), "") + _, err := e.GetPMPositionLimitation(contextGenerate(), "", mainPair.String(), "") require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetPMPositionLimitation(contextGenerate(), "SWAP", "", "") + _, err = e.GetPMPositionLimitation(contextGenerate(), "SWAP", "", "") require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetPMPositionLimitation(contextGenerate(), "SWAP", mainPair.String(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPMPositionLimitation(contextGenerate(), "SWAP", mainPair.String(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestViewSubaccountList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.ViewSubAccountList(contextGenerate(), false, "", time.Time{}, time.Time{}, 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ViewSubAccountList(contextGenerate(), false, "", time.Time{}, time.Time{}, 2) require.NoError(t, err) assert.NotNil(t, result) } func TestResetSubAccountAPIKey(t *testing.T) { t.Parallel() - _, err := ok.ResetSubAccountAPIKey(contextGenerate(), nil) + _, err := e.ResetSubAccountAPIKey(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKey: apiKey, APIKeyPermission: "trade"}) + _, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKey: apiKey, APIKeyPermission: "trade"}) require.ErrorIs(t, err, errInvalidSubAccountName) - _, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{SubAccountName: "sam", APIKey: "", APIKeyPermission: "trade"}) + _, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{SubAccountName: "sam", APIKey: "", APIKeyPermission: "trade"}) require.ErrorIs(t, err, errInvalidAPIKey) - _, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{IP: "1.2.3.", SubAccountName: "sam", APIKeyPermission: "trade", APIKey: "sample-api-key"}) + _, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{IP: "1.2.3.", SubAccountName: "sam", APIKeyPermission: "trade", APIKey: "sample-api-key"}) require.ErrorIs(t, err, errInvalidIPAddress) - _, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKeyPermission: "abc", APIKey: "sample-api-key", SubAccountName: "sam"}) + _, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{APIKeyPermission: "abc", APIKey: "sample-api-key", SubAccountName: "sam"}) require.ErrorIs(t, err, errInvalidAPIKeyPermission) - _, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ + _, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ Permissions: []string{"abc"}, SubAccountName: "sam", APIKey: "sample-api-key", }) require.ErrorIs(t, err, errInvalidAPIKeyPermission) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ SubAccountName: "sam", APIKey: apiKey, APIKeyPermission: "trade", }) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ + result, err = e.ResetSubAccountAPIKey(contextGenerate(), &SubAccountAPIKeyParam{ SubAccountName: "sam", APIKey: apiKey, Permissions: []string{"trade", "read"}, @@ -2708,133 +2708,133 @@ func TestResetSubAccountAPIKey(t *testing.T) { func TestGetSubaccountTradingBalance(t *testing.T) { t.Parallel() - _, err := ok.GetSubaccountTradingBalance(contextGenerate(), "") + _, err := e.GetSubaccountTradingBalance(contextGenerate(), "") assert.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSubaccountTradingBalance(contextGenerate(), "test1") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubaccountTradingBalance(contextGenerate(), "test1") require.NoError(t, err) assert.NotNil(t, result) } func TestGetSubaccountFundingBalance(t *testing.T) { t.Parallel() - _, err := ok.GetSubaccountFundingBalance(contextGenerate(), "", currency.EMPTYCODE) + _, err := e.GetSubaccountFundingBalance(contextGenerate(), "", currency.EMPTYCODE) require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSubaccountFundingBalance(contextGenerate(), "test1", currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubaccountFundingBalance(contextGenerate(), "test1", currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSubAccountMaximumWithdrawal(t *testing.T) { t.Parallel() - _, err := ok.GetSubAccountMaximumWithdrawal(contextGenerate(), "", currency.BTC) + _, err := e.GetSubAccountMaximumWithdrawal(contextGenerate(), "", currency.BTC) require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSubAccountMaximumWithdrawal(contextGenerate(), "test1", currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccountMaximumWithdrawal(contextGenerate(), "test1", currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestHistoryOfSubaccountTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.HistoryOfSubaccountTransfer(contextGenerate(), currency.EMPTYCODE, "0", "", time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.HistoryOfSubaccountTransfer(contextGenerate(), currency.EMPTYCODE, "0", "", time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetHistoryOfManagedSubAccountTransfer(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetHistoryOfManagedSubAccountTransfer(contextGenerate(), currency.BTC, "", "", "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHistoryOfManagedSubAccountTransfer(contextGenerate(), currency.BTC, "", "", "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestMasterAccountsManageTransfersBetweenSubaccounts(t *testing.T) { t.Parallel() - _, err := ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{}) + _, err := e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &SubAccountAssetTransferParams{LoanTransfer: true} - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.Currency = currency.BTC - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 1234 - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidSubaccount) arg.From = 1 - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidSubaccount) arg.To = 7 - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidSubaccount) arg.To = 6 - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidSubAccountName) arg.FromSubAccount = "sami" - _, err = ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) + _, err = e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{Currency: currency.BTC, Amount: 1200, From: 6, To: 6, FromSubAccount: "test1", ToSubAccount: "test2", LoanTransfer: true}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.MasterAccountsManageTransfersBetweenSubaccounts(contextGenerate(), &SubAccountAssetTransferParams{Currency: currency.BTC, Amount: 1200, From: 6, To: 6, FromSubAccount: "test1", ToSubAccount: "test2", LoanTransfer: true}) require.NoError(t, err) assert.NotNil(t, result) } func TestSetPermissionOfTransferOut(t *testing.T) { t.Parallel() - _, err := ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{}) + _, err := e.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{CanTransOut: true}) + _, err = e.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{CanTransOut: true}) require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{SubAcct: "Test1"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.SetPermissionOfTransferOut(contextGenerate(), &PermissionOfTransfer{SubAcct: "Test1"}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCustodyTradingSubaccountList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCustodyTradingSubaccountList(contextGenerate(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCustodyTradingSubaccountList(contextGenerate(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestSetSubAccountVIPLoanAllocation(t *testing.T) { t.Parallel() - _, err := ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{}) + _, err := e.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := subAccountVIPLoanAllocationInfo{} - _, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) + _, err = e.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) require.ErrorIs(t, err, common.ErrEmptyParams) arg.LoanAlloc = 123 - _, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) + _, err = e.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) require.ErrorIs(t, err, errInvalidSubAccountName) arg.LoanAlloc = -1 arg.SubAcct = "sams" - _, err = ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) + _, err = e.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{Alloc: []subAccountVIPLoanAllocationInfo{arg}}) require.ErrorIs(t, err, errInvalidLoanAllocationValue) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetSubAccountVIPLoanAllocation(contextGenerate(), &SubAccountLoanAllocationParam{ Enable: true, Alloc: []subAccountVIPLoanAllocationInfo{ { @@ -2849,11 +2849,11 @@ func TestSetSubAccountVIPLoanAllocation(t *testing.T) { func TestGetSubAccountBorrowInterestAndLimit(t *testing.T) { t.Parallel() - _, err := ok.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "", currency.ETH) + _, err := e.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "", currency.ETH) require.ErrorIs(t, err, errInvalidSubAccountName) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "123456", currency.ETH) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSubAccountBorrowInterestAndLimit(contextGenerate(), "123456", currency.ETH) require.NoError(t, err) assert.NotNil(t, result) } @@ -2862,55 +2862,55 @@ func TestGetSubAccountBorrowInterestAndLimit(t *testing.T) { func TestGetProductInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetProductInfo(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetProductInfo(contextGenerate()) require.NoError(t, err) assert.NotEmpty(t, result) } func TestPurcahseETHStaking(t *testing.T) { t.Parallel() - err := ok.PurchaseETHStaking(contextGenerate(), 0) + err := e.PurchaseETHStaking(contextGenerate(), 0) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - err = ok.PurchaseETHStaking(contextGenerate(), 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.PurchaseETHStaking(contextGenerate(), 100) assert.NoError(t, err) } // RedeemETHStaking func TestRedeemETHStaking(t *testing.T) { t.Parallel() - err := ok.RedeemETHStaking(contextGenerate(), 0) + err := e.RedeemETHStaking(contextGenerate(), 0) assert.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - err = ok.RedeemETHStaking(contextGenerate(), 100) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.RedeemETHStaking(contextGenerate(), 100) assert.NoError(t, err) } func TestGetBETHAssetsBalance(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBETHAssetsBalance(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBETHAssetsBalance(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetPurchaseAndRedeemHistory(t *testing.T) { t.Parallel() - _, err := ok.GetPurchaseAndRedeemHistory(contextGenerate(), "", "pending", time.Time{}, time.Now(), 10) + _, err := e.GetPurchaseAndRedeemHistory(contextGenerate(), "", "pending", time.Time{}, time.Now(), 10) require.ErrorIs(t, err, errLendingTermIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetPurchaseAndRedeemHistory(contextGenerate(), "purchase", "pending", time.Time{}, time.Now(), 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetPurchaseAndRedeemHistory(contextGenerate(), "purchase", "pending", time.Time{}, time.Now(), 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAPYHistory(t *testing.T) { t.Parallel() - result, err := ok.GetAPYHistory(contextGenerate(), 34) + result, err := e.GetAPYHistory(contextGenerate(), 34) require.NoError(t, err) assert.NotNil(t, result) } @@ -2923,44 +2923,44 @@ func TestPlaceGridAlgoOrder(t *testing.T) { err := json.Unmarshal([]byte(gridTradingPlaceOrder), &input) require.NoError(t, err) - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), &GridAlgoOrder{}) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), &GridAlgoOrder{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &GridAlgoOrder{BasePosition: true} - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingAlgoOrderType) arg.AlgoOrdType = "contract_grid" - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.MaxPrice = 1000 - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.MinPrice = 1200 arg.GridQuantity = -1 - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidGridQuantity) arg.GridQuantity = 123 - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountMustBeSet) arg.Size = 123 - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingRequiredArgumentDirection) arg.Direction = positionSideLong - _, err = ok.PlaceGridAlgoOrder(contextGenerate(), arg) + _, err = e.PlaceGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidLeverage) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceGridAlgoOrder(contextGenerate(), &input) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceGridAlgoOrder(contextGenerate(), &input) require.NoError(t, err) assert.NotNil(t, result) } @@ -2979,19 +2979,19 @@ func TestAmendGridAlgoOrder(t *testing.T) { require.NoError(t, err) arg := &GridAlgoOrderAmend{} - _, err = ok.AmendGridAlgoOrder(contextGenerate(), arg) + _, err = e.AmendGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, common.ErrEmptyParams) arg.TakeProfitTriggerPrice = 1234.5 - _, err = ok.AmendGridAlgoOrder(contextGenerate(), arg) + _, err = e.AmendGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errAlgoIDRequired) arg.AlgoID = "560472804207104000" - _, err = ok.AmendGridAlgoOrder(contextGenerate(), arg) + _, err = e.AmendGridAlgoOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendGridAlgoOrder(contextGenerate(), input) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendGridAlgoOrder(contextGenerate(), input) require.NoError(t, err) assert.NotNil(t, result) } @@ -3004,79 +3004,79 @@ func TestStopGridAlgoOrder(t *testing.T) { err := json.Unmarshal([]byte(stopGridAlgoOrderJSON), &resp) require.NoError(t, err) - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := StopGridAlgoOrderRequest{} - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) require.ErrorIs(t, err, common.ErrEmptyParams) arg.StopType = 20 - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) require.ErrorIs(t, err, errAlgoIDRequired) arg.AlgoID = "algo_id" - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) require.ErrorIs(t, err, errMissingAlgoOrderType) arg.AlgoOrderType = AlgoOrdTypeGrid - _, err = ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) + _, err = e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{arg}) require.ErrorIs(t, err, errMissingValidStopType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{resp}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.StopGridAlgoOrder(contextGenerate(), []StopGridAlgoOrderRequest{resp}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetGridAlgoOrdersList(t *testing.T) { t.Parallel() - _, err := ok.GetGridAlgoOrdersList(contextGenerate(), "abc", "", "", "", "", "", 1) + _, err := e.GetGridAlgoOrdersList(contextGenerate(), "abc", "", "", "", "", "", 1) require.ErrorIs(t, err, errMissingAlgoOrderType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetGridAlgoOrdersList(contextGenerate(), "grid", "", "", "", "", "", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetGridAlgoOrdersList(contextGenerate(), "grid", "", "", "", "", "", 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetGridAlgoOrderHistory(t *testing.T) { t.Parallel() - _, err := ok.GetGridAlgoOrderHistory(contextGenerate(), "abc", "", "", "", "", "", 1) + _, err := e.GetGridAlgoOrderHistory(contextGenerate(), "abc", "", "", "", "", "", 1) require.ErrorIs(t, err, errMissingAlgoOrderType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetGridAlgoOrderHistory(contextGenerate(), "contract_grid", "", "", "", "", "", 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetGridAlgoOrderHistory(contextGenerate(), "contract_grid", "", "", "", "", "", 1) require.NoError(t, err) assert.NotNil(t, result) } func TestGetGridAlgoOrderDetails(t *testing.T) { t.Parallel() - _, err := ok.GetGridAlgoOrderDetails(contextGenerate(), "grid", "") + _, err := e.GetGridAlgoOrderDetails(contextGenerate(), "grid", "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetGridAlgoOrderDetails(contextGenerate(), "grid", "7878") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetGridAlgoOrderDetails(contextGenerate(), "grid", "7878") require.NoError(t, err) assert.NotNil(t, result) } func TestGetGridAlgoSubOrders(t *testing.T) { t.Parallel() - _, err := ok.GetGridAlgoSubOrders(contextGenerate(), "", "", "", "", "", "", 2) + _, err := e.GetGridAlgoSubOrders(contextGenerate(), "", "", "", "", "", "", 2) require.ErrorIs(t, err, errMissingAlgoOrderType) - _, err = ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "", "", "", "", "", 2) + _, err = e.GetGridAlgoSubOrders(contextGenerate(), "grid", "", "", "", "", "", 2) require.ErrorIs(t, err, errAlgoIDRequired) - _, err = ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "", "", "", "", 2) + _, err = e.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "", "", "", "", 2) require.ErrorIs(t, err, errMissingSubOrderType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "live", "", "", "", 2) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetGridAlgoSubOrders(contextGenerate(), "grid", "1234", "live", "", "", "", 2) require.NoError(t, err) assert.NotNil(t, result) } @@ -3088,38 +3088,38 @@ func TestGetGridAlgoOrderPositions(t *testing.T) { var resp AlgoOrderPosition err := json.Unmarshal([]byte(spotGridAlgoOrderPosition), &resp) require.NoError(t, err) - _, err = ok.GetGridAlgoOrderPositions(contextGenerate(), "", "") + _, err = e.GetGridAlgoOrderPositions(contextGenerate(), "", "") require.ErrorIs(t, err, errInvalidAlgoOrderType) - _, err = ok.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "") + _, err = e.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "448965992920907776") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetGridAlgoOrderPositions(contextGenerate(), "contract_grid", "448965992920907776") require.NoError(t, err) assert.NotNil(t, result) } func TestSpotGridWithdrawProfit(t *testing.T) { t.Parallel() - _, err := ok.SpotGridWithdrawProfit(contextGenerate(), "") + _, err := e.SpotGridWithdrawProfit(contextGenerate(), "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SpotGridWithdrawProfit(contextGenerate(), "1234") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SpotGridWithdrawProfit(contextGenerate(), "1234") require.NoError(t, err) assert.NotNil(t, result) } func TestComputeMarginBalance(t *testing.T) { t.Parallel() - _, err := ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AlgoID: "123456", AdjustMarginBalanceType: "other"}) + _, err := e.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AlgoID: "123456", AdjustMarginBalanceType: "other"}) require.ErrorIs(t, err, errInvalidMarginTypeAdjust) - _, err = ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AdjustMarginBalanceType: "other"}) + _, err = e.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{AdjustMarginBalanceType: "other"}) require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ComputeMarginBalance(contextGenerate(), MarginBalanceParam{ AlgoID: "123456", AdjustMarginBalanceType: "reduce", }) @@ -3130,24 +3130,24 @@ func TestComputeMarginBalance(t *testing.T) { func TestAdjustMarginBalance(t *testing.T) { t.Parallel() arg := &MarginBalanceParam{} - _, err := ok.AdjustMarginBalance(contextGenerate(), arg) + _, err := e.AdjustMarginBalance(contextGenerate(), arg) require.ErrorIs(t, err, common.ErrEmptyParams) arg.Amount = 12345 - _, err = ok.AdjustMarginBalance(contextGenerate(), arg) + _, err = e.AdjustMarginBalance(contextGenerate(), arg) require.ErrorIs(t, err, errAlgoIDRequired) arg.AlgoID = "1234" - _, err = ok.AdjustMarginBalance(contextGenerate(), arg) + _, err = e.AdjustMarginBalance(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidMarginTypeAdjust) arg.AdjustMarginBalanceType = "reduce" arg.Amount = 0 - _, err = ok.AdjustMarginBalance(contextGenerate(), arg) + _, err = e.AdjustMarginBalance(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AdjustMarginBalance(contextGenerate(), &MarginBalanceParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AdjustMarginBalance(contextGenerate(), &MarginBalanceParam{ AlgoID: "1234", AdjustMarginBalanceType: "reduce", Amount: 12345, @@ -3164,42 +3164,42 @@ func TestGetGridAIParameter(t *testing.T) { err := json.Unmarshal([]byte(gridAIParamJSON), &response) require.NoError(t, err) - _, err = ok.GetGridAIParameter(contextGenerate(), "", mainPair.String(), "", "") + _, err = e.GetGridAIParameter(contextGenerate(), "", mainPair.String(), "", "") require.ErrorIs(t, err, errInvalidAlgoOrderType) - _, err = ok.GetGridAIParameter(contextGenerate(), "grid", "", "", "") + _, err = e.GetGridAIParameter(contextGenerate(), "grid", "", "", "") require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.GetGridAIParameter(contextGenerate(), "contract_grid", mainPair.String(), "", "") + _, err = e.GetGridAIParameter(contextGenerate(), "contract_grid", mainPair.String(), "", "") require.ErrorIs(t, err, errMissingRequiredArgumentDirection) - _, err = ok.GetGridAIParameter(contextGenerate(), "grid", mainPair.String(), "", "12M") + _, err = e.GetGridAIParameter(contextGenerate(), "grid", mainPair.String(), "", "12M") require.ErrorIs(t, err, errInvalidDuration) - result, err := ok.GetGridAIParameter(contextGenerate(), "grid", mainPair.String(), "", "") + result, err := e.GetGridAIParameter(contextGenerate(), "grid", mainPair.String(), "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOffers(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOffers(contextGenerate(), "", "", currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOffers(contextGenerate(), "", "", currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestPurchase(t *testing.T) { t.Parallel() - _, err := ok.Purchase(contextGenerate(), nil) + _, err := e.Purchase(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{Term: 2}) + _, err = e.Purchase(contextGenerate(), &PurchaseRequestParam{Term: 2}) require.ErrorIs(t, err, errMissingRequiredParameter) - _, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Amount: 1}}}) + _, err = e.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Amount: 1}}}) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Currency: currency.USDT}}}) + _, err = e.Purchase(contextGenerate(), &PurchaseRequestParam{ProductID: "1234", Term: 2, InvestData: []PurchaseInvestDataItem{{Currency: currency.USDT}}}) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.Purchase(contextGenerate(), &PurchaseRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.Purchase(contextGenerate(), &PurchaseRequestParam{ ProductID: "1234", InvestData: []PurchaseInvestDataItem{ { @@ -3219,15 +3219,15 @@ func TestPurchase(t *testing.T) { func TestRedeem(t *testing.T) { t.Parallel() - _, err := ok.Redeem(contextGenerate(), &RedeemRequestParam{}) + _, err := e.Redeem(contextGenerate(), &RedeemRequestParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.Redeem(contextGenerate(), &RedeemRequestParam{AllowEarlyRedeem: true}) + _, err = e.Redeem(contextGenerate(), &RedeemRequestParam{AllowEarlyRedeem: true}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.Redeem(contextGenerate(), &RedeemRequestParam{OrderID: "754147"}) + _, err = e.Redeem(contextGenerate(), &RedeemRequestParam{OrderID: "754147"}) require.ErrorIs(t, err, errInvalidProtocolType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.Redeem(contextGenerate(), &RedeemRequestParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.Redeem(contextGenerate(), &RedeemRequestParam{ OrderID: "754147", ProtocolType: "defi", AllowEarlyRedeem: true, @@ -3238,15 +3238,15 @@ func TestRedeem(t *testing.T) { func TestCancelPurchaseOrRedemption(t *testing.T) { t.Parallel() - _, err := ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{}) + _, err := e.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{ProtocolType: "defi"}) + _, err = e.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{ProtocolType: "defi"}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{OrderID: "754147"}) + _, err = e.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{OrderID: "754147"}) require.ErrorIs(t, err, errInvalidProtocolType) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelPurchaseOrRedemption(contextGenerate(), &CancelFundingParam{ OrderID: "754147", ProtocolType: "defi", }) @@ -3256,23 +3256,23 @@ func TestCancelPurchaseOrRedemption(t *testing.T) { func TestGetEarnActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetEarnActiveOrders(contextGenerate(), "", "", "", currency.EMPTYCODE) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEarnActiveOrders(contextGenerate(), "", "", "", currency.EMPTYCODE) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFundingOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFundingOrderHistory(contextGenerate(), "", "", currency.EMPTYCODE, time.Time{}, time.Time{}, 1) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFundingOrderHistory(contextGenerate(), "", "", currency.EMPTYCODE, time.Time{}, time.Time{}, 1) require.NoError(t, err) assert.NotNil(t, result) } func TestSystemStatusResponse(t *testing.T) { t.Parallel() - result, err := ok.SystemStatusResponse(contextGenerate(), "completed") + result, err := e.SystemStatusResponse(contextGenerate(), "completed") require.NoError(t, err) assert.NotNil(t, result) } @@ -3305,7 +3305,7 @@ func TestAssetTypeFromInstrumentType(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() for _, a := range []asset.Item{asset.Options, asset.PerpetualSwap, asset.Futures, asset.Spot, asset.Spread} { - result, err := ok.FetchTradablePairs(contextGenerate(), a) + result, err := e.FetchTradablePairs(contextGenerate(), a) assert.NoError(t, err) assert.NotNil(t, result) } @@ -3313,24 +3313,24 @@ func TestFetchTradablePairs(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) + testexch.UpdatePairsOnce(t, e) } func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - err := ok.UpdateOrderExecutionLimits(contextGenerate(), a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateOrderExecutionLimits(contextGenerate(), a) if !assert.NoError(t, err) { continue } - p, err := ok.GetAvailablePairs(a) + p, err := e.GetAvailablePairs(a) require.NoErrorf(t, err, "GetAvailablePairs for asset %s must not error", a) require.NotEmptyf(t, p, "GetAvailablePairs for asset %s must not return empty pairs", a) - limits, err := ok.GetOrderExecutionLimits(a, p[0]) + limits, err := e.GetOrderExecutionLimits(a, p[0]) if assert.NoErrorf(t, err, "GetOrderExecutionLimits for asset %s and pair %s should not error", a, p[0]) { require.Positivef(t, limits.PriceStepIncrementSize, "PriceStepIncrementSize must be positive for %s", p[0]) require.Positivef(t, limits.MinimumBaseAmount, "MinimumBaseAmount must be positive for %s", p[0]) @@ -3341,15 +3341,15 @@ func TestUpdateOrderExecutionLimits(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := ok.UpdateTicker(contextGenerate(), currency.Pair{}, asset.Binary) + _, err := e.UpdateTicker(contextGenerate(), currency.Pair{}, asset.Binary) require.ErrorIs(t, err, asset.ErrNotSupported) - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - p, err := ok.GetAvailablePairs(a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + p, err := e.GetAvailablePairs(a) require.NoErrorf(t, err, "GetAvailablePairs for asset %s must not error", a) require.NotEmptyf(t, p, "GetAvailablePairs for asset %s must not return empty pairs", a) - result, err := ok.UpdateTicker(contextGenerate(), p[0], a) + result, err := e.UpdateTicker(contextGenerate(), p[0], a) require.NoErrorf(t, err, "UpdateTicker for asset %s and pair %s must not error", a, p[0]) assert.NotNilf(t, result, "UpdateTicker for asset %s and pair %s should not return nil", a, p[0]) } @@ -3357,21 +3357,21 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - err := ok.UpdateTickers(contextGenerate(), a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + err := e.UpdateTickers(contextGenerate(), a) require.NoErrorf(t, err, "UpdateTickers for asset %s must not error", a) } } func TestUpdateOrderbook(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - p, err := ok.GetAvailablePairs(a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + p, err := e.GetAvailablePairs(a) require.NoErrorf(t, err, "GetAvailablePairs for asset %s must not error", a) require.NotEmptyf(t, p, "GetAvailablePairs for asset %s must not return empty pairs", a) - result, err := ok.UpdateOrderbook(contextGenerate(), p[0], a) + result, err := e.UpdateOrderbook(contextGenerate(), p[0], a) require.NoErrorf(t, err, "UpdateOrderbook for asset %s and pair %s must not error", a, p[0]) assert.NotNilf(t, result, "UpdateOrderbook for asset %s and pair %s should not return nil", a, p[0]) } @@ -3379,34 +3379,34 @@ func TestUpdateOrderbook(t *testing.T) { func TestUpdateAccountInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.UpdateAccountInfo(contextGenerate(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.UpdateAccountInfo(contextGenerate(), asset.Spot) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountFundingHistory(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountFundingHistory(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetWithdrawalsHistory(contextGenerate(), currency.BTC, asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalsHistory(contextGenerate(), currency.BTC, asset.Spot) require.NoError(t, err) assert.NotNil(t, result) } func TestGetRecentTrades(t *testing.T) { t.Parallel() - result, err := ok.GetRecentTrades(contextGenerate(), mainPair, asset.PerpetualSwap) + result, err := e.GetRecentTrades(contextGenerate(), mainPair, asset.PerpetualSwap) require.NoError(t, err) require.NotNil(t, result) - result, err = ok.GetRecentTrades(contextGenerate(), mainPair, asset.Spread) + result, err = e.GetRecentTrades(contextGenerate(), mainPair, asset.Spread) require.NoError(t, err) assert.NotNil(t, result) } @@ -3418,37 +3418,37 @@ func TestSubmitOrder(t *testing.T) { require.NoError(t, err) arg := &order.Submit{ - Exchange: ok.Name, + Exchange: e.Name, Side: order.Buy, Type: order.Limit, Price: 1, ClientID: "yeneOrder", AssetType: asset.Binary, } - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) require.ErrorIs(t, err, asset.ErrNotSupported) arg.AssetType = asset.Spot - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 1000000000 - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Pair = mainPair arg.AssetType = asset.Futures arg.Leverage = -1 - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSubmitLeverageNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) arg = &order.Submit{ Pair: currency.Pair{ Base: currency.LTC, Quote: currency.BTC, }, - Exchange: ok.Name, + Exchange: e.Name, Side: order.Sell, Type: order.Limit, Price: 120000, @@ -3456,49 +3456,49 @@ func TestSubmitOrder(t *testing.T) { ClientID: "yeneOrder", AssetType: asset.Spot, } - result, err := ok.SubmitOrder(contextGenerate(), arg) + result, err := e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.Trigger arg.TriggerPrice = 11999 arg.TriggerPriceType = order.LastPrice - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.ConditionalStop arg.TriggerPrice = 11999 arg.TriggerPriceType = order.IndexPrice - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.Chase - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) assert.ErrorIs(t, err, order.ErrUnknownTrackingMode) arg.TrackingMode = order.Percentage - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) assert.ErrorIs(t, err, order.ErrAmountBelowMin) arg.TrackingValue = .5 - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.TWAP - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.TrailingStop - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.OCO - _, err = ok.SubmitOrder(contextGenerate(), arg) + _, err = e.SubmitOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.RiskManagementModes = order.RiskManagementModes{ @@ -3511,7 +3511,7 @@ func TestSubmitOrder(t *testing.T) { LimitPrice: 11000, }, } - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) @@ -3520,7 +3520,7 @@ func TestSubmitOrder(t *testing.T) { arg = &order.Submit{ Pair: cp, - Exchange: ok.Name, + Exchange: e.Name, Side: order.Long, Type: order.Market, Amount: 1, @@ -3528,16 +3528,16 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Futures, MarginType: margin.Multi, } - result, err = ok.SubmitOrder(contextGenerate(), arg) + result, err = e.SubmitOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) pair, err := currency.NewPairFromString("BTC-USDT-SWAP_BTC-USDT-250328") require.NoError(t, err) - result, err = ok.SubmitOrder(contextGenerate(), &order.Submit{ + result, err = e.SubmitOrder(contextGenerate(), &order.Submit{ Pair: pair, - Exchange: ok.Name, + Exchange: e.Name, Side: order.Sell, Type: order.Limit, Price: 120000, @@ -3556,29 +3556,29 @@ func TestCancelOrder(t *testing.T) { AccountID: "1", AssetType: asset.Binary, } - err := ok.CancelOrder(contextGenerate(), arg) + err := e.CancelOrder(contextGenerate(), arg) require.ErrorIs(t, err, asset.ErrNotSupported) arg.AssetType = asset.Spot - err = ok.CancelOrder(contextGenerate(), arg) + err = e.CancelOrder(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Pair = mainPair - err = ok.CancelOrder(contextGenerate(), arg) + err = e.CancelOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - err = ok.CancelOrder(contextGenerate(), &order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.CancelOrder(contextGenerate(), &order.Cancel{ OrderID: "1", AccountID: "1", Pair: mainPair, AssetType: asset.Spot, }) assert.NoError(t, err) - err = ok.CancelOrder(contextGenerate(), &order.Cancel{ + err = e.CancelOrder(contextGenerate(), &order.Cancel{ Type: order.OCO, OrderID: "1", AccountID: "1", Pair: mainPair, AssetType: asset.Spot, }) assert.NoError(t, err) - err = ok.CancelOrder(contextGenerate(), &order.Cancel{ + err = e.CancelOrder(contextGenerate(), &order.Cancel{ OrderID: "1", AccountID: "1", Pair: spreadPair, AssetType: asset.Spread, }) assert.NoError(t, err) @@ -3586,36 +3586,36 @@ func TestCancelOrder(t *testing.T) { func TestCancelBatchOrders(t *testing.T) { t.Parallel() - _, err := ok.CancelBatchOrders(contextGenerate(), make([]order.Cancel, 21)) + _, err := e.CancelBatchOrders(contextGenerate(), make([]order.Cancel, 21)) require.ErrorIs(t, err, errExceedLimit) - _, err = ok.CancelBatchOrders(contextGenerate(), nil) + _, err = e.CancelBatchOrders(contextGenerate(), nil) require.ErrorIs(t, err, order.ErrCancelOrderIsNil) arg := order.Cancel{ AccountID: "1", AssetType: asset.Binary, } - _, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) + _, err = e.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) require.ErrorIs(t, err, asset.ErrNotSupported) arg.AssetType = asset.Spot - _, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) + _, err = e.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) require.ErrorIs(t, err, currency.ErrCurrencyPairsEmpty) arg.Pair = mainPair arg.Type = order.Liquidation - _, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) + _, err = e.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) require.ErrorIs(t, err, order.ErrUnsupportedOrderType) arg.Type = order.Trigger - _, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) + _, err = e.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) arg.Type = order.Limit - _, err = ok.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) + _, err = e.CancelBatchOrders(contextGenerate(), []order.Cancel{arg}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) orderCancellationParams := []order.Cancel{ { OrderID: "1", @@ -3637,65 +3637,65 @@ func TestCancelBatchOrders(t *testing.T) { AssetType: asset.Spot, }, } - result, err := ok.CancelBatchOrders(contextGenerate(), orderCancellationParams) + result, err := e.CancelBatchOrders(contextGenerate(), orderCancellationParams) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllOrders(t *testing.T) { t.Parallel() - _, err := ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Binary}) + _, err := e.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Binary}) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spread}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spread}) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Futures}) + result, err = e.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Futures}) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spot}) + result, err = e.CancelAllOrders(contextGenerate(), &order.Cancel{AssetType: asset.Spot}) assert.NoError(t, err) assert.NotNil(t, result) } func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := ok.ModifyOrder(contextGenerate(), nil) + _, err := e.ModifyOrder(contextGenerate(), nil) require.ErrorIs(t, err, order.ErrModifyOrderIsNil) arg := &order.Modify{} - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPairIsEmpty) arg.Pair = mainPair - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAssetNotSet) arg.AssetType = asset.Spot - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrOrderIDNotSet) arg.OrderID = "1234" arg.Type = order.Liquidation - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrUnsupportedOrderType) arg.Type = order.Limit - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation) arg.Type = order.Trigger - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.Type = order.OCO - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) arg = &order.Modify{ AssetType: asset.Spot, Pair: mainPair, @@ -3703,37 +3703,37 @@ func TestModifyOrder(t *testing.T) { Price: 123456.44, Amount: 123, } - result, err := ok.ModifyOrder(contextGenerate(), arg) + result, err := e.ModifyOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.Limit - result, err = ok.ModifyOrder(contextGenerate(), arg) + result, err = e.ModifyOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.Trigger - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.TriggerPrice = 12345678 - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) arg.Type = order.OCO - _, err = ok.ModifyOrder(contextGenerate(), arg) + _, err = e.ModifyOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.RiskManagementModes = order.RiskManagementModes{ TakeProfit: order.RiskManagement{Price: 12345677}, StopLoss: order.RiskManagement{Price: 12345667}, } - result, err = ok.ModifyOrder(contextGenerate(), arg) + result, err = e.ModifyOrder(contextGenerate(), arg) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.ModifyOrder(contextGenerate(), + result, err = e.ModifyOrder(contextGenerate(), &order.Modify{ AssetType: asset.Spread, Pair: spreadPair, @@ -3747,23 +3747,23 @@ func TestModifyOrder(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetOrderInfo(contextGenerate(), "123", perpetualSwapPair, asset.PerpetualSwap) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetOrderInfo(contextGenerate(), "123", perpetualSwapPair, asset.PerpetualSwap) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.GetOrderInfo(contextGenerate(), "123", spreadPair, asset.Spread) + result, err = e.GetOrderInfo(contextGenerate(), "123", spreadPair, asset.Spread) require.NoError(t, err) assert.NotNil(t, result) } func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := ok.GetDepositAddress(contextGenerate(), currency.EMPTYCODE, "", "") + _, err := e.GetDepositAddress(contextGenerate(), currency.EMPTYCODE, "", "") require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetDepositAddress(contextGenerate(), currency.BTC, core.BitcoinDonationAddress, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositAddress(contextGenerate(), currency.BTC, core.BitcoinDonationAddress, "") require.NoError(t, err) assert.NotNil(t, result) } @@ -3771,16 +3771,16 @@ func TestGetDepositAddress(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: ok.Name, + Exchange: e.Name, Amount: 0.00000000001, Currency: currency.BTC, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, }, } - result, err := ok.WithdrawCryptocurrencyFunds(contextGenerate(), &withdrawCryptoRequest) + result, err := e.WithdrawCryptocurrencyFunds(contextGenerate(), &withdrawCryptoRequest) require.NoError(t, err) assert.NotNil(t, result) } @@ -3792,20 +3792,20 @@ func TestGetPairFromInstrumentID(t *testing.T) { perpetualSwapPair.String(), "BTC-USDT-ER33234", } - dPair, err := ok.GetPairFromInstrumentID(instruments[0]) + dPair, err := e.GetPairFromInstrumentID(instruments[0]) require.NoError(t, err) require.NotNil(t, dPair) - dPair, err = ok.GetPairFromInstrumentID(instruments[1]) + dPair, err = e.GetPairFromInstrumentID(instruments[1]) require.NoError(t, err) require.NotNil(t, dPair) - dPair, err = ok.GetPairFromInstrumentID(instruments[2]) + dPair, err = e.GetPairFromInstrumentID(instruments[2]) require.NoError(t, err) assert.NotNil(t, dPair) } func TestGetActiveOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) for _, a := range []asset.Item{asset.Spot, asset.Spread} { pairs := []currency.Pair{currency.NewPair(currency.LTC, currency.USDT), mainPair} @@ -3813,7 +3813,7 @@ func TestGetActiveOrders(t *testing.T) { pairs = []currency.Pair{spreadPair} } - result, err := ok.GetActiveOrders(contextGenerate(), &order.MultiOrderRequest{ + result, err := e.GetActiveOrders(contextGenerate(), &order.MultiOrderRequest{ Type: order.Limit, Pairs: pairs, AssetType: asset.Spot, @@ -3831,26 +3831,26 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, Side: order.Buy, } - _, err := ok.GetOrderHistory(contextGenerate(), &getOrdersRequest) + _, err := e.GetOrderHistory(contextGenerate(), &getOrdersRequest) require.ErrorIs(t, err, currency.ErrCurrencyPairsEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) getOrdersRequest.Pairs = []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)} - result, err := ok.GetOrderHistory(contextGenerate(), &getOrdersRequest) + result, err := e.GetOrderHistory(contextGenerate(), &getOrdersRequest) assert.NoError(t, err) assert.NotNil(t, result) getOrdersRequest.AssetType = asset.Spread getOrdersRequest.Type = order.Market - result, err = ok.GetOrderHistory(contextGenerate(), &getOrdersRequest) + result, err = e.GetOrderHistory(contextGenerate(), &getOrdersRequest) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFeeByType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFeeByType(contextGenerate(), &exchange.FeeBuilder{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFeeByType(contextGenerate(), &exchange.FeeBuilder{ Amount: 1, FeeType: exchange.CryptocurrencyTradeFee, Pair: currency.NewPairWithDelimiter(currency.BTC.String(), @@ -3866,28 +3866,28 @@ func TestGetFeeByType(t *testing.T) { func TestValidateAPICredentials(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - err := ok.ValidateAPICredentials(contextGenerate(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + err := e.ValidateAPICredentials(contextGenerate(), asset.Spot) assert.NoError(t, err) } func TestGetHistoricCandles(t *testing.T) { t.Parallel() - _, err := ok.GetHistoricCandles(contextGenerate(), currency.Pair{}, asset.Binary, kline.OneDay, time.Now(), time.Now()) + _, err := e.GetHistoricCandles(contextGenerate(), currency.Pair{}, asset.Binary, kline.OneDay, time.Now(), time.Now()) require.ErrorIs(t, err, asset.ErrNotSupported) startTime := time.Date(2021, 2, 1, 0, 0, 0, 0, time.UTC) endTime := startTime.AddDate(0, 0, 100) - _, err = ok.GetHistoricCandles(contextGenerate(), mainPair, asset.Spot, kline.Interval(time.Hour*4), startTime, endTime) + _, err = e.GetHistoricCandles(contextGenerate(), mainPair, asset.Spot, kline.Interval(time.Hour*4), startTime, endTime) require.ErrorIs(t, err, kline.ErrRequestExceedsExchangeLimits) - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - pairs, err := ok.GetEnabledPairs(a) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs for asset %s must not error", a) require.NotEmptyf(t, pairs, "GetEnabledPairs for asset %s must not return empty pairs", a) - result, err := ok.GetHistoricCandles(contextGenerate(), pairs[0], a, kline.OneMin, time.Now().Add(-time.Hour), time.Now()) + result, err := e.GetHistoricCandles(contextGenerate(), pairs[0], a, kline.OneMin, time.Now().Add(-time.Hour), time.Now()) if (a == asset.Spread || a == asset.Options) && err != nil { // Options and spread candles sometimes returns no data continue } @@ -3898,7 +3898,7 @@ func TestGetHistoricCandles(t *testing.T) { func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - result, err := ok.GetHistoricCandlesExtended(contextGenerate(), mainPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Hour), time.Now()) + result, err := e.GetHistoricCandlesExtended(contextGenerate(), mainPair, asset.Spot, kline.OneMin, time.Now().Add(-time.Hour), time.Now()) require.NoError(t, err) assert.NotNil(t, result) } @@ -3913,15 +3913,15 @@ func TestGenerateOrderbookChecksum(t *testing.T) { func TestOrderPushData(t *testing.T) { t.Parallel() - ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(ok), "Test instance Setup must not error") - testexch.FixtureToDataHandler(t, "testdata/wsOrders.json", ok.WsHandleData) - close(ok.Websocket.DataHandler) - require.Len(t, ok.Websocket.DataHandler, 4, "Should see 4 orders") - for resp := range ok.Websocket.DataHandler { + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + testexch.FixtureToDataHandler(t, "testdata/wsOrders.json", e.WsHandleData) + close(e.Websocket.DataHandler) + require.Len(t, e.Websocket.DataHandler, 4, "Should see 4 orders") + for resp := range e.Websocket.DataHandler { switch v := resp.(type) { case *order.Detail: - switch len(ok.Websocket.DataHandler) { + switch len(e.Websocket.DataHandler) { case 3: assert.Equal(t, "452197707845865472", v.OrderID, "OrderID") assert.Equal(t, "HamsterParty14", v.ClientOrderID, "ClientOrderID") @@ -4016,20 +4016,19 @@ var pushDataMap = map[string]string{ func TestPushData(t *testing.T) { t.Parallel() - var err error - ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(ok), "Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup must not error") for x := range pushDataMap { if x == "Balance And Position" { - ok.API.AuthenticatedSupport = true - ok.API.AuthenticatedWebsocketSupport = true - ok.SetCredentials("test", "test", "test", "", "", "") + e.API.AuthenticatedSupport = true + e.API.AuthenticatedWebsocketSupport = true + e.SetCredentials("test", "test", "test", "", "", "") } else { - ok.API.AuthenticatedSupport = false - ok.API.AuthenticatedWebsocketSupport = false + e.API.AuthenticatedSupport = false + e.API.AuthenticatedWebsocketSupport = false } - err = ok.WsHandleData(t.Context(), []byte(pushDataMap[x])) + err := e.WsHandleData(t.Context(), []byte(pushDataMap[x])) require.NoErrorf(t, err, "Okx %s error %s", x, err) } } @@ -4043,17 +4042,17 @@ func TestPushDataDynamic(t *testing.T) { } var err error for x := range dataMap { - err = ok.WsHandleData(t.Context(), []byte(dataMap[x])) + err = e.WsHandleData(t.Context(), []byte(dataMap[x])) require.NoError(t, err) } } func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := ok.GetHistoricTrades(contextGenerate(), mainPair, asset.Spread, time.Now(), time.Now()) + _, err := e.GetHistoricTrades(contextGenerate(), mainPair, asset.Spread, time.Now(), time.Now()) require.ErrorIs(t, err, asset.ErrNotSupported) - result, err := ok.GetHistoricTrades(contextGenerate(), mainPair, asset.Spot, time.Now().Add(-time.Minute*4), time.Now().Add(-time.Minute*2)) + result, err := e.GetHistoricTrades(contextGenerate(), mainPair, asset.Spot, time.Now().Add(-time.Minute*4), time.Now().Add(-time.Minute*2)) require.NoError(t, err) assert.NotNil(t, result) } @@ -4061,15 +4060,15 @@ func TestGetHistoricTrades(t *testing.T) { func TestWSProcessTrades(t *testing.T) { t.Parallel() - ok := new(Okx) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes - require.NoError(t, testexch.Setup(ok), "Test instance Setup must not error") - assets, err := ok.getAssetsFromInstrumentID(mainPair.String()) + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Test instance Setup must not error") + assets, err := e.getAssetsFromInstrumentID(mainPair.String()) require.NoError(t, err, "getAssetsFromInstrumentID must not error") p := currency.NewPairWithDelimiter("BTC", "USDT", currency.DashDelimiter) for _, a := range assets { - err := ok.Websocket.AddSubscriptions(ok.Websocket.Conn, &subscription.Subscription{ + err := e.Websocket.AddSubscriptions(e.Websocket.Conn, &subscription.Subscription{ Asset: a, Pairs: currency.Pairs{p}, Channel: subscription.AllTradesChannel, @@ -4077,7 +4076,7 @@ func TestWSProcessTrades(t *testing.T) { }) require.NoError(t, err, "AddSubscriptions must not error") } - testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", ok.WsHandleData) + testexch.FixtureToDataHandler(t, "testdata/wsAllTrades.json", e.WsHandleData) exp := []trade.Data{ { @@ -4097,12 +4096,12 @@ func TestWSProcessTrades(t *testing.T) { } total := len(assets) * len(exp) - require.Len(t, ok.Websocket.DataHandler, total, "Must see correct number of trades") + require.Len(t, e.Websocket.DataHandler, total, "Must see correct number of trades") trades := make(map[asset.Item][]trade.Data) - for len(ok.Websocket.DataHandler) > 0 { - resp := <-ok.Websocket.DataHandler + for len(e.Websocket.DataHandler) > 0 { + resp := <-e.Websocket.DataHandler switch v := resp.(type) { case trade.Data: trades[v.AssetType] = append(trades[v.AssetType], v) @@ -4121,7 +4120,7 @@ func TestWSProcessTrades(t *testing.T) { for i, tradeData := range trades[assetType] { expected := exp[i] expected.AssetType = assetType - expected.Exchange = ok.Name + expected.Exchange = e.Name expected.CurrencyPair = p require.Equalf(t, expected, tradeData, "Trade %d (TID: %s) for asset %v must match expected data", i, tradeData.TID, assetType) } @@ -4130,15 +4129,15 @@ func TestWSProcessTrades(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() - result, err := ok.GetServerTime(contextGenerate(), asset.Empty) + result, err := e.GetServerTime(contextGenerate(), asset.Empty) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAvailableTransferChains(contextGenerate(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAvailableTransferChains(contextGenerate(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } @@ -4232,7 +4231,7 @@ func TestInstrument(t *testing.T) { func TestGetLatestFundingRate(t *testing.T) { t.Parallel() - result, err := ok.GetLatestFundingRates(contextGenerate(), &fundingrate.LatestRateRequest{ + result, err := e.GetLatestFundingRates(contextGenerate(), &fundingrate.LatestRateRequest{ Asset: asset.PerpetualSwap, Pair: perpetualSwapPair, IncludePredictedRate: true, @@ -4253,30 +4252,30 @@ func TestGetHistoricalFundingRates(t *testing.T) { } r.StartDate = time.Now().Add(-time.Hour * 24 * 120) - _, err := ok.GetHistoricalFundingRates(contextGenerate(), r) + _, err := e.GetHistoricalFundingRates(contextGenerate(), r) require.ErrorIs(t, err, fundingrate.ErrFundingRateOutsideLimits) - if sharedtestvalues.AreAPICredentialsSet(ok) { + if sharedtestvalues.AreAPICredentialsSet(e) { r.IncludePayments = true } r.StartDate = time.Now().Add(-time.Hour * 24 * 12) - result, err := ok.GetHistoricalFundingRates(contextGenerate(), r) + result, err := e.GetHistoricalFundingRates(contextGenerate(), r) require.NoError(t, err) require.NotNil(t, result) r.RespectHistoryLimits = true - result, err = ok.GetHistoricalFundingRates(contextGenerate(), r) + result, err = e.GetHistoricalFundingRates(contextGenerate(), r) require.NoError(t, err) assert.NotNil(t, result) } func TestIsPerpetualFutureCurrency(t *testing.T) { t.Parallel() - is, err := ok.IsPerpetualFutureCurrency(asset.Binary, mainPair) + is, err := e.IsPerpetualFutureCurrency(asset.Binary, mainPair) require.NoError(t, err) require.False(t, is) - is, err = ok.IsPerpetualFutureCurrency(asset.PerpetualSwap, perpetualSwapPair) + is, err = e.IsPerpetualFutureCurrency(asset.PerpetualSwap, perpetualSwapPair) require.NoError(t, err) assert.True(t, is, "expected true") } @@ -4284,14 +4283,14 @@ func TestIsPerpetualFutureCurrency(t *testing.T) { func TestGetAssetsFromInstrumentTypeOrID(t *testing.T) { t.Parallel() - ok := new(Okx) //nolint:govet // Intentional shadow - require.NoError(t, testexch.Setup(ok), "Setup must not error") + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup must not error") - _, err := ok.getAssetsFromInstrumentID("") + _, err := e.getAssetsFromInstrumentID("") assert.ErrorIs(t, err, errMissingInstrumentID) for _, a := range []asset.Item{asset.Spot, asset.Futures, asset.PerpetualSwap, asset.Options} { - assets, err2 := ok.getAssetsFromInstrumentID(ok.CurrencyPairs.Pairs[a].Enabled[0].String()) + assets, err2 := e.getAssetsFromInstrumentID(e.CurrencyPairs.Pairs[a].Enabled[0].String()) require.NoErrorf(t, err2, "GetAssetsFromInstrumentTypeOrID must not error for asset: %s", a) switch a { case asset.Spot, asset.Margin: @@ -4303,13 +4302,13 @@ func TestGetAssetsFromInstrumentTypeOrID(t *testing.T) { assert.Containsf(t, assets, a, "Should contain asset: %s", a) } - _, err = ok.getAssetsFromInstrumentID("test") + _, err = e.getAssetsFromInstrumentID("test") assert.ErrorIs(t, err, currency.ErrCurrencyNotSupported) - _, err = ok.getAssetsFromInstrumentID("test-test") + _, err = e.getAssetsFromInstrumentID("test-test") assert.ErrorIs(t, err, asset.ErrNotEnabled) for _, a := range []asset.Item{asset.Margin, asset.Spot} { - assets, err2 := ok.getAssetsFromInstrumentID(ok.CurrencyPairs.Pairs[a].Enabled[0].String()) + assets, err2 := e.getAssetsFromInstrumentID(e.CurrencyPairs.Pairs[a].Enabled[0].String()) require.NoErrorf(t, err2, "GetAssetsFromInstrumentTypeOrID must not error for asset: %s", a) assert.Contains(t, assets, a) } @@ -4317,14 +4316,14 @@ func TestGetAssetsFromInstrumentTypeOrID(t *testing.T) { func TestSetMarginType(t *testing.T) { t.Parallel() - err := ok.SetMarginType(contextGenerate(), asset.Spot, mainPair, margin.Isolated) + err := e.SetMarginType(contextGenerate(), asset.Spot, mainPair, margin.Isolated) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestChangePositionMargin(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.ChangePositionMargin(contextGenerate(), &margin.PositionChangeRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ChangePositionMargin(contextGenerate(), &margin.PositionChangeRequest{ Pair: mainPair, Asset: asset.Margin, MarginType: margin.Isolated, @@ -4337,43 +4336,43 @@ func TestChangePositionMargin(t *testing.T) { func TestGetCollateralMode(t *testing.T) { t.Parallel() - _, err := ok.GetCollateralMode(contextGenerate(), asset.USDTMarginedFutures) + _, err := e.GetCollateralMode(contextGenerate(), asset.USDTMarginedFutures) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCollateralMode(contextGenerate(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCollateralMode(contextGenerate(), asset.Spot) assert.NoError(t, err) assert.NotNil(t, result) } func TestSetCollateralMode(t *testing.T) { t.Parallel() - err := ok.SetCollateralMode(contextGenerate(), asset.Spot, collateral.SingleMode) + err := e.SetCollateralMode(contextGenerate(), asset.Spot, collateral.SingleMode) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestGetPositionSummary(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - pp, err := ok.CurrencyPairs.GetPairs(asset.PerpetualSwap, true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + pp, err := e.CurrencyPairs.GetPairs(asset.PerpetualSwap, true) require.NoError(t, err) - result, err := ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ + result, err := e.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ Asset: asset.PerpetualSwap, Pair: pp[0], UnderlyingPair: currency.EMPTYPAIR, }) require.NoError(t, err) require.NotNil(t, result) - pp, err = ok.CurrencyPairs.GetPairs(asset.Futures, true) + pp, err = e.CurrencyPairs.GetPairs(asset.Futures, true) require.NoError(t, err) - _, err = ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ + _, err = e.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ Asset: asset.Spot, Pair: pp[0], UnderlyingPair: mainPair, }) require.ErrorIsf(t, err, futures.ErrNotFuturesAsset, "received '%v', expected '%v'", err, futures.ErrNotFuturesAsset) - result, err = ok.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ + result, err = e.GetFuturesPositionSummary(contextGenerate(), &futures.PositionSummaryRequest{ Asset: asset.Futures, Pair: pp[0], UnderlyingPair: currency.EMPTYPAIR, @@ -4384,17 +4383,17 @@ func TestGetPositionSummary(t *testing.T) { func TestGetFuturesPositions(t *testing.T) { t.Parallel() - pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true) + pp, err := e.CurrencyPairs.GetPairs(asset.Futures, true) require.NoError(t, err) - _, err = ok.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{ + _, err = e.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{ Asset: asset.Spot, Pairs: []currency.Pair{pp[0]}, StartDate: time.Now().Add(time.Hour * 24 * -7), }) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFuturesPositionOrders(contextGenerate(), &futures.PositionsRequest{ Asset: asset.Futures, Pairs: []currency.Pair{pp[0]}, StartDate: time.Now().Add(time.Hour * 24 * -7), @@ -4406,53 +4405,53 @@ func TestGetFuturesPositions(t *testing.T) { func TestGetLeverage(t *testing.T) { t.Parallel() - pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true) + pp, err := e.CurrencyPairs.GetPairs(asset.Futures, true) require.NoError(t, err) - _, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.UnknownSide) + _, err = e.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.UnknownSide) require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, order.UnknownSide) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, order.UnknownSide) require.NoError(t, err) require.NotNil(t, result) - result, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Long) + result, err = e.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Long) require.NoError(t, err) require.NotNil(t, result) - result, err = ok.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Short) + result, err = e.GetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, order.Short) require.NoError(t, err) assert.NotNil(t, result) } func TestSetLeverage(t *testing.T) { t.Parallel() - pp, err := ok.CurrencyPairs.GetPairs(asset.Futures, true) + pp, err := e.CurrencyPairs.GetPairs(asset.Futures, true) require.NoError(t, err) - err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.UnknownSide) + err = e.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.UnknownSide) require.ErrorIs(t, err, order.ErrSideIsInvalid) - err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.CouldNotBuy) + err = e.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.CouldNotBuy) require.ErrorIs(t, err, order.ErrSideIsInvalid) - err = ok.SetLeverage(contextGenerate(), asset.Spot, pp[0], margin.Multi, 5, order.UnknownSide) + err = e.SetLeverage(contextGenerate(), asset.Spot, pp[0], margin.Multi, 5, order.UnknownSide) require.ErrorIs(t, err, asset.ErrNotSupported) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, 5, order.UnknownSide) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + err = e.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Multi, 5, order.UnknownSide) require.NoError(t, err) - err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Long) + err = e.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Long) require.NoError(t, err) - err = ok.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Short) + err = e.SetLeverage(contextGenerate(), asset.Futures, pp[0], margin.Isolated, 5, order.Short) assert.NoError(t, err) } func TestGetFuturesContractDetails(t *testing.T) { t.Parallel() - _, err := ok.GetFuturesContractDetails(contextGenerate(), asset.Spot) + _, err := e.GetFuturesContractDetails(contextGenerate(), asset.Spot) require.ErrorIs(t, err, futures.ErrNotFuturesAsset) - _, err = ok.GetFuturesContractDetails(contextGenerate(), asset.USDTMarginedFutures) + _, err = e.GetFuturesContractDetails(contextGenerate(), asset.USDTMarginedFutures) require.ErrorIs(t, err, asset.ErrNotSupported) for _, a := range []asset.Item{asset.Futures, asset.PerpetualSwap, asset.Spread} { - result, err := ok.GetFuturesContractDetails(contextGenerate(), a) + result, err := e.GetFuturesContractDetails(contextGenerate(), a) require.NoError(t, err) require.NotNil(t, result) } @@ -4461,17 +4460,17 @@ func TestGetFuturesContractDetails(t *testing.T) { func TestWsProcessOrderbook5(t *testing.T) { t.Parallel() ob5payload := []byte(`{"arg":{"channel":"books5","instId":"OKB-USDT"},"data":[{"asks":[["0.0000007465","2290075956","0","4"],["0.0000007466","1747284705","0","4"],["0.0000007467","1338861655","0","3"],["0.0000007468","1661668387","0","6"],["0.0000007469","2715477116","0","5"]],"bids":[["0.0000007464","15693119","0","1"],["0.0000007463","2330835024","0","4"],["0.0000007462","1182926517","0","2"],["0.0000007461","3818684357","0","4"],["0.000000746","6021641435","0","7"]],"instId":"OKB-USDT","ts":"1695864901807","seqId":4826378794}]}`) - err := ok.wsProcessOrderbook5(ob5payload) + err := e.wsProcessOrderbook5(ob5payload) require.NoError(t, err) required := currency.NewPairWithDelimiter("OKB", "USDT", "-") - got, err := orderbook.Get(ok.Name, required, asset.Spot) + got, err := orderbook.Get(e.Name, required, asset.Spot) require.NoError(t, err) require.Len(t, got.Asks, 5) require.Len(t, got.Bids, 5) // Book replicated to margin - got, err = orderbook.Get(ok.Name, required, asset.Margin) + got, err = orderbook.Get(e.Name, required, asset.Margin) require.NoError(t, err) require.Len(t, got.Asks, 5) assert.Len(t, got.Bids, 5) @@ -4479,52 +4478,52 @@ func TestWsProcessOrderbook5(t *testing.T) { func TestGetLeverateEstimatedInfo(t *testing.T) { t.Parallel() - _, err := ok.GetLeverageEstimatedInfo(contextGenerate(), "", "cross", "1", "", mainPair.String(), currency.BTC) + _, err := e.GetLeverageEstimatedInfo(contextGenerate(), "", "cross", "1", "", mainPair.String(), currency.BTC) require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "", "1", "", mainPair.String(), currency.BTC) + _, err = e.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "", "1", "", mainPair.String(), currency.BTC) require.ErrorIs(t, err, margin.ErrMarginTypeUnsupported) - _, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "", "", mainPair.String(), currency.BTC) + _, err = e.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "", "", mainPair.String(), currency.BTC) require.ErrorIs(t, err, errInvalidLeverage) - _, err = ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", mainPair.String(), currency.EMPTYCODE) + _, err = e.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", mainPair.String(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", mainPair.String(), currency.BTC) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeverageEstimatedInfo(contextGenerate(), "MARGIN", "cross", "1", "", mainPair.String(), currency.BTC) require.NoError(t, err) assert.NotNil(t, result) } func TestManualBorrowAndRepayInQuickMarginMode(t *testing.T) { t.Parallel() - _, err := ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{}) + _, err := e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ + _, err = e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ InstrumentID: mainPair.String(), LoanCcy: currency.USDT, Side: "borrow", }) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ + _, err = e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ Amount: 1, InstrumentID: mainPair.String(), Side: "borrow", }) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ + _, err = e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ Amount: 1, InstrumentID: mainPair.String(), LoanCcy: currency.USDT, }) require.ErrorIs(t, err, order.ErrSideIsInvalid) - _, err = ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ + _, err = e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ Amount: 1, LoanCcy: currency.USDT, Side: "borrow", }) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ManualBorrowAndRepayInQuickMarginMode(contextGenerate(), &BorrowAndRepay{ Amount: 1, InstrumentID: mainPair.String(), LoanCcy: currency.USDT, @@ -4536,102 +4535,102 @@ func TestManualBorrowAndRepayInQuickMarginMode(t *testing.T) { func TestGetBorrowAndRepayHistoryInQuickMarginMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetBorrowAndRepayHistoryInQuickMarginMode(contextGenerate(), currency.EMPTYPAIR, currency.BTC, "borrow", "", "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetBorrowAndRepayHistoryInQuickMarginMode(contextGenerate(), currency.EMPTYPAIR, currency.BTC, "borrow", "", "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetVIPInterestAccruedData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetVIPInterestAccruedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetVIPInterestAccruedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetVIPInterestDeductedData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetVIPInterestDeductedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetVIPInterestDeductedData(contextGenerate(), currency.ETH, "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetVIPLoanOrderList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetVIPLoanOrderList(contextGenerate(), "", "1", currency.BTC, time.Time{}, time.Now(), 20) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetVIPLoanOrderList(contextGenerate(), "", "1", currency.BTC, time.Time{}, time.Now(), 20) require.NoError(t, err) assert.NotNil(t, result) } func TestGetVIPLoanOrderDetail(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetVIPLoanOrderDetail(contextGenerate(), "123456", currency.BTC, time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetVIPLoanOrderDetail(contextGenerate(), "123456", currency.BTC, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestSetRiskOffsetType(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetRiskOffsetType(contextGenerate(), "3") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetRiskOffsetType(contextGenerate(), "3") require.NoError(t, err) assert.NotNil(t, result) } func TestActivateOption(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.ActivateOption(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.ActivateOption(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestSetAutoLoan(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.SetAutoLoan(contextGenerate(), true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.SetAutoLoan(contextGenerate(), true) require.NoError(t, err) assert.NotNil(t, result) } func TestSetAccountMode(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetAccountMode(contextGenerate(), "1") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetAccountMode(contextGenerate(), "1") require.NoError(t, err) assert.NotNil(t, result) } func TestResetMMPStatus(t *testing.T) { t.Parallel() - _, err := ok.ResetMMPStatus(contextGenerate(), instTypeOption, "") + _, err := e.ResetMMPStatus(contextGenerate(), instTypeOption, "") require.ErrorIs(t, err, errInstrumentFamilyRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ResetMMPStatus(contextGenerate(), instTypeOption, "BTC-USD") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ResetMMPStatus(contextGenerate(), instTypeOption, "BTC-USD") require.NoError(t, err) assert.NotNil(t, result) } func TestSetMMP(t *testing.T) { t.Parallel() - _, err := ok.SetMMP(contextGenerate(), &MMPConfig{}) + _, err := e.SetMMP(contextGenerate(), &MMPConfig{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetMMP(contextGenerate(), &MMPConfig{ + _, err = e.SetMMP(contextGenerate(), &MMPConfig{ TimeInterval: 5000, }) require.ErrorIs(t, err, errInstrumentFamilyRequired) - _, err = ok.SetMMP(contextGenerate(), &MMPConfig{ + _, err = e.SetMMP(contextGenerate(), &MMPConfig{ InstrumentFamily: "BTC-USD", }) require.ErrorIs(t, err, errInvalidQuantityLimit) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetMMP(contextGenerate(), &MMPConfig{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetMMP(contextGenerate(), &MMPConfig{ InstrumentFamily: "BTC-USD", TimeInterval: 5000, FrozenInterval: 2000, @@ -4643,75 +4642,75 @@ func TestSetMMP(t *testing.T) { func TestGetMMPConfig(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMMPConfig(contextGenerate(), "BTC-USD") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMMPConfig(contextGenerate(), "BTC-USD") require.NoError(t, err) assert.NotNil(t, result) } func TestMassCancelOrder(t *testing.T) { t.Parallel() - _, err := ok.CancelAllMMPOrders(contextGenerate(), "", "BTC-USD", 2000) + _, err := e.CancelAllMMPOrders(contextGenerate(), "", "BTC-USD", 2000) require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "", 2000) + _, err = e.CancelAllMMPOrders(contextGenerate(), "OPTION", "", 2000) require.ErrorIs(t, err, errInstrumentFamilyRequired) - _, err = ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", -1) + _, err = e.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", -1) require.ErrorIs(t, err, errMissingIntervalValue) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", 2000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllMMPOrders(contextGenerate(), "OPTION", "BTC-USD", 2000) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllDelayed(t *testing.T) { t.Parallel() - _, err := ok.CancelAllDelayed(contextGenerate(), 2, "") + _, err := e.CancelAllDelayed(contextGenerate(), 2, "") require.ErrorIs(t, err, errCountdownTimeoutRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllDelayed(contextGenerate(), 60, "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllDelayed(contextGenerate(), 60, "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetTradeAccountRateLimit(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetTradeAccountRateLimit(contextGenerate()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTradeAccountRateLimit(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestPreCheckOrder(t *testing.T) { t.Parallel() - _, err := ok.PreCheckOrder(contextGenerate(), nil) + _, err := e.PreCheckOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) arg := &OrderPreCheckParams{ ClientOrderID: "b15", } - _, err = ok.PreCheckOrder(contextGenerate(), arg) + _, err = e.PreCheckOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.PreCheckOrder(contextGenerate(), arg) + _, err = e.PreCheckOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) arg.TradeMode = "cash" - _, err = ok.PreCheckOrder(contextGenerate(), arg) + _, err = e.PreCheckOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "buy" - _, err = ok.PreCheckOrder(contextGenerate(), arg) + _, err = e.PreCheckOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = "limit" - _, err = ok.PreCheckOrder(contextGenerate(), arg) + _, err = e.PreCheckOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PreCheckOrder(contextGenerate(), &OrderPreCheckParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PreCheckOrder(contextGenerate(), &OrderPreCheckParams{ InstrumentID: mainPair.String(), TradeMode: "cash", ClientOrderID: "b15", @@ -4726,19 +4725,19 @@ func TestPreCheckOrder(t *testing.T) { func TestAmendAlgoOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendAlgoOrder(contextGenerate(), nil) + _, err := e.AmendAlgoOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{NewSize: 2}) + _, err = e.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{NewSize: 2}) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{ + _, err = e.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{ InstrumentID: perpetualSwapPair.String(), NewSize: 2, }) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendAlgoOrder(contextGenerate(), &AmendAlgoOrderParam{ AlgoID: "2510789768709120", InstrumentID: perpetualSwapPair.String(), NewSize: 2, @@ -4749,28 +4748,28 @@ func TestAmendAlgoOrder(t *testing.T) { func TestGetAlgoOrderDetail(t *testing.T) { t.Parallel() - _, err := ok.GetAlgoOrderDetail(contextGenerate(), "", "") + _, err := e.GetAlgoOrderDetail(contextGenerate(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAlgoOrderDetail(contextGenerate(), "1234231231423", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAlgoOrderDetail(contextGenerate(), "1234231231423", "") require.NoError(t, err) assert.NotNil(t, result) } func TestClosePositionForContractID(t *testing.T) { t.Parallel() - _, err := ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{}) + _, err := e.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "", MarketCloseAllPositions: true}) + _, err = e.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "", MarketCloseAllPositions: true}) require.ErrorIs(t, err, errAlgoIDRequired) - _, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false}) + _, err = e.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false}) require.ErrorIs(t, err, order.ErrAmountMustBeSet) - _, err = ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false, Size: 123}) + _, err = e.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{AlgoID: "448965992920907776", MarketCloseAllPositions: false, Size: 123}) require.ErrorIs(t, err, order.ErrPriceBelowMin) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.ClosePositionForContractID(contextGenerate(), &ClosePositionParams{ AlgoID: "448965992920907776", MarketCloseAllPositions: true, }) @@ -4780,15 +4779,15 @@ func TestClosePositionForContractID(t *testing.T) { func TestCancelClosePositionOrderForContractGrid(t *testing.T) { t.Parallel() - _, err := ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{}) + _, err := e.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{OrderID: "570627699870375936"}) + _, err = e.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{OrderID: "570627699870375936"}) require.ErrorIs(t, err, errAlgoIDRequired) - _, err = ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{AlgoID: "448965992920907776"}) + _, err = e.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{AlgoID: "448965992920907776"}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelClosePositionOrderForContractGrid(contextGenerate(), &CancelClosePositionOrder{ AlgoID: "448965992920907776", OrderID: "570627699870375936", }) @@ -4798,8 +4797,8 @@ func TestCancelClosePositionOrderForContractGrid(t *testing.T) { func TestInstantTriggerGridAlgoOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.InstantTriggerGridAlgoOrder(contextGenerate(), "123456789") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.InstantTriggerGridAlgoOrder(contextGenerate(), "123456789") require.NoError(t, err) assert.NotNil(t, result) } @@ -4809,47 +4808,47 @@ func TestComputeMinInvestment(t *testing.T) { arg := &ComputeInvestmentDataParam{ RunType: "1", } - _, err := ok.ComputeMinInvestment(contextGenerate(), arg) + _, err := e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.InstrumentID = mainPair.String() - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidAlgoOrderType) arg.AlgoOrderType = "grid" - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.MaxPrice = 5000 - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.MinPrice = 5000 - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidGridQuantity) arg.GridNumber = 1234 arg.RunType = "" - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errRunTypeRequired) arg.RunType = "1" arg.AlgoOrderType = "contract_grid" - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errMissingRequiredArgumentDirection) arg.Direction = positionSideLong - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidLeverage) arg.Leverage = 5 arg.InvestmentData = []InvestmentData{{Currency: currency.ETH}} - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.InvestmentData = []InvestmentData{{Amount: 0.01}} - _, err = ok.ComputeMinInvestment(contextGenerate(), arg) + _, err = e.ComputeMinInvestment(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - result, err := ok.ComputeMinInvestment(contextGenerate(), &ComputeInvestmentDataParam{ + result, err := e.ComputeMinInvestment(contextGenerate(), &ComputeInvestmentDataParam{ InstrumentID: mainPair.String(), AlgoOrderType: "grid", GridNumber: 50, @@ -4873,99 +4872,99 @@ func TestComputeMinInvestment(t *testing.T) { func TestRSIBackTesting(t *testing.T) { t.Parallel() - _, err := ok.RSIBackTesting(contextGenerate(), "", "", "", 50, 14, kline.FiveMin) + _, err := e.RSIBackTesting(contextGenerate(), "", "", "", 50, 14, kline.FiveMin) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.RSIBackTesting(contextGenerate(), mainPair.String(), "", "", 50, 14, kline.FiveMin) + result, err := e.RSIBackTesting(contextGenerate(), mainPair.String(), "", "", 50, 14, kline.FiveMin) require.NoError(t, err) assert.NotNil(t, result) } func TestSignalBotTrading(t *testing.T) { t.Parallel() - _, err := ok.GetSignalBotOrderDetail(contextGenerate(), "", "623833708424069120") + _, err := e.GetSignalBotOrderDetail(contextGenerate(), "", "623833708424069120") require.ErrorIs(t, err, errInvalidAlgoOrderType) - _, err = ok.GetSignalBotOrderDetail(contextGenerate(), "contract", "") + _, err = e.GetSignalBotOrderDetail(contextGenerate(), "contract", "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.GetSignalBotOrderDetail(contextGenerate(), "contract", "623833708424069120") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.GetSignalBotOrderDetail(contextGenerate(), "contract", "623833708424069120") require.NoError(t, err) assert.NotNil(t, result) } func TestGetSignalOrderPositions(t *testing.T) { t.Parallel() - _, err := ok.GetSignalOrderPositions(contextGenerate(), "", "623833708424069120") + _, err := e.GetSignalOrderPositions(contextGenerate(), "", "623833708424069120") require.ErrorIs(t, err, errInvalidAlgoOrderType) - _, err = ok.GetSignalOrderPositions(contextGenerate(), "contract", "") + _, err = e.GetSignalOrderPositions(contextGenerate(), "contract", "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSignalOrderPositions(contextGenerate(), "contract", "623833708424069120") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSignalOrderPositions(contextGenerate(), "contract", "623833708424069120") require.NoError(t, err) assert.NotNil(t, result) } func TestGetSignalBotSubOrders(t *testing.T) { t.Parallel() - _, err := ok.GetSignalBotSubOrders(contextGenerate(), "", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0) + _, err := e.GetSignalBotSubOrders(contextGenerate(), "", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errAlgoIDRequired) - _, err = ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "", "filled", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "", "filled", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, errInvalidAlgoOrderType) - _, err = ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "", "", "", "", time.Time{}, time.Time{}, 0) + _, err = e.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "", "", "", "", time.Time{}, time.Time{}, 0) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSignalBotSubOrders(contextGenerate(), "623833708424069120", "contract", "filled", "", "", "", time.Time{}, time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSignalBotEventHistory(t *testing.T) { t.Parallel() - _, err := ok.GetSignalBotEventHistory(contextGenerate(), "", time.Time{}, time.Now(), 50) + _, err := e.GetSignalBotEventHistory(contextGenerate(), "", time.Time{}, time.Now(), 50) require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSignalBotEventHistory(contextGenerate(), "12345", time.Time{}, time.Now(), 50) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSignalBotEventHistory(contextGenerate(), "12345", time.Time{}, time.Now(), 50) require.NoError(t, err) assert.NotNil(t, result) } func TestPlaceRecurringBuyOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceRecurringBuyOrder(contextGenerate(), nil) + _, err := e.PlaceRecurringBuyOrder(contextGenerate(), nil) require.ErrorIs(t, err, common.ErrNilPointer) arg := &PlaceRecurringBuyOrderParam{ TimeZone: "3", } - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, errStrategyNameRequired) arg.StrategyName = "BTC|ETH recurring buy monthly" - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, common.ErrEmptyParams) arg.RecurringList = []RecurringListItem{{}} - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.RecurringList = []RecurringListItem{{Currency: currency.BTC}} - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, errRecurringDayRequired) arg.RecurringDay = "1" arg.RecurringTime = -10 - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, errRecurringBuyTimeRequired) arg.RecurringTime = 2 - _, err = ok.PlaceRecurringBuyOrder(contextGenerate(), arg) + _, err = e.PlaceRecurringBuyOrder(contextGenerate(), arg) require.ErrorIs(t, err, errInvalidTradeModeValue) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceRecurringBuyOrder(contextGenerate(), &PlaceRecurringBuyOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceRecurringBuyOrder(contextGenerate(), &PlaceRecurringBuyOrderParam{ StrategyName: "BTC|ETH recurring buy monthly", Amount: 100, RecurringList: []RecurringListItem{ @@ -4991,15 +4990,15 @@ func TestPlaceRecurringBuyOrder(t *testing.T) { func TestAmendRecurringBuyOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{}) + _, err := e.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{StrategyName: "stg1"}) + _, err = e.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{StrategyName: "stg1"}) require.ErrorIs(t, err, errAlgoIDRequired) - _, err = ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{AlgoID: "448965992920907776"}) + _, err = e.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{AlgoID: "448965992920907776"}) require.ErrorIs(t, err, errStrategyNameRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendRecurringBuyOrder(contextGenerate(), &AmendRecurringOrderParam{ AlgoID: "448965992920907776", StrategyName: "stg1", }) @@ -5009,67 +5008,67 @@ func TestAmendRecurringBuyOrder(t *testing.T) { func TestStopRecurringBuyOrder(t *testing.T) { t.Parallel() - _, err := ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{}) + _, err := e.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{}}) + _, err = e.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{}}) require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{AlgoID: "1232323434234"}}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.StopRecurringBuyOrder(contextGenerate(), []StopRecurringBuyOrder{{AlgoID: "1232323434234"}}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetRecurringBuyOrderList(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRecurringBuyOrderList(contextGenerate(), "", "paused", time.Time{}, time.Time{}, 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecurringBuyOrderList(contextGenerate(), "", "paused", time.Time{}, time.Time{}, 30) require.NoError(t, err) assert.NotNil(t, result) } func TestGetRecurringBuyOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRecurringBuyOrderHistory(contextGenerate(), "", time.Time{}, time.Time{}, 30) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecurringBuyOrderHistory(contextGenerate(), "", time.Time{}, time.Time{}, 30) require.NoError(t, err) assert.NotNil(t, result) } func TestGetRecurringOrderDetails(t *testing.T) { t.Parallel() - _, err := ok.GetRecurringOrderDetails(contextGenerate(), "", "") + _, err := e.GetRecurringOrderDetails(contextGenerate(), "", "") require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRecurringOrderDetails(contextGenerate(), "560473220642766848", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecurringOrderDetails(contextGenerate(), "560473220642766848", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetRecurringSubOrders(t *testing.T) { t.Parallel() - _, err := ok.GetRecurringSubOrders(contextGenerate(), "", "123422", time.Time{}, time.Now(), 0) + _, err := e.GetRecurringSubOrders(contextGenerate(), "", "123422", time.Time{}, time.Now(), 0) require.ErrorIs(t, err, errAlgoIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetRecurringSubOrders(contextGenerate(), "560473220642766848", "123422", time.Time{}, time.Now(), 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetRecurringSubOrders(contextGenerate(), "560473220642766848", "123422", time.Time{}, time.Now(), 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetExistingLeadingPositions(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetExistingLeadingPositions(contextGenerate(), instTypeSpot, mainPair.String(), time.Now(), time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetExistingLeadingPositions(contextGenerate(), instTypeSpot, mainPair.String(), time.Now(), time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLeadingPositionsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLeadingPositionsHistory(contextGenerate(), "OPTION", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeadingPositionsHistory(contextGenerate(), "OPTION", "", time.Time{}, time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } @@ -5077,15 +5076,15 @@ func TestGetLeadingPositionsHistory(t *testing.T) { func TestPlaceLeadingStopOrder(t *testing.T) { t.Parallel() arg := &TPSLOrderParam{} - _, err := ok.PlaceLeadingStopOrder(contextGenerate(), arg) + _, err := e.PlaceLeadingStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, common.ErrEmptyParams) arg.Tag = "1235454" - _, err = ok.PlaceLeadingStopOrder(contextGenerate(), arg) + _, err = e.PlaceLeadingStopOrder(contextGenerate(), arg) require.ErrorIs(t, err, errSubPositionIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceLeadingStopOrder(contextGenerate(), &TPSLOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceLeadingStopOrder(contextGenerate(), &TPSLOrderParam{ SubPositionID: "1235454", TakeProfitTriggerPrice: 123455, }) @@ -5095,13 +5094,13 @@ func TestPlaceLeadingStopOrder(t *testing.T) { func TestCloseLeadingPosition(t *testing.T) { t.Parallel() - _, err := ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{}) + _, err := e.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{Tag: "tag-here"}) + _, err = e.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{Tag: "tag-here"}) require.ErrorIs(t, err, errSubPositionIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CloseLeadingPosition(contextGenerate(), &CloseLeadingPositionParam{ SubPositionID: "518541406042591232", }) require.NoError(t, err) @@ -5110,54 +5109,54 @@ func TestCloseLeadingPosition(t *testing.T) { func TestGetLeadingInstrument(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLeadingInstrument(contextGenerate(), "SWAP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLeadingInstrument(contextGenerate(), "SWAP") require.NoError(t, err) assert.NotNil(t, result) } func TestAmendLeadingInstruments(t *testing.T) { t.Parallel() - _, err := ok.AmendLeadingInstruments(contextGenerate(), "", "") + _, err := e.AmendLeadingInstruments(contextGenerate(), "", "") require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendLeadingInstruments(contextGenerate(), perpetualSwapPair.String(), "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendLeadingInstruments(contextGenerate(), perpetualSwapPair.String(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetProfitSharingDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetProfitSharingDetails(contextGenerate(), "", time.Now(), time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetProfitSharingDetails(contextGenerate(), "", time.Now(), time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTotalProfitSharing(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetTotalProfitSharing(contextGenerate(), "SWAP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetTotalProfitSharing(contextGenerate(), "SWAP") require.NoError(t, err) assert.NotNil(t, result) } func TestGetUnrealizedProfitSharingDetails(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetUnrealizedProfitSharingDetails(contextGenerate(), "SWAP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUnrealizedProfitSharingDetails(contextGenerate(), "SWAP") require.NoError(t, err) assert.NotNil(t, result) } func TestSetFirstCopySettings(t *testing.T) { t.Parallel() - _, err := ok.AmendCopySettings(contextGenerate(), &FirstCopySettings{}) + _, err := e.AmendCopySettings(contextGenerate(), &FirstCopySettings{}) require.ErrorIs(t, err, common.ErrEmptyParams) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendCopySettings(contextGenerate(), &FirstCopySettings{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendCopySettings(contextGenerate(), &FirstCopySettings{ InstrumentType: "SWAP", UniqueCode: "25CD5A80241D6FE6", CopyMarginMode: "cross", @@ -5173,29 +5172,29 @@ func TestSetFirstCopySettings(t *testing.T) { func TestAmendCopySettings(t *testing.T) { t.Parallel() - _, err := ok.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{}) + _, err := e.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &FirstCopySettings{ CopyMode: "ratio_copy", } - _, err = ok.SetFirstCopySettings(contextGenerate(), arg) + _, err = e.SetFirstCopySettings(contextGenerate(), arg) require.ErrorIs(t, err, errUniqueCodeRequired) arg.UniqueCode = "25CD5A80241D6FE6" - _, err = ok.SetFirstCopySettings(contextGenerate(), arg) + _, err = e.SetFirstCopySettings(contextGenerate(), arg) require.ErrorIs(t, err, errCopyInstrumentIDTypeRequired) arg.CopyInstrumentIDType = "copy" - _, err = ok.SetFirstCopySettings(contextGenerate(), arg) + _, err = e.SetFirstCopySettings(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.CopyTotalAmount = 500 - _, err = ok.SetFirstCopySettings(contextGenerate(), arg) + _, err = e.SetFirstCopySettings(contextGenerate(), arg) require.ErrorIs(t, err, errSubPositionCloseTypeRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.SetFirstCopySettings(contextGenerate(), &FirstCopySettings{ InstrumentType: "SWAP", UniqueCode: "25CD5A80241D6FE6", CopyMarginMode: "cross", @@ -5211,22 +5210,22 @@ func TestAmendCopySettings(t *testing.T) { func TestStopCopying(t *testing.T) { t.Parallel() - _, err := ok.StopCopying(contextGenerate(), &StopCopyingParameter{}) + _, err := e.StopCopying(contextGenerate(), &StopCopyingParameter{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.StopCopying(contextGenerate(), &StopCopyingParameter{ + _, err = e.StopCopying(contextGenerate(), &StopCopyingParameter{ InstrumentType: "SWAP", SubPositionCloseType: "manual_close", }) require.ErrorIs(t, err, errUniqueCodeRequired) - _, err = ok.StopCopying(contextGenerate(), &StopCopyingParameter{ + _, err = e.StopCopying(contextGenerate(), &StopCopyingParameter{ InstrumentType: "SWAP", UniqueCode: "25CD5A80241D6FE6", }) require.ErrorIs(t, err, errSubPositionCloseTypeRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.StopCopying(contextGenerate(), &StopCopyingParameter{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.StopCopying(contextGenerate(), &StopCopyingParameter{ InstrumentType: "SWAP", UniqueCode: "25CD5A80241D6FE6", SubPositionCloseType: "manual_close", @@ -5237,44 +5236,44 @@ func TestStopCopying(t *testing.T) { func TestGetCopySettings(t *testing.T) { t.Parallel() - _, err := ok.GetCopySettings(contextGenerate(), "SWAP", "") + _, err := e.GetCopySettings(contextGenerate(), "SWAP", "") require.ErrorIs(t, err, errUniqueCodeRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCopySettings(contextGenerate(), "SWAP", "213E8C92DC61EFAC") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCopySettings(contextGenerate(), "SWAP", "213E8C92DC61EFAC") require.NoError(t, err) assert.NotNil(t, result) } func TestGetMultipleLeverages(t *testing.T) { t.Parallel() - _, err := ok.GetMultipleLeverages(contextGenerate(), "", "213E8C92DC61EFAC", "") + _, err := e.GetMultipleLeverages(contextGenerate(), "", "213E8C92DC61EFAC", "") require.ErrorIs(t, err, margin.ErrInvalidMarginType) - _, err = ok.GetMultipleLeverages(contextGenerate(), "isolated", "", "") + _, err = e.GetMultipleLeverages(contextGenerate(), "isolated", "", "") require.ErrorIs(t, err, errUniqueCodeRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMultipleLeverages(contextGenerate(), "isolated", "213E8C92DC61EFAC", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMultipleLeverages(contextGenerate(), "isolated", "213E8C92DC61EFAC", "") require.NoError(t, err) assert.NotNil(t, result) } func TestSetMultipleLeverages(t *testing.T) { t.Parallel() - _, err := ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{}) + _, err := e.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{Leverage: 5}) + _, err = e.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{Leverage: 5}) require.ErrorIs(t, err, margin.ErrInvalidMarginType) - _, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{MarginMode: "cross"}) + _, err = e.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{MarginMode: "cross"}) require.ErrorIs(t, err, errInvalidLeverage) - _, err = ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{ + _, err = e.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{ MarginMode: "cross", Leverage: 5, }) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.SetMultipleLeverages(contextGenerate(), &SetLeveragesParam{ MarginMode: "cross", Leverage: 5, InstrumentID: mainPair.String(), @@ -5285,119 +5284,119 @@ func TestSetMultipleLeverages(t *testing.T) { func TestGetMyLeadTraders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetMyLeadTraders(contextGenerate(), "SWAP") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetMyLeadTraders(contextGenerate(), "SWAP") require.NoError(t, err) assert.NotNil(t, result) } func TestGetHistoryLeadTraders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetHistoryLeadTraders(contextGenerate(), "", "", "", 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetHistoryLeadTraders(contextGenerate(), "", "", "", 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetWeeklyTraderProfitAndLoss(t *testing.T) { t.Parallel() - _, err := ok.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", "") + _, err := e.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", "") require.ErrorIs(t, err, errUniqueCodeRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - mainResult, err := ok.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", leadTraderUniqueID) + mainResult, err := e.GetWeeklyTraderProfitAndLoss(contextGenerate(), "", leadTraderUniqueID) require.NoError(t, err) assert.NotNil(t, mainResult) } func TestGetDailyLeadTraderPNL(t *testing.T) { t.Parallel() - _, err := ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", "", "2") + _, err := e.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", "", "2") require.ErrorIs(t, err, errUniqueCodeRequired) - _, err = ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", "WOOF", "") + _, err = e.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", "WOOF", "") require.ErrorIs(t, err, errLastDaysRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - mainResult, err := ok.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", leadTraderUniqueID, "2") + mainResult, err := e.GetDailyLeadTraderPNL(contextGenerate(), "SWAP", leadTraderUniqueID, "2") require.NoError(t, err) assert.NotNil(t, mainResult) } func TestGetLeadTraderStats(t *testing.T) { t.Parallel() - _, err := ok.GetLeadTraderStats(contextGenerate(), "SWAP", "", "2") + _, err := e.GetLeadTraderStats(contextGenerate(), "SWAP", "", "2") require.ErrorIs(t, err, errUniqueCodeRequired) - _, err = ok.GetLeadTraderStats(contextGenerate(), "SWAP", "RAWR", "") + _, err = e.GetLeadTraderStats(contextGenerate(), "SWAP", "RAWR", "") require.ErrorIs(t, err, errLastDaysRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - result, err := ok.GetLeadTraderStats(contextGenerate(), "SWAP", leadTraderUniqueID, "2") + result, err := e.GetLeadTraderStats(contextGenerate(), "SWAP", leadTraderUniqueID, "2") require.NoError(t, err) assert.NotNil(t, result) } func TestGetLeadTraderCurrencyPreferences(t *testing.T) { t.Parallel() - _, err := ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", "", "2") + _, err := e.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", "", "2") require.ErrorIs(t, err, errUniqueCodeRequired) - _, err = ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", "MEOW", "") + _, err = e.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", "MEOW", "") require.ErrorIs(t, err, errLastDaysRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - result, err := ok.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", leadTraderUniqueID, "2") + result, err := e.GetLeadTraderCurrencyPreferences(contextGenerate(), "SWAP", leadTraderUniqueID, "2") require.NoError(t, err) assert.NotNil(t, result) } func TestGetLeadTraderCurrentLeadPositions(t *testing.T) { t.Parallel() - _, err := ok.GetLeadTraderCurrentLeadPositions(contextGenerate(), instTypeSwap, "", "", "", 10) + _, err := e.GetLeadTraderCurrentLeadPositions(contextGenerate(), instTypeSwap, "", "", "", 10) require.ErrorIs(t, err, errUniqueCodeRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - _, err = ok.GetLeadTraderCurrentLeadPositions(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10) + _, err = e.GetLeadTraderCurrentLeadPositions(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10) require.NoError(t, err) // No test validation of positions performed as the lead trader may not have any positions open } func TestGetLeadTraderLeadPositionHistory(t *testing.T) { t.Parallel() - _, err := ok.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", "", "", "", 10) + _, err := e.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", "", "", "", 10) require.ErrorIs(t, err, errUniqueCodeRequired) require.NoError(t, syncLeadTraderUniqueID(t), "syncLeadTraderUniqueID must not error") - result, err := ok.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10) + result, err := e.GetLeadTraderLeadPositionHistory(contextGenerate(), "SWAP", leadTraderUniqueID, "", "", 10) require.NoError(t, err) assert.NotNil(t, result) } func TestPlaceSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{}) + _, err := e.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &SpreadOrderParam{Tag: "tag-here"} - _, err = ok.PlaceSpreadOrder(contextGenerate(), arg) + _, err = e.PlaceSpreadOrder(contextGenerate(), arg) require.ErrorIs(t, err, errMissingInstrumentID) arg.SpreadID = spreadPair.String() - _, err = ok.PlaceSpreadOrder(contextGenerate(), arg) + _, err = e.PlaceSpreadOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = "limit" - _, err = ok.PlaceSpreadOrder(contextGenerate(), arg) + _, err = e.PlaceSpreadOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Size = 1 - _, err = ok.PlaceSpreadOrder(contextGenerate(), arg) + _, err = e.PlaceSpreadOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrPriceBelowMin) arg.Price = 12345 - _, err = ok.PlaceSpreadOrder(contextGenerate(), arg) + _, err = e.PlaceSpreadOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceSpreadOrder(contextGenerate(), &SpreadOrderParam{ InstrumentID: spreadPair.String(), SpreadID: "1234", ClientOrderID: "12354123523", @@ -5412,34 +5411,34 @@ func TestPlaceSpreadOrder(t *testing.T) { func TestCancelSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.CancelSpreadOrder(contextGenerate(), "", "") + _, err := e.CancelSpreadOrder(contextGenerate(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelSpreadOrder(request.WithVerbose(contextGenerate()), "12345", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelSpreadOrder(request.WithVerbose(contextGenerate()), "12345", "") require.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllSpreadOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllSpreadOrders(contextGenerate(), "123456") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllSpreadOrders(contextGenerate(), "123456") require.NoError(t, err) assert.NotNil(t, result) } func TestAmendSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{}) + _, err := e.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) - _, err = ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{NewSize: 2}) + _, err = e.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{NewSize: 2}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{OrderID: "2510789768709120"}) + _, err = e.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{OrderID: "2510789768709120"}) require.ErrorIs(t, err, errSizeOrPriceIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendSpreadOrder(contextGenerate(), &AmendSpreadOrderParam{ OrderID: "2510789768709120", NewSize: 2, }) @@ -5449,99 +5448,99 @@ func TestAmendSpreadOrder(t *testing.T) { func TestGetSpreadOrderDetails(t *testing.T) { t.Parallel() - _, err := ok.GetSpreadOrderDetails(contextGenerate(), "", "") + _, err := e.GetSpreadOrderDetails(contextGenerate(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSpreadOrderDetails(contextGenerate(), "1234567", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSpreadOrderDetails(contextGenerate(), "1234567", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetActiveSpreadOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetActiveSpreadOrders(contextGenerate(), "", "post_only", "partially_filled", "", "", 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetActiveSpreadOrders(contextGenerate(), "", "post_only", "partially_filled", "", "", 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetCompletedSpreadOrdersLast7Days(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetCompletedSpreadOrdersLast7Days(contextGenerate(), "", "limit", "canceled", "", "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetCompletedSpreadOrdersLast7Days(contextGenerate(), "", "limit", "canceled", "", "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSpreadTradesOfLast7Days(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetSpreadTradesOfLast7Days(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetSpreadTradesOfLast7Days(contextGenerate(), "", "", "", "", "", time.Time{}, time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSpreads(t *testing.T) { t.Parallel() - result, err := ok.GetPublicSpreads(contextGenerate(), "", "", "", "") + result, err := e.GetPublicSpreads(contextGenerate(), "", "", "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetSpreadOrderBooks(t *testing.T) { t.Parallel() - _, err := ok.GetPublicSpreadOrderBooks(contextGenerate(), "", 0) + _, err := e.GetPublicSpreadOrderBooks(contextGenerate(), "", 0) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetPublicSpreadOrderBooks(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP", 0) + result, err := e.GetPublicSpreadOrderBooks(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP", 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetSpreadTickers(t *testing.T) { t.Parallel() - _, err := ok.GetPublicSpreadTickers(contextGenerate(), "") + _, err := e.GetPublicSpreadTickers(contextGenerate(), "") require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetPublicSpreadTickers(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP") + result, err := e.GetPublicSpreadTickers(contextGenerate(), "BTC-USDT_BTC-USDT-SWAP") require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicSpreadTrades(t *testing.T) { t.Parallel() - result, err := ok.GetPublicSpreadTrades(contextGenerate(), "") + result, err := e.GetPublicSpreadTrades(contextGenerate(), "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetSpreadCandlesticks(t *testing.T) { t.Parallel() - _, err := ok.GetSpreadCandlesticks(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetSpreadCandlesticks(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetSpreadCandlesticks(contextGenerate(), spreadPair.String(), kline.FiveMin, time.Now().AddDate(0, 0, -1), time.Now(), 10) + result, err := e.GetSpreadCandlesticks(contextGenerate(), spreadPair.String(), kline.FiveMin, time.Now().AddDate(0, 0, -1), time.Now(), 10) require.NoError(t, err, "GetSpreadCandlesticks must not error") assert.NotEmpty(t, result, "GetSpreadCandlesticks should not return an empty result") } func TestGetSpreadCandlesticksHistory(t *testing.T) { t.Parallel() - _, err := ok.GetSpreadCandlesticksHistory(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetSpreadCandlesticksHistory(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetSpreadCandlesticksHistory(contextGenerate(), spreadPair.String(), kline.FiveMin, time.Now().AddDate(0, 0, -1), time.Now(), 10) + result, err := e.GetSpreadCandlesticksHistory(contextGenerate(), spreadPair.String(), kline.FiveMin, time.Now().AddDate(0, 0, -1), time.Now(), 10) require.NoError(t, err, "GetSpreadCandlesticksHistory must not error") assert.NotEmpty(t, result, "GetSpreadCandlesticksHistory should not return an empty result") } func TestGetOptionsTickBands(t *testing.T) { t.Parallel() - _, err := ok.GetOptionsTickBands(contextGenerate(), "", "") + _, err := e.GetOptionsTickBands(contextGenerate(), "", "") require.ErrorIs(t, err, errInvalidInstrumentType) - result, err := ok.GetOptionsTickBands(contextGenerate(), "OPTION", "") + result, err := e.GetOptionsTickBands(contextGenerate(), "OPTION", "") require.NoError(t, err) assert.NotNil(t, result) } @@ -5559,71 +5558,71 @@ func TestExtractIndexCandlestick(t *testing.T) { func TestGetHistoricIndexAndMarkPriceCandlesticks(t *testing.T) { t.Parallel() - _, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.FiveMin, 10) + _, err := e.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.FiveMin, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "BTC-USD", time.Time{}, time.Time{}, kline.FiveMin, 10) + result, err := e.GetHistoricIndexCandlesticksHistory(contextGenerate(), "BTC-USD", time.Time{}, time.Time{}, kline.FiveMin, 10) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.GetMarkPriceCandlestickHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, kline.FiveMin, 10) + result, err = e.GetMarkPriceCandlestickHistory(contextGenerate(), perpetualSwapPair.String(), time.Time{}, time.Time{}, kline.FiveMin, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetEconomicCanendarData(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetEconomicCalendarData(contextGenerate(), "", "", time.Now(), time.Time{}, 0) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetEconomicCalendarData(contextGenerate(), "", "", time.Now(), time.Time{}, 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetDepositWithdrawalStatus(t *testing.T) { t.Parallel() - _, err := ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "", "", "") + _, err := e.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "", "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "1244", "", "") + _, err = e.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "", "1244", "", "") require.ErrorIs(t, err, errMissingValidWithdrawalID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "1244", "", "", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositWithdrawalStatus(contextGenerate(), currency.EMPTYCODE, "1244", "", "", "") require.NoError(t, err) assert.NotNil(t, result) } func TestGetPublicExchangeList(t *testing.T) { t.Parallel() - result, err := ok.GetPublicExchangeList(contextGenerate()) + result, err := e.GetPublicExchangeList(contextGenerate()) require.NoError(t, err) assert.NotNil(t, result) } func TestGetInviteesDetail(t *testing.T) { t.Parallel() - _, err := ok.GetInviteesDetail(contextGenerate(), "") + _, err := e.GetInviteesDetail(contextGenerate(), "") require.ErrorIs(t, err, errUserIDRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetInviteesDetail(contextGenerate(), "1234") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetInviteesDetail(contextGenerate(), "1234") require.NoError(t, err) assert.NotNil(t, result) } func TestGetUserAffilateRebateInformation(t *testing.T) { t.Parallel() - _, err := ok.GetUserAffiliateRebateInformation(contextGenerate(), "") + _, err := e.GetUserAffiliateRebateInformation(contextGenerate(), "") require.ErrorIs(t, err, errInvalidAPIKey) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetUserAffiliateRebateInformation(contextGenerate(), "1234") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetUserAffiliateRebateInformation(contextGenerate(), "1234") require.NoError(t, err) assert.NotNil(t, result) } func TestGetOpenInterest(t *testing.T) { t.Parallel() - _, err := ok.GetOpenInterest(contextGenerate(), key.PairAsset{ + _, err := e.GetOpenInterest(contextGenerate(), key.PairAsset{ Base: currency.ETH.Item, Quote: currency.USDT.Item, Asset: asset.USDTMarginedFutures, @@ -5631,7 +5630,7 @@ func TestGetOpenInterest(t *testing.T) { require.ErrorIs(t, err, asset.ErrNotSupported) usdSwapCode := currency.NewCode("USD-SWAP") - resp, err := ok.GetOpenInterest(contextGenerate(), key.PairAsset{ + resp, err := e.GetOpenInterest(contextGenerate(), key.PairAsset{ Base: perpetualSwapPair.Base.Item, Quote: perpetualSwapPair.Quote.Item, Asset: asset.PerpetualSwap, @@ -5640,8 +5639,8 @@ func TestGetOpenInterest(t *testing.T) { assert.NotEmpty(t, resp) cp1 := currency.NewPair(currency.DOGE, usdSwapCode) - sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, ok, asset.PerpetualSwap, cp1) - resp, err = ok.GetOpenInterest(contextGenerate(), + sharedtestvalues.SetupCurrencyPairsForExchangeAsset(t, e, asset.PerpetualSwap, cp1) + resp, err = e.GetOpenInterest(contextGenerate(), key.PairAsset{ Base: currency.BTC.Item, Quote: usdSwapCode.Item, @@ -5655,20 +5654,20 @@ func TestGetOpenInterest(t *testing.T) { ) assert.NoError(t, err) assert.NotEmpty(t, resp) - resp, err = ok.GetOpenInterest(contextGenerate()) + resp, err = e.GetOpenInterest(contextGenerate()) assert.NoError(t, err) assert.NotEmpty(t, resp) } func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, ok) - for _, a := range ok.GetAssetTypes(false) { - pairs, err := ok.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) assert.NoError(t, err) assert.NotEmpty(t, pairs) - resp, err := ok.GetCurrencyTradeURL(contextGenerate(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(contextGenerate(), a, pairs[0]) assert.NoError(t, err) assert.NotEmpty(t, resp) } @@ -5676,27 +5675,27 @@ func TestGetCurrencyTradeURL(t *testing.T) { func TestPlaceLendingOrder(t *testing.T) { t.Parallel() - _, err := ok.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{}) + _, err := e.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{}) require.ErrorIs(t, err, common.ErrEmptyParams) arg := &LendingOrderParam{AutoRenewal: true} - _, err = ok.PlaceLendingOrder(contextGenerate(), arg) + _, err = e.PlaceLendingOrder(contextGenerate(), arg) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) arg.Currency = currency.USDT - _, err = ok.PlaceLendingOrder(contextGenerate(), arg) + _, err = e.PlaceLendingOrder(contextGenerate(), arg) require.ErrorIs(t, err, order.ErrAmountBelowMin) arg.Amount = 1 - _, err = ok.PlaceLendingOrder(contextGenerate(), arg) + _, err = e.PlaceLendingOrder(contextGenerate(), arg) require.ErrorIs(t, err, errRateRequired) arg.Rate = 0.01 - _, err = ok.PlaceLendingOrder(contextGenerate(), arg) + _, err = e.PlaceLendingOrder(contextGenerate(), arg) require.ErrorIs(t, err, errLendingTermIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.PlaceLendingOrder(contextGenerate(), &LendingOrderParam{ Currency: currency.USDT, Amount: 1, Rate: 0.01, @@ -5709,115 +5708,115 @@ func TestPlaceLendingOrder(t *testing.T) { func TestAmendLendingOrder(t *testing.T) { t.Parallel() - _, err := ok.AmendLendingOrder(contextGenerate(), "", 0, 0, false) + _, err := e.AmendLendingOrder(contextGenerate(), "", 0, 0, false) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.AmendLendingOrder(contextGenerate(), "12312312", 1., 2., true) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.AmendLendingOrder(contextGenerate(), "12312312", 1., 2., true) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLendingOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLendingOrders(contextGenerate(), "", "pending", currency.ETH, time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLendingOrders(contextGenerate(), "", "pending", currency.ETH, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetLendingSubOrderList(t *testing.T) { t.Parallel() - _, err := ok.GetLendingSubOrderList(contextGenerate(), "", "pending", time.Time{}, time.Time{}, 10) + _, err := e.GetLendingSubOrderList(contextGenerate(), "", "pending", time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetLendingSubOrderList(contextGenerate(), "12345", "", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetLendingSubOrderList(contextGenerate(), "12345", "", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelAllSpreadOrdersAfterCountdown(t *testing.T) { t.Parallel() - _, err := ok.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 2) + _, err := e.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 2) require.ErrorIs(t, err, errCountdownTimeoutRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 12) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CancelAllSpreadOrdersAfterCountdown(contextGenerate(), 12) require.NoError(t, err) assert.NotNil(t, result) } func TestGetContractsOpenInterestHistory(t *testing.T) { t.Parallel() - _, err := ok.GetFuturesContractsOpenInterestHistory(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetFuturesContractsOpenInterestHistory(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetFuturesContractsOpenInterestHistory(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) + result, err := e.GetFuturesContractsOpenInterestHistory(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesContractTakerVolume(t *testing.T) { t.Parallel() - _, err := ok.GetFuturesContractTakerVolume(contextGenerate(), "", kline.FiveMin, 1, 10, time.Time{}, time.Time{}) + _, err := e.GetFuturesContractTakerVolume(contextGenerate(), "", kline.FiveMin, 1, 10, time.Time{}, time.Time{}) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetFuturesContractTakerVolume(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, 1, 10, time.Time{}, time.Time{}) + result, err := e.GetFuturesContractTakerVolume(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, 1, 10, time.Time{}, time.Time{}) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFuturesContractLongShortAccountRatio(t *testing.T) { t.Parallel() - _, err := ok.GetFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetFuturesContractLongShortAccountRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) + result, err := e.GetFuturesContractLongShortAccountRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTopTradersFuturesContractLongShortRatio(t *testing.T) { t.Parallel() - _, err := ok.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) + result, err := e.GetTopTradersFuturesContractLongShortAccountRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetTopTradersFuturesContractLongShortPositionRatio(t *testing.T) { t.Parallel() - _, err := ok.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) + result, err := e.GetTopTradersFuturesContractLongShortPositionRatio(contextGenerate(), perpetualSwapPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAccountInstruments(t *testing.T) { t.Parallel() - _, err := ok.GetAccountInstruments(contextGenerate(), asset.Empty, "", "", mainPair.String()) + _, err := e.GetAccountInstruments(contextGenerate(), asset.Empty, "", "", mainPair.String()) require.ErrorIs(t, err, errInvalidInstrumentType) - _, err = ok.GetAccountInstruments(contextGenerate(), asset.Futures, "", "", mainPair.String()) + _, err = e.GetAccountInstruments(contextGenerate(), asset.Futures, "", "", mainPair.String()) require.ErrorIs(t, err, errInvalidUnderlying) - _, err = ok.GetAccountInstruments(contextGenerate(), asset.Options, "", "", mainPair.String()) + _, err = e.GetAccountInstruments(contextGenerate(), asset.Options, "", "", mainPair.String()) require.ErrorIs(t, err, errInstrumentFamilyOrUnderlyingRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetAccountInstruments(contextGenerate(), asset.Spot, "", "", mainPair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetAccountInstruments(contextGenerate(), asset.Spot, "", "", mainPair.String()) assert.NoError(t, err) assert.NotNil(t, result) - result, err = ok.GetAccountInstruments(contextGenerate(), asset.PerpetualSwap, "", mainPair.String(), perpetualSwapPair.String()) + result, err = e.GetAccountInstruments(contextGenerate(), asset.PerpetualSwap, "", mainPair.String(), perpetualSwapPair.String()) assert.NoError(t, err) assert.NotNil(t, result) - testexch.UpdatePairsOnce(t, ok) - p, err := ok.GetEnabledPairs(asset.Options) + testexch.UpdatePairsOnce(t, e) + p, err := e.GetEnabledPairs(asset.Options) require.NoError(t, err, "GetEnabledPairs must not error") require.NotEmpty(t, p, "GetEnabledPairs must not return empty pairs") @@ -5826,7 +5825,7 @@ func TestGetAccountInstruments(t *testing.T) { require.NotEqual(t, -1, idx, "strings.Index must find a hyphen") uly += "-" + p[0].Quote.String()[:idx] - result, err = ok.GetAccountInstruments(contextGenerate(), asset.Options, uly, "", p[0].String()) + result, err = e.GetAccountInstruments(contextGenerate(), asset.Options, uly, "", p[0].String()) require.NoError(t, err) assert.NotNil(t, result) } @@ -5875,20 +5874,20 @@ func TestOrderTypeString(t *testing.T) { func TestGetMarkPriceCandlesticks(t *testing.T) { t.Parallel() - _, err := ok.GetMarkPriceCandlesticks(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) + _, err := e.GetMarkPriceCandlesticks(contextGenerate(), "", kline.FiveMin, time.Time{}, time.Time{}, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetMarkPriceCandlesticks(contextGenerate(), mainPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) + result, err := e.GetMarkPriceCandlesticks(contextGenerate(), mainPair.String(), kline.FiveMin, time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetHistoricIndexCandlesticksHistory(t *testing.T) { t.Parallel() - _, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.TenMin, 10) + _, err := e.GetHistoricIndexCandlesticksHistory(contextGenerate(), "", time.Time{}, time.Time{}, kline.TenMin, 10) require.ErrorIs(t, err, errMissingInstrumentID) - result, err := ok.GetHistoricIndexCandlesticksHistory(contextGenerate(), mainPair.String(), time.Time{}, time.Time{}, kline.FiveMin, 10) + result, err := e.GetHistoricIndexCandlesticksHistory(contextGenerate(), mainPair.String(), time.Time{}, time.Time{}, kline.FiveMin, 10) require.NoError(t, err) assert.NotNil(t, result) } @@ -5898,7 +5897,7 @@ func TestAssetTypeString(t *testing.T) { _, err := assetTypeString(asset.LinearContract) require.ErrorIs(t, err, asset.ErrNotSupported) - assetTypes := ok.GetAssetTypes(false) + assetTypes := e.GetAssetTypes(false) for a := range assetTypes { if assetTypes[a] == asset.Spread { continue @@ -5910,113 +5909,113 @@ func TestAssetTypeString(t *testing.T) { func TestGetAnnouncements(t *testing.T) { t.Parallel() - result, err := ok.GetAnnouncements(contextGenerate(), "", 0) + result, err := e.GetAnnouncements(contextGenerate(), "", 0) require.NoError(t, err) assert.NotNil(t, result) } func TestGetAnnouncementTypes(t *testing.T) { t.Parallel() - _, err := ok.GetAnnouncementTypes(contextGenerate()) + _, err := e.GetAnnouncementTypes(contextGenerate()) assert.NoError(t, err) // No tests of contents of resp because currently in US based github actions announcement-types returns empty } func TestGetDepositOrderDetail(t *testing.T) { t.Parallel() - _, err := ok.GetDepositOrderDetail(contextGenerate(), "") + _, err := e.GetDepositOrderDetail(contextGenerate(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetDepositOrderDetail(contextGenerate(), "12312312") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetDepositOrderDetail(contextGenerate(), "12312312") require.NoError(t, err) assert.NotNil(t, result) } func TestGetFiatDepositOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFiatDepositOrderHistory(contextGenerate(), currency.USDT, "TR_BANKS", "failed", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFiatDepositOrderHistory(contextGenerate(), currency.USDT, "TR_BANKS", "failed", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestGetWithdrawalOrderDetail(t *testing.T) { t.Parallel() - _, err := ok.GetWithdrawalOrderDetail(contextGenerate(), "") + _, err := e.GetWithdrawalOrderDetail(contextGenerate(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetWithdrawalOrderDetail(contextGenerate(), "024041201450544699") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetWithdrawalOrderDetail(contextGenerate(), "024041201450544699") require.NoError(t, err) assert.NotNil(t, result) } func TestGetFiatWithdrawalOrderHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFiatWithdrawalOrderHistory(contextGenerate(), currency.USDT, "SEPA", "failed", time.Time{}, time.Time{}, 10) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFiatWithdrawalOrderHistory(contextGenerate(), currency.USDT, "SEPA", "failed", time.Time{}, time.Time{}, 10) require.NoError(t, err) assert.NotNil(t, result) } func TestCancelWithdrawalOrder(t *testing.T) { t.Parallel() - _, err := ok.CancelWithdrawalOrder(contextGenerate(), "") + _, err := e.CancelWithdrawalOrder(contextGenerate(), "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.CancelWithdrawalOrder(contextGenerate(), "124041201450544699") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.CancelWithdrawalOrder(contextGenerate(), "124041201450544699") require.NoError(t, err) assert.NotNil(t, result) } func TestCreateWithdrawalOrder(t *testing.T) { t.Parallel() - _, err := ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) + _, err := e.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) require.ErrorIs(t, err, errIDNotSet) - _, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.EMPTYCODE, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) + _, err = e.CreateWithdrawalOrder(contextGenerate(), currency.EMPTYCODE, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - _, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 0) + _, err = e.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 0) require.ErrorIs(t, err, order.ErrAmountBelowMin) - _, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "", "194a6975e98246538faeb0fab0d502df", 1000) + _, err = e.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "", "194a6975e98246538faeb0fab0d502df", 1000) require.ErrorIs(t, err, errPaymentMethodRequired) - _, err = ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "", 1000) + _, err = e.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "", 1000) require.ErrorIs(t, err, errIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - result, err := ok.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + result, err := e.CreateWithdrawalOrder(contextGenerate(), currency.BTC, "1231312312", "SEPA", "194a6975e98246538faeb0fab0d502df", 1000) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFiatWithdrawalPaymentMethods(t *testing.T) { t.Parallel() - _, err := ok.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.EMPTYCODE) + _, err := e.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.TRY) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFiatWithdrawalPaymentMethods(contextGenerate(), currency.TRY) require.NoError(t, err) assert.NotNil(t, result) } func TestGetFiatDepositPaymentMethods(t *testing.T) { t.Parallel() - _, err := ok.GetFiatDepositPaymentMethods(contextGenerate(), currency.EMPTYCODE) + _, err := e.GetFiatDepositPaymentMethods(contextGenerate(), currency.EMPTYCODE) require.ErrorIs(t, err, currency.ErrCurrencyCodeEmpty) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) - result, err := ok.GetFiatDepositPaymentMethods(contextGenerate(), currency.TRY) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + result, err := e.GetFiatDepositPaymentMethods(contextGenerate(), currency.TRY) require.NoError(t, err) assert.NotNil(t, result) } -func (ok *Okx) instrumentFamilyFromInstID(instrumentType, instID string) (string, error) { - ok.instrumentsInfoMapLock.Lock() - defer ok.instrumentsInfoMapLock.Unlock() +func (e *Exchange) instrumentFamilyFromInstID(instrumentType, instID string) (string, error) { + e.instrumentsInfoMapLock.Lock() + defer e.instrumentsInfoMapLock.Unlock() if instrumentType != "" { - insts, okay := ok.instrumentsInfoMap[instrumentType] + insts, okay := e.instrumentsInfoMap[instrumentType] if !okay { return "", errInvalidInstrumentType } @@ -6026,7 +6025,7 @@ func (ok *Okx) instrumentFamilyFromInstID(instrumentType, instID string) (string } } } else { - for _, insts := range ok.instrumentsInfoMap { + for _, insts := range e.instrumentsInfoMap { for a := range insts { if insts[a].InstrumentID.String() == instID { return insts[a].InstrumentFamily, nil @@ -6040,21 +6039,21 @@ func (ok *Okx) instrumentFamilyFromInstID(instrumentType, instID string) (string func TestGenerateSubscriptions(t *testing.T) { t.Parallel() - ok := new(Okx) //nolint:govet // Intentional copy to prevent future copy/paste mistakes - require.NoError(t, testexch.Setup(ok), "Setup must not error") - ok.Websocket.SetCanUseAuthenticatedEndpoints(true) - subs, err := ok.generateSubscriptions() + e := new(Exchange) //nolint:govet // Intentional shadow + require.NoError(t, testexch.Setup(e), "Setup must not error") + e.Websocket.SetCanUseAuthenticatedEndpoints(true) + subs, err := e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp := subscription.List{ {Channel: subscription.MyAccountChannel, QualifiedChannel: `{"channel":"account"}`, Authenticated: true}, } var pairs currency.Pairs - for _, s := range ok.Features.Subscriptions { - for _, a := range ok.GetAssetTypes(true) { + for _, s := range e.Features.Subscriptions { + for _, a := range e.GetAssetTypes(true) { if a == asset.Spread || (s.Asset != asset.All && s.Asset != a) { continue } - pairs, err = ok.GetEnabledPairs(a) + pairs, err = e.GetEnabledPairs(a) require.NoErrorf(t, err, "GetEnabledPairs %s must not error", a) pairs = common.SortStrings(pairs).Format(currency.PairFormat{Uppercase: true, Delimiter: "-"}) s := s.Clone() //nolint:govet // Intentional lexical scope shadow @@ -6081,14 +6080,14 @@ func TestGenerateSubscriptions(t *testing.T) { } testsubs.EqualLists(t, exp, subs) - ok.Features.Subscriptions = subscription.List{{Channel: channelGridPositions, Params: map[string]any{"algoId": "42"}}} - subs, err = ok.generateSubscriptions() + e.Features.Subscriptions = subscription.List{{Channel: channelGridPositions, Params: map[string]any{"algoId": "42"}}} + subs, err = e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp = subscription.List{{Channel: channelGridPositions, Params: map[string]any{"algoId": "42"}, QualifiedChannel: `{"channel":"grid-positions","algoId":"42"}`}} testsubs.EqualLists(t, exp, subs) - ok.Features.Subscriptions = subscription.List{{Channel: channelGridPositions}} - subs, err = ok.generateSubscriptions() + e.Features.Subscriptions = subscription.List{{Channel: channelGridPositions}} + subs, err = e.generateSubscriptions() require.NoError(t, err, "generateSubscriptions must not error") exp = subscription.List{{Channel: channelGridPositions, QualifiedChannel: `{"channel":"grid-positions"}`}} testsubs.EqualLists(t, exp, subs) @@ -6104,31 +6103,31 @@ const ( func TestWsProcessSpreadOrderbook(t *testing.T) { t.Parallel() - err := ok.wsProcessSpreadOrderbook([]byte(processSpreadOrderbookJSON)) + err := e.wsProcessSpreadOrderbook([]byte(processSpreadOrderbookJSON)) assert.NoError(t, err) } func TestWsProcessPublicSpreadTrades(t *testing.T) { t.Parallel() - err := ok.wsProcessPublicSpreadTrades([]byte(wsProcessPublicSpreadTradesJSON)) + err := e.wsProcessPublicSpreadTrades([]byte(wsProcessPublicSpreadTradesJSON)) assert.NoError(t, err) } func TestWsProcessPublicSpreadTicker(t *testing.T) { t.Parallel() - err := ok.wsProcessPublicSpreadTicker([]byte(okxSpreadPublicTickerJSON)) + err := e.wsProcessPublicSpreadTicker([]byte(okxSpreadPublicTickerJSON)) assert.NoError(t, err) } func TestWsProcessSpreadOrders(t *testing.T) { t.Parallel() - err := ok.wsProcessSpreadOrders([]byte(wsProcessSpreadOrdersJSON)) + err := e.wsProcessSpreadOrders([]byte(wsProcessSpreadOrdersJSON)) assert.NoError(t, err) } func TestWsProcessSpreadTradesJSON(t *testing.T) { t.Parallel() - err := ok.wsProcessSpreadTrades([]byte(wsProcessSpreadTradesJSON)) + err := e.wsProcessSpreadTrades([]byte(wsProcessSpreadTradesJSON)) assert.NoError(t, err) } @@ -6174,16 +6173,16 @@ func TestGetFee(t *testing.T) { Pair: mainPair, PurchasePrice: 1, } - _, err := ok.GetFee(contextGenerate(), feeBuilder) + _, err := e.GetFee(contextGenerate(), feeBuilder) require.ErrorIs(t, err, errFeeTypeUnsupported) feeBuilder.FeeType = exchange.OfflineTradeFee - _, err = ok.GetFee(contextGenerate(), feeBuilder) + _, err = e.GetFee(contextGenerate(), feeBuilder) assert.NoError(t, err) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) feeBuilder.FeeType = exchange.CryptocurrencyTradeFee - _, err = ok.GetFee(contextGenerate(), feeBuilder) + _, err = e.GetFee(contextGenerate(), feeBuilder) require.NoError(t, err) } @@ -6213,7 +6212,7 @@ func TestMarginTypeToString(t *testing.T) { } var marginTypeString string for m := range marginTypeToStringMap { - marginTypeString = ok.marginTypeToString(m) + marginTypeString = e.marginTypeToString(m) assert.Equal(t, marginTypeString, marginTypeToStringMap[m]) } } diff --git a/exchanges/okx/okx_websocket.go b/exchanges/okx/okx_websocket.go index 6e946c94a37..59bb41cdf33 100644 --- a/exchanges/okx/okx_websocket.go +++ b/exchanges/okx/okx_websocket.go @@ -236,63 +236,63 @@ var subscriptionNames = map[string]string{ } // WsConnect initiates a websocket connection -func (ok *Okx) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !ok.Websocket.IsEnabled() || !ok.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer dialer.ReadBufferSize = 8192 dialer.WriteBufferSize = 8192 - err := ok.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - ok.Websocket.Wg.Add(1) - go ok.wsReadData(ctx, ok.Websocket.Conn) - if ok.Verbose { + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, e.Websocket.Conn) + if e.Verbose { log.Debugf(log.ExchangeSys, "Successful connection to %v\n", - ok.Websocket.GetWebsocketURL()) + e.Websocket.GetWebsocketURL()) } - ok.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Conn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: pingMsg, Delay: time.Second * 20, }) - if ok.Websocket.CanUseAuthenticatedEndpoints() { - err = ok.WsAuth(ctx) + if e.Websocket.CanUseAuthenticatedEndpoints() { + err = e.WsAuth(ctx) if err != nil { log.Errorf(log.ExchangeSys, "Error connecting auth socket: %s\n", err.Error()) - ok.Websocket.SetCanUseAuthenticatedEndpoints(false) + e.Websocket.SetCanUseAuthenticatedEndpoints(false) } } return nil } // WsAuth will connect to Okx's Private websocket connection and Authenticate with a login payload. -func (ok *Okx) WsAuth(ctx context.Context) error { - if !ok.AreCredentialsValid(ctx) || !ok.Websocket.CanUseAuthenticatedEndpoints() { - return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", ok.Name) +func (e *Exchange) WsAuth(ctx context.Context) error { + if !e.AreCredentialsValid(ctx) || !e.Websocket.CanUseAuthenticatedEndpoints() { + return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", e.Name) } - creds, err := ok.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } var dialer gws.Dialer - err = ok.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}) + err = e.Websocket.AuthConn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - ok.Websocket.Wg.Add(1) - go ok.wsReadData(ctx, ok.Websocket.AuthConn) - ok.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{ + e.Websocket.Wg.Add(1) + go e.wsReadData(ctx, e.Websocket.AuthConn) + e.Websocket.AuthConn.SetupPingHandler(request.Unset, websocket.PingHandler{ MessageType: gws.TextMessage, Message: pingMsg, Delay: time.Second * 20, }) - ok.Websocket.SetCanUseAuthenticatedEndpoints(true) + e.Websocket.SetCanUseAuthenticatedEndpoints(true) ts := time.Now().Unix() signPath := "/users/self/verify" hmac, err := crypto.GetHMAC(crypto.HashSHA256, @@ -312,38 +312,38 @@ func (ok *Okx) WsAuth(ctx context.Context) error { }, } - return ok.SendAuthenticatedWebsocketRequest(ctx, request.Unset, "login-response", operationLogin, args, nil) + return e.SendAuthenticatedWebsocketRequest(ctx, request.Unset, "login-response", operationLogin, args, nil) } // wsReadData sends msgs from public and auth websockets to data handler -func (ok *Okx) wsReadData(ctx context.Context, ws websocket.Connection) { - defer ok.Websocket.Wg.Done() +func (e *Exchange) wsReadData(ctx context.Context, ws websocket.Connection) { + defer e.Websocket.Wg.Done() for { resp := ws.ReadMessage() if resp.Raw == nil { return } - if err := ok.WsHandleData(ctx, resp.Raw); err != nil { - ok.Websocket.DataHandler <- err + if err := e.WsHandleData(ctx, resp.Raw); err != nil { + e.Websocket.DataHandler <- err } } } // Subscribe sends a websocket subscription request to several channels to receive data. -func (ok *Okx) Subscribe(channelsToSubscribe subscription.List) error { +func (e *Exchange) Subscribe(channelsToSubscribe subscription.List) error { ctx := context.TODO() - return ok.handleSubscription(ctx, operationSubscribe, channelsToSubscribe) + return e.handleSubscription(ctx, operationSubscribe, channelsToSubscribe) } // Unsubscribe sends a websocket unsubscription request to several channels to receive data. -func (ok *Okx) Unsubscribe(channelsToUnsubscribe subscription.List) error { +func (e *Exchange) Unsubscribe(channelsToUnsubscribe subscription.List) error { ctx := context.TODO() - return ok.handleSubscription(ctx, operationUnsubscribe, channelsToUnsubscribe) + return e.handleSubscription(ctx, operationUnsubscribe, channelsToUnsubscribe) } // handleSubscription sends a subscription and unsubscription information thought the websocket endpoint. // as of the okx, exchange this endpoint sends subscription and unsubscription messages but with a list of json objects. -func (ok *Okx) handleSubscription(ctx context.Context, operation string, subs subscription.List) error { +func (e *Exchange) handleSubscription(ctx context.Context, operation string, subs subscription.List) error { reqs := WSSubscriptionInformationList{Operation: operation} authRequests := WSSubscriptionInformationList{Operation: operation} var channels subscription.List @@ -367,14 +367,14 @@ func (ok *Okx) handleSubscription(ctx context.Context, operation string, subs su if len(authChunk) > maxConnByteLen { authRequests.Arguments = authRequests.Arguments[:len(authRequests.Arguments)-1] i-- - err = ok.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, authRequests) + err = e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, authRequests) if err != nil { return err } if operation == operationUnsubscribe { - err = ok.Websocket.RemoveSubscriptions(ok.Websocket.AuthConn, channels...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.AuthConn, channels...) } else { - err = ok.Websocket.AddSuccessfulSubscriptions(ok.Websocket.AuthConn, channels...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.AuthConn, channels...) } if err != nil { return err @@ -391,14 +391,14 @@ func (ok *Okx) handleSubscription(ctx context.Context, operation string, subs su } if len(chunk) > maxConnByteLen { i-- - err = ok.Websocket.Conn.SendJSONMessage(ctx, request.Unset, reqs) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, reqs) if err != nil { return err } if operation == operationUnsubscribe { - err = ok.Websocket.RemoveSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channels...) } else { - err = ok.Websocket.AddSuccessfulSubscriptions(ok.Websocket.Conn, channels...) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channels...) } if err != nil { return err @@ -411,28 +411,28 @@ func (ok *Okx) handleSubscription(ctx context.Context, operation string, subs su } if len(reqs.Arguments) > 0 { - if err := ok.Websocket.Conn.SendJSONMessage(ctx, request.Unset, reqs); err != nil { + if err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, reqs); err != nil { return err } } - if len(authRequests.Arguments) > 0 && ok.Websocket.CanUseAuthenticatedEndpoints() { - if err := ok.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, authRequests); err != nil { + if len(authRequests.Arguments) > 0 && e.Websocket.CanUseAuthenticatedEndpoints() { + if err := e.Websocket.AuthConn.SendJSONMessage(ctx, request.Unset, authRequests); err != nil { return err } } channels = append(channels, authChannels...) if operation == operationUnsubscribe { - return ok.Websocket.RemoveSubscriptions(ok.Websocket.Conn, channels...) + return e.Websocket.RemoveSubscriptions(e.Websocket.Conn, channels...) } - return ok.Websocket.AddSuccessfulSubscriptions(ok.Websocket.Conn, channels...) + return e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, channels...) } // WsHandleData will read websocket raw data and pass to appropriate handler -func (ok *Okx) WsHandleData(ctx context.Context, respRaw []byte) error { +func (e *Exchange) WsHandleData(ctx context.Context, respRaw []byte) error { if id, _ := jsonparser.GetString(respRaw, "id"); id != "" { - return ok.Websocket.Match.RequireMatchWithData(id, respRaw) + return e.Websocket.Match.RequireMatchWithData(id, respRaw) } var resp wsIncomingData @@ -444,7 +444,7 @@ func (ok *Okx) WsHandleData(ctx context.Context, respRaw []byte) error { return fmt.Errorf("%w unmarshalling %v", err, respRaw) } if resp.Event == operationLogin || (resp.Event == "error" && slices.Contains(authConnErrorCodes, resp.StatusCode)) { - return ok.Websocket.Match.RequireMatchWithData("login-response", respRaw) + return e.Websocket.Match.RequireMatchWithData("login-response", respRaw) } if len(resp.Data) == 0 { return nil @@ -457,7 +457,7 @@ func (ok *Okx) WsHandleData(ctx context.Context, respRaw []byte) error { channelCandle3Mutc, channelCandle1Mutc, channelCandle1Wutc, channelCandle1Dutc, channelCandle2Dutc, channelCandle3Dutc, channelCandle5Dutc, channelCandle12Hutc, channelCandle6Hutc: - return ok.wsProcessCandles(respRaw) + return e.wsProcessCandles(respRaw) case channelIndexCandle1Y, channelIndexCandle6M, channelIndexCandle3M, channelIndexCandle1M, channelIndexCandle1W, channelIndexCandle1D, channelIndexCandle2D, channelIndexCandle3D, channelIndexCandle5D, channelIndexCandle12H, channelIndexCandle6H, channelIndexCandle4H, @@ -466,100 +466,100 @@ func (ok *Okx) WsHandleData(ctx context.Context, respRaw []byte) error { channelIndexCandle3Mutc, channelIndexCandle1Mutc, channelIndexCandle1Wutc, channelIndexCandle1Dutc, channelIndexCandle2Dutc, channelIndexCandle3Dutc, channelIndexCandle5Dutc, channelIndexCandle12Hutc, channelIndexCandle6Hutc: - return ok.wsProcessIndexCandles(respRaw) + return e.wsProcessIndexCandles(respRaw) case channelTickers: - return ok.wsProcessTickers(respRaw) + return e.wsProcessTickers(respRaw) case channelIndexTickers: var response WsIndexTicker - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelStatus: var response WsSystemStatusResponse - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelPublicStrucBlockTrades: var response WsPublicTradesResponse - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelPublicBlockTrades: - return ok.wsProcessBlockPublicTrades(respRaw) + return e.wsProcessBlockPublicTrades(respRaw) case channelBlockTickers: var response WsBlockTicker - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelAccountGreeks: var response WsGreeks - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelAccount: var response WsAccountChannelPushData - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelPositions, channelLiquidationWarning: var response WsPositionResponse - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelBalanceAndPosition: - return ok.wsProcessBalanceAndPosition(ctx, respRaw) + return e.wsProcessBalanceAndPosition(ctx, respRaw) case channelOrders: - return ok.wsProcessOrders(respRaw) + return e.wsProcessOrders(respRaw) case channelAlgoOrders: var response WsAlgoOrder - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelAlgoAdvance: var response WsAdvancedAlgoOrder - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelRFQs: var response WsRFQ - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelQuotes: var response WsQuote - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelStructureBlockTrades: var response WsStructureBlocTrade - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelSpotGridOrder: var response WsSpotGridAlgoOrder - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelGridOrdersContract: var response WsContractGridAlgoOrder - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelGridPositions: var response WsContractGridAlgoOrder - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelGridSubOrders: var response WsGridSubOrderData - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelInstruments: var response WSInstrumentResponse - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelOpenInterest: var response WSOpenInterestResponse - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelTrades, channelAllTrades: - return ok.wsProcessTrades(respRaw) + return e.wsProcessTrades(respRaw) case channelEstimatedPrice: var response WsDeliveryEstimatedPrice - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelMarkPrice, channelPriceLimit: var response WsMarkPrice - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelOrderBooks5: - return ok.wsProcessOrderbook5(respRaw) + return e.wsProcessOrderbook5(respRaw) case okxSpreadOrderbookLevel1, okxSpreadOrderbook: - return ok.wsProcessSpreadOrderbook(respRaw) + return e.wsProcessSpreadOrderbook(respRaw) case okxSpreadPublicTrades: - return ok.wsProcessPublicSpreadTrades(respRaw) + return e.wsProcessPublicSpreadTrades(respRaw) case okxSpreadPublicTicker: - return ok.wsProcessPublicSpreadTicker(respRaw) + return e.wsProcessPublicSpreadTicker(respRaw) case channelOrderBooks, channelOrderBooks50TBT, channelBBOTBT, channelOrderBooksTBT: - return ok.wsProcessOrderBooks(respRaw) + return e.wsProcessOrderBooks(respRaw) case channelOptionTrades: - return ok.wsProcessOptionTrades(respRaw) + return e.wsProcessOptionTrades(respRaw) case channelOptSummary: var response WsOptionSummary - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelFundingRate: var response WsFundingRate - return ok.wsProcessPushData(respRaw, &response) + return e.wsProcessPushData(respRaw, &response) case channelMarkPriceCandle1Y, channelMarkPriceCandle6M, channelMarkPriceCandle3M, channelMarkPriceCandle1M, channelMarkPriceCandle1W, channelMarkPriceCandle1D, channelMarkPriceCandle2D, channelMarkPriceCandle3D, channelMarkPriceCandle5D, channelMarkPriceCandle12H, channelMarkPriceCandle6H, channelMarkPriceCandle4H, @@ -568,49 +568,49 @@ func (ok *Okx) WsHandleData(ctx context.Context, respRaw []byte) error { channelMarkPriceCandle3Mutc, channelMarkPriceCandle1Mutc, channelMarkPriceCandle1Wutc, channelMarkPriceCandle1Dutc, channelMarkPriceCandle2Dutc, channelMarkPriceCandle3Dutc, channelMarkPriceCandle5Dutc, channelMarkPriceCandle12Hutc, channelMarkPriceCandle6Hutc: - return ok.wsHandleMarkPriceCandles(respRaw) + return e.wsHandleMarkPriceCandles(respRaw) case okxSpreadOrders: - return ok.wsProcessSpreadOrders(respRaw) + return e.wsProcessSpreadOrders(respRaw) case okxSpreadTrades: - return ok.wsProcessSpreadTrades(respRaw) + return e.wsProcessSpreadTrades(respRaw) case okxWithdrawalInfo: resp := &struct { Arguments SubscriptionInfo `json:"arg"` Data []WsDepositInfo `json:"data"` }{} - return ok.wsProcessPushData(respRaw, resp) + return e.wsProcessPushData(respRaw, resp) case okxDepositInfo: resp := &struct { Arguments SubscriptionInfo `json:"arg"` Data []WsWithdrawlInfo `json:"data"` }{} - return ok.wsProcessPushData(respRaw, resp) + return e.wsProcessPushData(respRaw, resp) case channelRecurringBuy: resp := &struct { Arguments SubscriptionInfo `json:"arg"` Data []RecurringBuyOrder `json:"data"` }{} - return ok.wsProcessPushData(respRaw, resp) + return e.wsProcessPushData(respRaw, resp) case liquidationOrders: var resp *LiquidationOrder - return ok.wsProcessPushData(respRaw, &resp) + return e.wsProcessPushData(respRaw, &resp) case adlWarning: var resp ADLWarning - return ok.wsProcessPushData(respRaw, &resp) + return e.wsProcessPushData(respRaw, &resp) case economicCalendar: var resp EconomicCalendarResponse - return ok.wsProcessPushData(respRaw, &resp) + return e.wsProcessPushData(respRaw, &resp) case copyTrading: var resp CopyTradingNotification - return ok.wsProcessPushData(respRaw, &resp) + return e.wsProcessPushData(respRaw, &resp) default: - ok.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: ok.Name + websocket.UnhandledMessage + string(respRaw)} + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{Message: e.Name + websocket.UnhandledMessage + string(respRaw)} return nil } } // wsProcessSpreadTrades handle and process spread order trades -func (ok *Okx) wsProcessSpreadTrades(respRaw []byte) error { +func (e *Exchange) wsProcessSpreadTrades(respRaw []byte) error { if respRaw == nil { return common.ErrNilPointer } @@ -622,7 +622,7 @@ func (ok *Okx) wsProcessSpreadTrades(respRaw []byte) error { if len(resp.Data) == 0 { return kline.ErrNoTimeSeriesDataToConvert } - pair, err := ok.GetPairFromInstrumentID(resp.Argument.SpreadID) + pair, err := e.GetPairFromInstrumentID(resp.Argument.SpreadID) if err != nil { return err } @@ -636,7 +636,7 @@ func (ok *Okx) wsProcessSpreadTrades(respRaw []byte) error { Amount: resp.Data[x].FillSize.Float64(), AssetType: asset.Spread, CurrencyPair: pair, - Exchange: ok.Name, + Exchange: e.Name, Side: oSide, Timestamp: resp.Data[x].Timestamp.Time(), TID: resp.Data[x].TradeID, @@ -649,7 +649,7 @@ func (ok *Okx) wsProcessSpreadTrades(respRaw []byte) error { // wsProcessSpreadOrders retrieve order information from the sprd-order Websocket channel. // Data will not be pushed when first subscribed. // Data will only be pushed when triggered by events such as placing/canceling order. -func (ok *Okx) wsProcessSpreadOrders(respRaw []byte) error { +func (e *Exchange) wsProcessSpreadOrders(respRaw []byte) error { if respRaw == nil { return common.ErrNilPointer } @@ -664,7 +664,7 @@ func (ok *Okx) wsProcessSpreadOrders(respRaw []byte) error { if len(resp.Data) == 0 { return kline.ErrNoTimeSeriesDataToConvert } - pair, err := ok.GetPairFromInstrumentID(resp.Argument.SpreadID) + pair, err := e.GetPairFromInstrumentID(resp.Argument.SpreadID) if err != nil { return err } @@ -689,7 +689,7 @@ func (ok *Okx) wsProcessSpreadOrders(respRaw []byte) error { AverageExecutedPrice: resp.Data[x].AveragePrice.Float64(), ClientOrderID: resp.Data[x].ClientOrderID, Date: resp.Data[x].CreationTime.Time(), - Exchange: ok.Name, + Exchange: e.Name, ExecutedAmount: resp.Data[x].FillSize.Float64(), OrderID: resp.Data[x].OrderID, Pair: pair, @@ -702,12 +702,12 @@ func (ok *Okx) wsProcessSpreadOrders(respRaw []byte) error { LastUpdated: resp.Data[x].UpdateTime.Time(), } } - ok.Websocket.DataHandler <- orderDetails + e.Websocket.DataHandler <- orderDetails return nil } // wsProcessIndexCandles processes index candlestick data -func (ok *Okx) wsProcessIndexCandles(respRaw []byte) error { +func (e *Exchange) wsProcessIndexCandles(respRaw []byte) error { if respRaw == nil { return common.ErrNilPointer } @@ -731,7 +731,7 @@ func (ok *Okx) wsProcessIndexCandles(respRaw []byte) error { } assets = append(assets, assetType) } else { - assets, err = ok.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) + assets, err = e.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) if err != nil { return err } @@ -741,7 +741,7 @@ func (ok *Okx) wsProcessIndexCandles(respRaw []byte) error { candlesData := response.Data[i] myCandle := websocket.KlineData{ Pair: response.Argument.InstrumentID, - Exchange: ok.Name, + Exchange: e.Name, Timestamp: time.UnixMilli(candlesData[0].Int64()), Interval: candleInterval, OpenPrice: candlesData[1].Float64(), @@ -751,14 +751,14 @@ func (ok *Okx) wsProcessIndexCandles(respRaw []byte) error { } for i := range assets { myCandle.AssetType = assets[i] - ok.Websocket.DataHandler <- myCandle + e.Websocket.DataHandler <- myCandle } } return nil } // wsProcessPublicSpreadTicker process spread order ticker push data. -func (ok *Okx) wsProcessPublicSpreadTicker(respRaw []byte) error { +func (e *Exchange) wsProcessPublicSpreadTicker(respRaw []byte) error { var resp WsSpreadPushData data := []WsSpreadPublicTicker{} resp.Data = &data @@ -777,19 +777,19 @@ func (ok *Okx) wsProcessPublicSpreadTicker(respRaw []byte) error { Bid: data[x].BidPrice.Float64(), Ask: data[x].AskPrice.Float64(), Pair: pair, - ExchangeName: ok.Name, + ExchangeName: e.Name, AssetType: asset.Spread, LastUpdated: data[x].Timestamp.Time(), } } - ok.Websocket.DataHandler <- tickers + e.Websocket.DataHandler <- tickers return nil } // wsProcessPublicSpreadTrades retrieve the recent trades data from sprd-public-trades. // Data will be pushed whenever there is a trade. // Every update contains only one trade. -func (ok *Okx) wsProcessPublicSpreadTrades(respRaw []byte) error { +func (e *Exchange) wsProcessPublicSpreadTrades(respRaw []byte) error { var resp WsSpreadPushData data := []WsSpreadPublicTrade{} resp.Data = data @@ -809,7 +809,7 @@ func (ok *Okx) wsProcessPublicSpreadTrades(respRaw []byte) error { } trades[x] = trade.Data{ TID: data[x].TradeID, - Exchange: ok.Name, + Exchange: e.Name, CurrencyPair: pair, AssetType: asset.Spread, Side: oSide, @@ -822,13 +822,13 @@ func (ok *Okx) wsProcessPublicSpreadTrades(respRaw []byte) error { } // wsProcessSpreadOrderbook process spread orderbook data. -func (ok *Okx) wsProcessSpreadOrderbook(respRaw []byte) error { +func (e *Exchange) wsProcessSpreadOrderbook(respRaw []byte) error { var resp WsSpreadOrderbook err := json.Unmarshal(respRaw, &resp) if err != nil { return err } - pair, err := ok.GetPairFromInstrumentID(resp.Arg.SpreadID) + pair, err := e.GetPairFromInstrumentID(resp.Arg.SpreadID) if err != nil { return err } @@ -837,14 +837,14 @@ func (ok *Okx) wsProcessSpreadOrderbook(respRaw []byte) error { return err } for x := range extractedResponse.Data { - err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asset: asset.Spread, Asks: extractedResponse.Data[x].Asks, Bids: extractedResponse.Data[x].Bids, LastUpdated: resp.Data[x].Timestamp.Time(), Pair: pair, - Exchange: ok.Name, - ValidateOrderbook: ok.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, }) if err != nil { return err @@ -854,7 +854,7 @@ func (ok *Okx) wsProcessSpreadOrderbook(respRaw []byte) error { } // wsProcessOrderbook5 processes orderbook data -func (ok *Okx) wsProcessOrderbook5(data []byte) error { +func (e *Exchange) wsProcessOrderbook5(data []byte) error { var resp WsOrderbook5 err := json.Unmarshal(data, &resp) if err != nil { @@ -862,10 +862,10 @@ func (ok *Okx) wsProcessOrderbook5(data []byte) error { } if len(resp.Data) != 1 { - return fmt.Errorf("%s - no data returned", ok.Name) + return fmt.Errorf("%s - no data returned", e.Name) } - assets, err := ok.getAssetsFromInstrumentID(resp.Argument.InstrumentID.String()) + assets, err := e.getAssetsFromInstrumentID(resp.Argument.InstrumentID.String()) if err != nil { return err } @@ -883,14 +883,14 @@ func (ok *Okx) wsProcessOrderbook5(data []byte) error { } for x := range assets { - err = ok.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ + err = e.Websocket.Orderbook.LoadSnapshot(&orderbook.Book{ Asset: assets[x], Asks: asks, Bids: bids, LastUpdated: resp.Data[0].Timestamp.Time(), Pair: resp.Argument.InstrumentID, - Exchange: ok.Name, - ValidateOrderbook: ok.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, }) if err != nil { return err @@ -900,7 +900,7 @@ func (ok *Okx) wsProcessOrderbook5(data []byte) error { } // wsProcessOptionTrades handles options trade data -func (ok *Okx) wsProcessOptionTrades(data []byte) error { +func (e *Exchange) wsProcessOptionTrades(data []byte) error { var resp WsOptionTrades err := json.Unmarshal(data, &resp) if err != nil { @@ -909,7 +909,7 @@ func (ok *Okx) wsProcessOptionTrades(data []byte) error { trades := make([]trade.Data, len(resp.Data)) for i := range resp.Data { var pair currency.Pair - pair, err = ok.GetPairFromInstrumentID(resp.Data[i].InstrumentID) + pair, err = e.GetPairFromInstrumentID(resp.Data[i].InstrumentID) if err != nil { return err } @@ -921,7 +921,7 @@ func (ok *Okx) wsProcessOptionTrades(data []byte) error { Amount: resp.Data[i].Size.Float64(), AssetType: asset.Options, CurrencyPair: pair, - Exchange: ok.Name, + Exchange: e.Name, Side: oSide, Timestamp: resp.Data[i].Timestamp.Time(), TID: resp.Data[i].TradeID, @@ -932,7 +932,7 @@ func (ok *Okx) wsProcessOptionTrades(data []byte) error { } // wsProcessOrderBooks processes "snapshot" and "update" order book -func (ok *Okx) wsProcessOrderBooks(data []byte) error { +func (e *Exchange) wsProcessOrderBooks(data []byte) error { var response WsOrderBook err := json.Unmarshal(data, &response) if err != nil { @@ -951,7 +951,7 @@ func (ok *Okx) wsProcessOrderBooks(data []byte) error { } assets = append(assets, assetType) } else { - assets, err = ok.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) + assets, err = e.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) if err != nil { return err } @@ -962,16 +962,16 @@ func (ok *Okx) wsProcessOrderBooks(data []byte) error { response.Argument.InstrumentID.Delimiter = currency.DashDelimiter for i := range response.Data { if response.Action == wsOrderbookSnapshot { - err = ok.WsProcessSnapshotOrderBook(&response.Data[i], response.Argument.InstrumentID, assets) + err = e.WsProcessSnapshotOrderBook(&response.Data[i], response.Argument.InstrumentID, assets) } else { if len(response.Data[i].Asks) == 0 && len(response.Data[i].Bids) == 0 { return nil } - err = ok.WsProcessUpdateOrderbook(&response.Data[i], response.Argument.InstrumentID, assets) + err = e.WsProcessUpdateOrderbook(&response.Data[i], response.Argument.InstrumentID, assets) } if err != nil { if errors.Is(err, errInvalidChecksum) { - err = ok.Subscribe(subscription.List{ + err = e.Subscribe(subscription.List{ { Channel: response.Argument.Channel, Asset: assets[0], @@ -979,22 +979,22 @@ func (ok *Okx) wsProcessOrderBooks(data []byte) error { }, }) if err != nil { - ok.Websocket.DataHandler <- err + e.Websocket.DataHandler <- err } } else { return err } } } - if ok.Verbose { - log.Debugf(log.ExchangeSys, "%s passed checksum for pair %s", ok.Name, response.Argument.InstrumentID) + if e.Verbose { + log.Debugf(log.ExchangeSys, "%s passed checksum for pair %s", e.Name, response.Argument.InstrumentID) } return nil } // WsProcessSnapshotOrderBook processes snapshot order books -func (ok *Okx) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.Pair, assets []asset.Item) error { - signedChecksum, err := ok.CalculateOrderbookChecksum(data) +func (e *Exchange) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.Pair, assets []asset.Item) error { + signedChecksum, err := e.CalculateOrderbookChecksum(data) if err != nil { return fmt.Errorf("%w %v: unable to calculate orderbook checksum: %s", errInvalidChecksum, @@ -1007,11 +1007,11 @@ func (ok *Okx) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.P pair) } - asks, err := ok.AppendWsOrderbookItems(data.Asks) + asks, err := e.AppendWsOrderbookItems(data.Asks) if err != nil { return err } - bids, err := ok.AppendWsOrderbookItems(data.Bids) + bids, err := e.AppendWsOrderbookItems(data.Bids) if err != nil { return err } @@ -1022,10 +1022,10 @@ func (ok *Okx) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.P Bids: bids, LastUpdated: data.Timestamp.Time(), Pair: pair, - Exchange: ok.Name, - ValidateOrderbook: ok.ValidateOrderbook, + Exchange: e.Name, + ValidateOrderbook: e.ValidateOrderbook, } - err = ok.Websocket.Orderbook.LoadSnapshot(&newOrderBook) + err = e.Websocket.Orderbook.LoadSnapshot(&newOrderBook) if err != nil { return err } @@ -1036,17 +1036,17 @@ func (ok *Okx) WsProcessSnapshotOrderBook(data *WsOrderBookData, pair currency.P // WsProcessUpdateOrderbook updates an existing orderbook using websocket data // After merging WS data, it will sort, validate and finally update the existing // orderbook -func (ok *Okx) WsProcessUpdateOrderbook(data *WsOrderBookData, pair currency.Pair, assets []asset.Item) error { - asks, err := ok.AppendWsOrderbookItems(data.Asks) +func (e *Exchange) WsProcessUpdateOrderbook(data *WsOrderBookData, pair currency.Pair, assets []asset.Item) error { + asks, err := e.AppendWsOrderbookItems(data.Asks) if err != nil { return err } - bids, err := ok.AppendWsOrderbookItems(data.Bids) + bids, err := e.AppendWsOrderbookItems(data.Bids) if err != nil { return err } for i := range assets { - if err := ok.Websocket.Orderbook.Update(&orderbook.Update{ + if err := e.Websocket.Orderbook.Update(&orderbook.Update{ Pair: pair, Asset: assets[i], UpdateTime: data.Timestamp.Time(), @@ -1062,7 +1062,7 @@ func (ok *Okx) WsProcessUpdateOrderbook(data *WsOrderBookData, pair currency.Pai } // AppendWsOrderbookItems adds websocket orderbook data bid/asks into an orderbook item array -func (ok *Okx) AppendWsOrderbookItems(entries [][4]types.Number) (orderbook.Levels, error) { +func (e *Exchange) AppendWsOrderbookItems(entries [][4]types.Number) (orderbook.Levels, error) { items := make(orderbook.Levels, len(entries)) for j := range entries { items[j] = orderbook.Level{Amount: entries[j][1].Float64(), Price: entries[j][0].Float64()} @@ -1094,7 +1094,7 @@ func generateOrderbookChecksum(orderbookData *orderbook.Book) uint32 { } // CalculateOrderbookChecksum alternates over the first 25 bid and ask entries from websocket data. -func (ok *Okx) CalculateOrderbookChecksum(orderbookData *WsOrderBookData) (uint32, error) { +func (e *Exchange) CalculateOrderbookChecksum(orderbookData *WsOrderBookData) (uint32, error) { var checksum strings.Builder for i := range allowableIterations { if len(orderbookData.Bids)-1 >= i { @@ -1120,7 +1120,7 @@ func (ok *Okx) CalculateOrderbookChecksum(orderbookData *WsOrderBookData) (uint3 } // wsHandleMarkPriceCandles processes candlestick mark price push data as a result of subscription to "mark-price-candle*" channel. -func (ok *Okx) wsHandleMarkPriceCandles(data []byte) error { +func (e *Exchange) wsHandleMarkPriceCandles(data []byte) error { tempo := &struct { Argument SubscriptionInfo `json:"arg"` Data [][5]types.Number `json:"data"` @@ -1139,20 +1139,20 @@ func (ok *Okx) wsHandleMarkPriceCandles(data []byte) error { ClosePrice: tempo.Data[x][4].Float64(), } } - ok.Websocket.DataHandler <- candles + e.Websocket.DataHandler <- candles return nil } // wsProcessTrades handles a list of trade information. -func (ok *Okx) wsProcessTrades(data []byte) error { +func (e *Exchange) wsProcessTrades(data []byte) error { var response WsTradeOrder err := json.Unmarshal(data, &response) if err != nil { return err } - saveTradeData := ok.IsSaveTradeDataEnabled() - tradeFeed := ok.IsTradeFeedEnabled() + saveTradeData := e.IsSaveTradeDataEnabled() + tradeFeed := e.IsTradeFeedEnabled() if !saveTradeData && !tradeFeed { return nil } @@ -1165,7 +1165,7 @@ func (ok *Okx) wsProcessTrades(data []byte) error { } assets = append(assets, assetType) } else { - assets, err = ok.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) + assets, err = e.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) if err != nil { return err } @@ -1181,7 +1181,7 @@ func (ok *Okx) wsProcessTrades(data []byte) error { Amount: response.Data[i].Quantity.Float64(), AssetType: assets[j], CurrencyPair: pair, - Exchange: ok.Name, + Exchange: e.Name, Side: response.Data[i].Side, Timestamp: response.Data[i].Timestamp.Time().UTC(), TID: response.Data[i].TradeID, @@ -1191,7 +1191,7 @@ func (ok *Okx) wsProcessTrades(data []byte) error { } if tradeFeed { for i := range trades { - ok.Websocket.DataHandler <- trades[i] + e.Websocket.DataHandler <- trades[i] } } if saveTradeData { @@ -1201,7 +1201,7 @@ func (ok *Okx) wsProcessTrades(data []byte) error { } // wsProcessOrders handles websocket order push data responses. -func (ok *Okx) wsProcessOrders(respRaw []byte) error { +func (e *Exchange) wsProcessOrders(respRaw []byte) error { var response WsOrderResponse err := json.Unmarshal(respRaw, &response) if err != nil { @@ -1214,16 +1214,16 @@ func (ok *Okx) wsProcessOrders(respRaw []byte) error { for x := range response.Data { orderType, err := order.StringToOrderType(response.Data[x].OrderType) if err != nil { - ok.Websocket.DataHandler <- order.ClassificationError{ - Exchange: ok.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } } orderStatus, err := order.StringToOrderStatus(response.Data[x].State) if err != nil { - ok.Websocket.DataHandler <- order.ClassificationError{ - Exchange: ok.Name, + e.Websocket.DataHandler <- order.ClassificationError{ + Exchange: e.Name, OrderID: response.Data[x].OrderID, Err: err, } @@ -1268,7 +1268,7 @@ func (ok *Okx) wsProcessOrders(respRaw []byte) error { AverageExecutedPrice: avgPrice, ClientOrderID: response.Data[x].ClientOrderID, Date: response.Data[x].CreationTime.Time(), - Exchange: ok.Name, + Exchange: e.Name, ExecutedAmount: execAmount, Fee: 0.0 - response.Data[x].Fee.Float64(), FeeAsset: response.Data[x].FeeCurrency, @@ -1287,13 +1287,13 @@ func (ok *Okx) wsProcessOrders(respRaw []byte) error { d.Amount = d.ExecutedAmount } } - ok.Websocket.DataHandler <- d + e.Websocket.DataHandler <- d } return nil } // wsProcessCandles handler to get a list of candlestick messages. -func (ok *Okx) wsProcessCandles(respRaw []byte) error { +func (e *Exchange) wsProcessCandles(respRaw []byte) error { if respRaw == nil { return common.ErrNilPointer } @@ -1316,7 +1316,7 @@ func (ok *Okx) wsProcessCandles(respRaw []byte) error { } assets = append(assets, assetType) } else { - assets, err = ok.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) + assets, err = e.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) if err != nil { return err } @@ -1324,11 +1324,11 @@ func (ok *Okx) wsProcessCandles(respRaw []byte) error { candleInterval := strings.TrimPrefix(response.Argument.Channel, candle) for i := range response.Data { for j := range assets { - ok.Websocket.DataHandler <- websocket.KlineData{ + e.Websocket.DataHandler <- websocket.KlineData{ Timestamp: time.UnixMilli(response.Data[i][0].Int64()), Pair: response.Argument.InstrumentID, AssetType: assets[j], - Exchange: ok.Name, + Exchange: e.Name, Interval: candleInterval, OpenPrice: response.Data[i][1].Float64(), ClosePrice: response.Data[i][4].Float64(), @@ -1342,7 +1342,7 @@ func (ok *Okx) wsProcessCandles(respRaw []byte) error { } // wsProcessTickers handles the trade ticker information. -func (ok *Okx) wsProcessTickers(data []byte) error { +func (e *Exchange) wsProcessTickers(data []byte) error { var response WSTickerResponse err := json.Unmarshal(data, &response) if err != nil { @@ -1357,7 +1357,7 @@ func (ok *Okx) wsProcessTickers(data []byte) error { } assets = append(assets, assetType) } else { - assets, err = ok.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) + assets, err = e.getAssetsFromInstrumentID(response.Argument.InstrumentID.String()) if err != nil { return err } @@ -1373,7 +1373,7 @@ func (ok *Okx) wsProcessTickers(data []byte) error { } for j := range assets { tickData := &ticker.Price{ - ExchangeName: ok.Name, + ExchangeName: e.Name, Open: response.Data[i].Open24H.Float64(), Volume: baseVolume, QuoteVolume: quoteVolume, @@ -1388,19 +1388,19 @@ func (ok *Okx) wsProcessTickers(data []byte) error { Pair: response.Data[i].InstrumentID, LastUpdated: response.Data[i].TickerDataGenerationTime.Time(), } - ok.Websocket.DataHandler <- tickData + e.Websocket.DataHandler <- tickData } } return nil } // generateSubscriptions returns a list of subscriptions from the configured subscriptions feature -func (ok *Okx) generateSubscriptions() (subscription.List, error) { - return ok.Features.Subscriptions.ExpandTemplates(ok) +func (e *Exchange) generateSubscriptions() (subscription.List, error) { + return e.Features.Subscriptions.ExpandTemplates(e) } // GetSubscriptionTemplate returns a subscription channel template -func (ok *Okx) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { +func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) { return template.New("master.tmpl").Funcs(template.FuncMap{ "channelName": channelName, "isSymbolChannel": isSymbolChannel, @@ -1410,7 +1410,7 @@ func (ok *Okx) GetSubscriptionTemplate(_ *subscription.Subscription) (*template. } // wsProcessBlockPublicTrades handles the recent block trades data by individual legs. -func (ok *Okx) wsProcessBlockPublicTrades(data []byte) error { +func (e *Exchange) wsProcessBlockPublicTrades(data []byte) error { var resp PublicBlockTrades err := json.Unmarshal(data, &resp) if err != nil { @@ -1419,7 +1419,7 @@ func (ok *Okx) wsProcessBlockPublicTrades(data []byte) error { trades := make([]trade.Data, len(resp.Data)) for i := range resp.Data { var pair currency.Pair - pair, err = ok.GetPairFromInstrumentID(resp.Data[i].InstrumentID) + pair, err = e.GetPairFromInstrumentID(resp.Data[i].InstrumentID) if err != nil { return err } @@ -1431,7 +1431,7 @@ func (ok *Okx) wsProcessBlockPublicTrades(data []byte) error { Amount: resp.Data[i].Size.Float64(), AssetType: asset.Options, CurrencyPair: pair, - Exchange: ok.Name, + Exchange: e.Name, Side: oSide, Timestamp: resp.Data[i].Timestamp.Time(), TID: resp.Data[i].TradeID, @@ -1441,12 +1441,12 @@ func (ok *Okx) wsProcessBlockPublicTrades(data []byte) error { return trade.AddTradesToBuffer(trades...) } -func (ok *Okx) wsProcessBalanceAndPosition(ctx context.Context, data []byte) error { +func (e *Exchange) wsProcessBalanceAndPosition(ctx context.Context, data []byte) error { var resp WsBalanceAndPosition if err := json.Unmarshal(data, &resp); err != nil { return err } - creds, err := ok.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return err } @@ -1466,16 +1466,16 @@ func (ok *Okx) wsProcessBalanceAndPosition(ctx context.Context, data []byte) err } // TODO: Handle position data } - ok.Websocket.DataHandler <- changes - return account.ProcessChange(ok.Name, changes, creds) + e.Websocket.DataHandler <- changes + return account.ProcessChange(e.Name, changes, creds) } // wsProcessPushData processes push data coming through the websocket channel -func (ok *Okx) wsProcessPushData(data []byte, resp any) error { +func (e *Exchange) wsProcessPushData(data []byte, resp any) error { if err := json.Unmarshal(data, resp); err != nil { return err } - ok.Websocket.DataHandler <- resp + e.Websocket.DataHandler <- resp return nil } diff --git a/exchanges/okx/okx_wrapper.go b/exchanges/okx/okx_wrapper.go index 61aba2592ff..498dff32b09 100644 --- a/exchanges/okx/okx_wrapper.go +++ b/exchanges/okx/okx_wrapper.go @@ -40,16 +40,16 @@ const ( ) // SetDefaults sets the basic defaults for Okx -func (ok *Okx) SetDefaults() { - ok.Name = "Okx" - ok.Enabled = true - ok.Verbose = true +func (e *Exchange) SetDefaults() { + e.Name = "Okx" + e.Enabled = true + e.Verbose = true - ok.API.CredentialsValidator.RequiresKey = true - ok.API.CredentialsValidator.RequiresSecret = true - ok.API.CredentialsValidator.RequiresClientID = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true + e.API.CredentialsValidator.RequiresClientID = true - ok.instrumentsInfoMap = make(map[string][]Instrument) + e.instrumentsInfoMap = make(map[string][]Instrument) cpf := ¤cy.PairFormat{ Delimiter: currency.DashDelimiter, @@ -57,18 +57,18 @@ func (ok *Okx) SetDefaults() { } // In this exchange, we represent deliverable futures contracts as 'FUTURES'/asset.Futures and perpetual futures as 'SWAP'/asset.PerpetualSwap - err := ok.SetGlobalPairsManager(cpf, cpf, asset.Spot, asset.Futures, asset.PerpetualSwap, asset.Options, asset.Margin, asset.Spread) + err := e.SetGlobalPairsManager(cpf, cpf, asset.Spot, asset.Futures, asset.PerpetualSwap, asset.Options, asset.Margin, asset.Spread) if err != nil { log.Errorln(log.ExchangeSys, err) } // TODO: Disabled until spread/business websocket is implemented - if err := ok.DisableAssetWebsocketSupport(asset.Spread); err != nil { - log.Errorf(log.ExchangeSys, "%s error disabling %q asset websocket support: %s", ok.Name, asset.Spread.String(), err) + if err := e.DisableAssetWebsocketSupport(asset.Spread); err != nil { + log.Errorf(log.ExchangeSys, "%s error disabling %q asset websocket support: %s", e.Name, asset.Spread.String(), err) } // Fill out the capabilities/features that the exchange supports - ok.Features = exchange.Features{ + e.Features = exchange.Features{ CurrencyTranslations: currency.NewTranslations(map[currency.Code]currency.Code{ currency.NewCode("USDT-SWAP"): currency.USDT, currency.NewCode("USD-SWAP"): currency.USD, @@ -164,15 +164,15 @@ func (ok *Okx) SetDefaults() { }, Subscriptions: defaultSubscriptions.Clone(), } - ok.Requester, err = request.New(ok.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(rateLimits)) if err != nil { log.Errorln(log.ExchangeSys, err) } - ok.API.Endpoints = ok.NewEndpoints() - err = ok.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: apiURL, exchange.WebsocketSpot: apiWebsocketPublicURL, }) @@ -180,79 +180,79 @@ func (ok *Okx) SetDefaults() { log.Errorln(log.ExchangeSys, err) } - ok.Websocket = websocket.NewManager() - ok.WebsocketResponseMaxLimit = websocketResponseMaxLimit - ok.WebsocketResponseCheckTimeout = websocketResponseMaxLimit - ok.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = websocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = websocketResponseMaxLimit + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup takes in the supplied exchange configuration details and sets params -func (ok *Okx) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { if err := exch.Validate(); err != nil { return err } if !exch.Enabled { - ok.SetEnabled(false) + e.SetEnabled(false) return nil } - if err := ok.SetupDefaults(exch); err != nil { + if err := e.SetupDefaults(exch); err != nil { return err } - wsRunningEndpoint, err := ok.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningEndpoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - if err := ok.Websocket.Setup(&websocket.ManagerSetup{ + if err := e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: apiWebsocketPublicURL, RunningURL: wsRunningEndpoint, - Connector: ok.WsConnect, - Subscriber: ok.Subscribe, - Unsubscriber: ok.Unsubscribe, - GenerateSubscriptions: ok.generateSubscriptions, - Features: &ok.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.generateSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, MaxWebsocketSubscriptionsPerConnection: 240, RateLimitDefinitions: rateLimits, }); err != nil { return err } - if err := ok.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + if err := e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: apiWebsocketPublicURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: websocketResponseMaxLimit, RateLimit: request.NewRateLimitWithWeight(time.Second, 2, 1), - BespokeGenerateMessageID: func(bool) int64 { return ok.messageIDSeq.IncrementAndGet() }, + BespokeGenerateMessageID: func(bool) int64 { return e.messageIDSeq.IncrementAndGet() }, }); err != nil { return err } - return ok.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ URL: apiWebsocketPrivateURL, ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: websocketResponseMaxLimit, Authenticated: true, RateLimit: request.NewRateLimitWithWeight(time.Second, 2, 1), - BespokeGenerateMessageID: func(bool) int64 { return ok.messageIDSeq.IncrementAndGet() }, + BespokeGenerateMessageID: func(bool) int64 { return e.messageIDSeq.IncrementAndGet() }, }) } // GetServerTime returns the current exchange server time. -func (ok *Okx) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - t, err := ok.GetSystemTime(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + t, err := e.GetSystemTime(ctx) return t.Time(), err } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (ok *Okx) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) { switch a { case asset.Options, asset.Futures, asset.Spot, asset.PerpetualSwap, asset.Margin: - format, err := ok.GetPairFormat(a, true) + format, err := e.GetPairFormat(a, true) if err != nil { return nil, err } - insts, err := ok.getInstrumentsForAsset(ctx, a) + insts, err := e.getInstrumentsForAsset(ctx, a) if err != nil { return nil, err } @@ -265,11 +265,11 @@ func (ok *Okx) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.P } return pairs, nil case asset.Spread: - format, err := ok.GetPairFormat(a, true) + format, err := e.GetPairFormat(a, true) if err != nil { return nil, err } - spreadInstruments, err := ok.GetPublicSpreads(ctx, "", "", "", "live") + spreadInstruments, err := e.GetPublicSpreads(ctx, "", "", "", "live") if err != nil { return nil, fmt.Errorf("%w asset type: %v", err, a) } @@ -284,27 +284,27 @@ func (ok *Okx) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.P } // UpdateTradablePairs updates the exchanges available pairs and stores them in the exchanges config -func (ok *Okx) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - assetTypes := ok.GetAssetTypes(true) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + assetTypes := e.GetAssetTypes(true) for i := range assetTypes { - pairs, err := ok.FetchTradablePairs(ctx, assetTypes[i]) + pairs, err := e.FetchTradablePairs(ctx, assetTypes[i]) if err != nil { return fmt.Errorf("%w for asset %v", err, assetTypes[i]) } - err = ok.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) + err = e.UpdatePairs(pairs, assetTypes[i], false, forceUpdate) if err != nil { return fmt.Errorf("%w for asset %v", err, assetTypes[i]) } } - return ok.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateOrderExecutionLimits sets exchange execution order limits for an asset type -func (ok *Okx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { switch a { case asset.Spot, asset.Margin, asset.Options, asset.PerpetualSwap, asset.Futures: - insts, err := ok.getInstrumentsForAsset(ctx, a) + insts, err := e.getInstrumentsForAsset(ctx, a) if err != nil { return err } @@ -320,9 +320,9 @@ func (ok *Okx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) err MinimumBaseAmount: insts[x].MinimumOrderSize.Float64(), } } - return ok.LoadLimits(limits) + return e.LoadLimits(limits) case asset.Spread: - insts, err := ok.GetPublicSpreads(ctx, "", "", "", "live") + insts, err := e.GetPublicSpreads(ctx, "", "", "", "live") if err != nil { return err } @@ -339,25 +339,25 @@ func (ok *Okx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) err QuoteStepIncrementSize: insts[x].TickSize.Float64(), } } - return ok.LoadLimits(limits) + return e.LoadLimits(limits) default: return fmt.Errorf("%w %v", asset.ErrNotSupported, a) } } // UpdateTicker updates and returns the ticker for a currency pair -func (ok *Okx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if !ok.SupportsAsset(a) { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, a) } - p, err := ok.FormatExchangeCurrency(p, a) + p, err := e.FormatExchangeCurrency(p, a) if err != nil { return nil, err } if a == asset.Spread { - spreadTicker, err := ok.GetPublicSpreadTickers(ctx, p.String()) + spreadTicker, err := e.GetPublicSpreadTickers(ctx, p.String()) if err != nil { return nil, err } @@ -379,12 +379,12 @@ func (ok *Okx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) LastUpdated: spreadTicker[0].Timestamp.Time(), Pair: p, AssetType: a, - ExchangeName: ok.Name, + ExchangeName: e.Name, }); err != nil { return nil, err } } else { - mdata, err := ok.GetTicker(ctx, p.String()) + mdata, err := e.GetTicker(ctx, p.String()) if err != nil { return nil, err } @@ -409,31 +409,31 @@ func (ok *Okx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) QuoteVolume: quoteVolume, Open: mdata.Open24H.Float64(), Pair: p, - ExchangeName: ok.Name, + ExchangeName: e.Name, AssetType: a, }); err != nil { return nil, err } } - return ticker.GetTicker(ok.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateTickers updates all currency pairs of a given asset type -func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { +func (e *Exchange) UpdateTickers(ctx context.Context, assetType asset.Item) error { switch assetType { case asset.Spread: - format, err := ok.GetPairFormat(asset.Spread, true) + format, err := e.GetPairFormat(asset.Spread, true) if err != nil { return err } - pairs, err := ok.GetEnabledPairs(assetType) + pairs, err := e.GetEnabledPairs(assetType) if err != nil { return err } for y := range pairs { var spreadTickers []SpreadTicker - spreadTickers, err = ok.GetPublicSpreadTickers(ctx, format.Format(pairs[y])) + spreadTickers, err = e.GetPublicSpreadTickers(ctx, format.Format(pairs[y])) if err != nil { return err } @@ -449,7 +449,7 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { Ask: spreadTickers[x].AskPrice.Float64(), AskSize: spreadTickers[x].AskSize.Float64(), Pair: pair, - ExchangeName: ok.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { @@ -458,7 +458,7 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { } } case asset.Spot, asset.PerpetualSwap, asset.Futures, asset.Options, asset.Margin: - pairs, err := ok.GetEnabledPairs(assetType) + pairs, err := e.GetEnabledPairs(assetType) if err != nil { return err } @@ -467,18 +467,18 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { if assetType == asset.Margin { instrumentType = instTypeSpot } - ticks, err := ok.GetTickers(ctx, instrumentType, "", "") + ticks, err := e.GetTickers(ctx, instrumentType, "", "") if err != nil { return err } for y := range ticks { - pair, err := ok.GetPairFromInstrumentID(ticks[y].InstrumentID.String()) + pair, err := e.GetPairFromInstrumentID(ticks[y].InstrumentID.String()) if err != nil { return err } for i := range pairs { - pairFmt, err := ok.FormatExchangeCurrency(pairs[i], assetType) + pairFmt, err := e.FormatExchangeCurrency(pairs[i], assetType) if err != nil { return err } @@ -497,7 +497,7 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { QuoteVolume: ticks[y].VolCcy24H.Float64(), Open: ticks[y].Open24H.Float64(), Pair: pairFmt, - ExchangeName: ok.Name, + ExchangeName: e.Name, AssetType: assetType, }) if err != nil { @@ -512,7 +512,7 @@ func (ok *Okx) UpdateTickers(ctx context.Context, assetType asset.Item) error { } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } @@ -523,20 +523,20 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp pairFormat currency.PairFormat spreadOrderbook []SpreadOrderbook ) - pairFormat, err = ok.GetPairFormat(assetType, true) + pairFormat, err = e.GetPairFormat(assetType, true) if err != nil { return nil, err } - spreadOrderbook, err = ok.GetPublicSpreadOrderBooks(ctx, pairFormat.Format(pair), 50) + spreadOrderbook, err = e.GetPublicSpreadOrderBooks(ctx, pairFormat.Format(pair), 50) if err != nil { return nil, err } for y := range spreadOrderbook { book := &orderbook.Book{ - Exchange: ok.Name, + Exchange: e.Name, Pair: pair, Asset: assetType, - ValidateOrderbook: ok.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } book.Bids = make(orderbook.Levels, 0, len(spreadOrderbook[y].Bids)) for b := range spreadOrderbook[y].Bids { @@ -568,12 +568,12 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp } } case asset.Spot, asset.Options, asset.Margin, asset.PerpetualSwap, asset.Futures: - err = ok.CurrencyPairs.IsAssetEnabled(assetType) + err = e.CurrencyPairs.IsAssetEnabled(assetType) if err != nil { return nil, err } var instrumentID string - pairFormat, err := ok.GetPairFormat(assetType, true) + pairFormat, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -582,13 +582,13 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp } instrumentID = pairFormat.Format(pair) book := &orderbook.Book{ - Exchange: ok.Name, + Exchange: e.Name, Pair: pair, Asset: assetType, - ValidateOrderbook: ok.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } var orderBookD *OrderBookResponseDetail - orderBookD, err = ok.GetOrderBookDepth(ctx, instrumentID, 400) + orderBookD, err = e.GetOrderBookDepth(ctx, instrumentID, 400) if err != nil { return book, err } @@ -614,22 +614,22 @@ func (ok *Okx) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetTyp default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - return orderbook.Get(ok.Name, pair, assetType) + return orderbook.Get(e.Name, pair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies. -func (ok *Okx) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { - if err := ok.CurrencyPairs.IsAssetEnabled(assetType); err != nil { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return account.Holdings{}, err } var info account.Holdings var acc account.SubAccount - info.Exchange = ok.Name - if !ok.SupportsAsset(assetType) { + info.Exchange = e.Name + if !e.SupportsAsset(assetType) { return info, fmt.Errorf("%w: %v", asset.ErrNotSupported, assetType) } - accountBalances, err := ok.AccountBalance(ctx, currency.EMPTYCODE) + accountBalances, err := e.AccountBalance(ctx, currency.EMPTYCODE) if err != nil { return info, err } @@ -647,7 +647,7 @@ func (ok *Okx) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc acc.Currencies = currencyBalances acc.AssetType = assetType info.Accounts = append(info.Accounts, acc) - creds, err := ok.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return info, err } @@ -658,20 +658,20 @@ func (ok *Okx) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (acc } // GetAccountFundingHistory returns funding history, deposits and withdrawals -func (ok *Okx) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { - depositHistories, err := ok.GetCurrencyDepositHistory(ctx, currency.EMPTYCODE, "", "", "", "", time.Time{}, time.Time{}, -1, 0) +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { + depositHistories, err := e.GetCurrencyDepositHistory(ctx, currency.EMPTYCODE, "", "", "", "", time.Time{}, time.Time{}, -1, 0) if err != nil { return nil, err } - withdrawalHistories, err := ok.GetWithdrawalHistory(ctx, currency.EMPTYCODE, "", "", "", "", time.Time{}, time.Time{}, -5) + withdrawalHistories, err := e.GetWithdrawalHistory(ctx, currency.EMPTYCODE, "", "", "", "", time.Time{}, time.Time{}, -5) if err != nil { return nil, err } resp := make([]exchange.FundingHistory, 0, len(depositHistories)+len(withdrawalHistories)) for x := range depositHistories { resp = append(resp, exchange.FundingHistory{ - ExchangeName: ok.Name, + ExchangeName: e.Name, Status: strconv.FormatInt(depositHistories[x].State.Int64(), 10), Timestamp: depositHistories[x].Timestamp.Time(), Currency: depositHistories[x].Currency, @@ -683,7 +683,7 @@ func (ok *Okx) GetAccountFundingHistory(ctx context.Context) ([]exchange.Funding } for x := range withdrawalHistories { resp = append(resp, exchange.FundingHistory{ - ExchangeName: ok.Name, + ExchangeName: e.Name, Status: withdrawalHistories[x].StateOfWithdrawal, Timestamp: withdrawalHistories[x].Timestamp.Time(), Currency: withdrawalHistories[x].Currency, @@ -700,8 +700,8 @@ func (ok *Okx) GetAccountFundingHistory(ctx context.Context) ([]exchange.Funding } // GetWithdrawalsHistory returns previous withdrawals data -func (ok *Okx) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { - withdrawals, err := ok.GetWithdrawalHistory(ctx, c, "", "", "", "", time.Time{}, time.Time{}, -5) +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { + withdrawals, err := e.GetWithdrawalHistory(ctx, c, "", "", "", "", time.Time{}, time.Time{}, -5) if err != nil { return nil, err } @@ -724,8 +724,8 @@ func (ok *Okx) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ ass } // GetRecentTrades returns the most recent trades for a currency and asset -func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - format, err := ok.GetPairFormat(assetType, true) +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + format, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -733,7 +733,7 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a switch assetType { case asset.Spread: var spreadTrades []SpreadPublicTradeItem - spreadTrades, err = ok.GetPublicSpreadTrades(ctx, "") + spreadTrades, err = e.GetPublicSpreadTrades(ctx, "") if err != nil { return nil, err } @@ -746,7 +746,7 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a } resp[x] = trade.Data{ TID: spreadTrades[x].TradeID, - Exchange: ok.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: oSide, @@ -761,7 +761,7 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a } instrumentID := format.Format(p) var tradeData []TradeResponse - tradeData, err = ok.GetTrades(ctx, instrumentID, 1000) + tradeData, err = e.GetTrades(ctx, instrumentID, 1000) if err != nil { return nil, err } @@ -770,7 +770,7 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a for x := range tradeData { resp[x] = trade.Data{ TID: tradeData[x].TradeID, - Exchange: ok.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Side: tradeData[x].Side, @@ -782,7 +782,7 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a default: return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } - if ok.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err = trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -793,8 +793,8 @@ func (ok *Okx) GetRecentTrades(ctx context.Context, p currency.Pair, assetType a } // GetHistoricTrades retrieves historic trade data within the timeframe provided -func (ok *Okx) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { - if !ok.SupportsAsset(assetType) || assetType == asset.Spread { +func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { + if !e.SupportsAsset(assetType) || assetType == asset.Spread { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, assetType) } @@ -802,7 +802,7 @@ func (ok *Okx) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType return nil, errOnlyThreeMonthsSupported } const limit = 100 - pairFormat, err := ok.GetPairFormat(assetType, true) + pairFormat, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -815,7 +815,7 @@ func (ok *Okx) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType allTrades: for { var trades []TradeResponse - trades, err = ok.GetTradesHistory(ctx, instrumentID, "", tradeIDEnd, limit) + trades, err = e.GetTradesHistory(ctx, instrumentID, "", tradeIDEnd, limit) if err != nil { return nil, err } @@ -831,7 +831,7 @@ allTrades: } resp = append(resp, trade.Data{ TID: trades[i].TradeID, - Exchange: ok.Name, + Exchange: e.Name, CurrencyPair: p, AssetType: assetType, Price: trades[i].Price.Float64(), @@ -842,7 +842,7 @@ allTrades: } tradeIDEnd = trades[len(trades)-1].TradeID } - if ok.IsSaveTradeDataEnabled() { + if e.IsSaveTradeDataEnabled() { err = trade.AddTradesToBuffer(resp...) if err != nil { return nil, err @@ -853,14 +853,14 @@ allTrades: } // SubmitOrder submits a new order -func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if !ok.SupportsAsset(s.AssetType) { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if !e.SupportsAsset(s.AssetType) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, s.AssetType) } if s.Amount <= 0 { return nil, order.ErrAmountBelowMin } - pairFormat, err := ok.GetPairFormat(s.AssetType, true) + pairFormat, err := e.GetPairFormat(s.AssetType, true) if err != nil { return nil, err } @@ -868,7 +868,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR return nil, currency.ErrCurrencyPairEmpty } pairString := pairFormat.Format(s.Pair) - tradeMode := ok.marginTypeToString(s.MarginType) + tradeMode := e.marginTypeToString(s.MarginType) if s.AssetType.IsFutures() && s.Leverage != 0 && s.Leverage != 1 { return nil, fmt.Errorf("%w received '%v'", order.ErrSubmitLeverageNotSupported, s.Leverage) } @@ -899,13 +899,13 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR Price: s.Price, } var placeSpreadOrderResponse *SpreadOrderResponse - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - placeSpreadOrderResponse, err = ok.WSPlaceSpreadOrder(ctx, spreadParam) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + placeSpreadOrderResponse, err = e.WSPlaceSpreadOrder(ctx, spreadParam) if err != nil { return nil, err } } else { - placeSpreadOrderResponse, err = ok.PlaceSpreadOrder(ctx, spreadParam) + placeSpreadOrderResponse, err = e.PlaceSpreadOrder(ctx, spreadParam) if err != nil { return nil, err } @@ -947,17 +947,17 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR orderRequest.PositionSide = positionSideShort } } - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - placeOrderResponse, err = ok.WSPlaceOrder(ctx, orderRequest) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + placeOrderResponse, err = e.WSPlaceOrder(ctx, orderRequest) } else { - placeOrderResponse, err = ok.PlaceOrder(ctx, orderRequest) + placeOrderResponse, err = e.PlaceOrder(ctx, orderRequest) } if err != nil { return nil, err } return s.DeriveSubmitResponse(placeOrderResponse.OrderID) case orderTrigger: - result, err = ok.PlaceTriggerAlgoOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceTriggerAlgoOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: s.Side.Lower(), @@ -970,7 +970,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR }) case orderConditional: // Trigger Price and type are used as a stop losss trigger price and type. - result, err = ok.PlaceTakeProfitStopLossOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceTakeProfitStopLossOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: s.Side.Lower(), @@ -989,7 +989,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR if s.TrackingValue == 0 { return nil, fmt.Errorf("%w, tracking value required", order.ErrAmountBelowMin) } - result, err = ok.PlaceChaseAlgoOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceChaseAlgoOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: s.Side.Lower(), @@ -1011,7 +1011,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR case order.Percentage: callbackRatio = s.TrackingValue } - result, err = ok.PlaceTrailingStopOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceTrailingStopOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: sideType, @@ -1034,7 +1034,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR case order.Percentage: priceVar = s.TrackingValue } - result, err = ok.PlaceTWAPOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceTWAPOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: sideType, @@ -1055,7 +1055,7 @@ func (ok *Okx) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitR case s.RiskManagementModes.StopLoss.Price <= 0: return nil, fmt.Errorf("%w, stop loss price is required", order.ErrPriceBelowMin) } - result, err = ok.PlaceAlgoOrder(ctx, &AlgoOrderParams{ + result, err = e.PlaceAlgoOrder(ctx, &AlgoOrderParams{ InstrumentID: pairString, TradeMode: tradeMode, Side: sideType, @@ -1096,7 +1096,7 @@ func priceTypeString(pt order.PriceType) string { var allowedMarginTypes = margin.Isolated | margin.NoMargin | margin.SpotIsolated -func (ok *Okx) marginTypeToString(m margin.Type) string { +func (e *Exchange) marginTypeToString(m margin.Type) string { if allowedMarginTypes&m == m { return m.String() } else if margin.Multi == m { @@ -1106,7 +1106,7 @@ func (ok *Okx) marginTypeToString(m margin.Type) string { } // ModifyOrder will allow of changing orderbook placement and limit to market conversion -func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } @@ -1122,10 +1122,10 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo NewSize: action.Amount, NewPrice: action.Price, } - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - _, err = ok.WSAmendSpreadOrder(ctx, amendSpreadOrder) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + _, err = e.WSAmendSpreadOrder(ctx, amendSpreadOrder) } else { - _, err = ok.AmendSpreadOrder(ctx, amendSpreadOrder) + _, err = e.AmendSpreadOrder(ctx, amendSpreadOrder) } if err != nil { return nil, err @@ -1134,7 +1134,7 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo } // For other asset type instances. - pairFormat, err := ok.GetPairFormat(action.AssetType, true) + pairFormat, err := e.GetPairFormat(action.AssetType, true) if err != nil { return nil, err } @@ -1149,10 +1149,10 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo OrderID: action.OrderID, ClientOrderID: action.ClientOrderID, } - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - _, err = ok.WSAmendOrder(ctx, &amendRequest) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + _, err = e.WSAmendOrder(ctx, &amendRequest) } else { - _, err = ok.AmendOrder(ctx, &amendRequest) + _, err = e.AmendOrder(ctx, &amendRequest) } if err != nil { return nil, err @@ -1174,7 +1174,7 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo }, } } - _, err = ok.AmendAlgoOrder(ctx, &AmendAlgoOrderParam{ + _, err = e.AmendAlgoOrder(ctx, &AmendAlgoOrderParam{ InstrumentID: pairFormat.Format(action.Pair), AlgoID: action.OrderID, ClientSuppliedAlgoOrderID: action.ClientOrderID, @@ -1199,7 +1199,7 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo action.RiskManagementModes.StopLoss.LimitPrice <= 0: return nil, fmt.Errorf("%w, either stop loss trigger price or order price is required", order.ErrPriceBelowMin) } - _, err = ok.AmendAlgoOrder(ctx, &AmendAlgoOrderParam{ + _, err = e.AmendAlgoOrder(ctx, &AmendAlgoOrderParam{ InstrumentID: pairFormat.Format(action.Pair), AlgoID: action.OrderID, ClientSuppliedAlgoOrderID: action.ClientOrderID, @@ -1224,20 +1224,20 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo } // CancelOrder cancels an order by its corresponding ID number -func (ok *Okx) CancelOrder(ctx context.Context, ord *order.Cancel) error { - if !ok.SupportsAsset(ord.AssetType) { +func (e *Exchange) CancelOrder(ctx context.Context, ord *order.Cancel) error { + if !e.SupportsAsset(ord.AssetType) { return fmt.Errorf("%w: %v", asset.ErrNotSupported, ord.AssetType) } var err error if ord.AssetType == asset.Spread { - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - _, err = ok.WSCancelSpreadOrder(ctx, ord.OrderID, ord.ClientOrderID) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + _, err = e.WSCancelSpreadOrder(ctx, ord.OrderID, ord.ClientOrderID) } else { - _, err = ok.CancelSpreadOrder(ctx, ord.OrderID, ord.ClientOrderID) + _, err = e.CancelSpreadOrder(ctx, ord.OrderID, ord.ClientOrderID) } return err } - pairFormat, err := ok.GetPairFormat(ord.AssetType, true) + pairFormat, err := e.GetPairFormat(ord.AssetType, true) if err != nil { return err } @@ -1252,14 +1252,14 @@ func (ok *Okx) CancelOrder(ctx context.Context, ord *order.Cancel) error { OrderID: ord.OrderID, ClientOrderID: ord.ClientOrderID, } - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - _, err = ok.WSCancelOrder(ctx, &req) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + _, err = e.WSCancelOrder(ctx, &req) } else { - _, err = ok.CancelSingleOrder(ctx, &req) + _, err = e.CancelSingleOrder(ctx, &req) } case order.Trigger, order.OCO, order.ConditionalStop, order.TWAP, order.TrailingStop, order.Chase: var response *AlgoOrder - response, err = ok.CancelAdvanceAlgoOrder(ctx, []AlgoOrderCancelParams{ + response, err = e.CancelAdvanceAlgoOrder(ctx, []AlgoOrderCancelParams{ { AlgoOrderID: ord.OrderID, InstrumentID: instrumentID, @@ -1276,7 +1276,7 @@ func (ok *Okx) CancelOrder(ctx context.Context, ord *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) > 20 { return nil, fmt.Errorf("%w, cannot cancel more than 20 orders", errExceedLimit) } else if len(o) == 0 { @@ -1287,11 +1287,11 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order. var err error for x := range o { ord := o[x] - if !ok.SupportsAsset(ord.AssetType) { + if !e.SupportsAsset(ord.AssetType) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, ord.AssetType) } var pairFormat currency.PairFormat - pairFormat, err = ok.GetPairFormat(ord.AssetType, true) + pairFormat, err = e.GetPairFormat(ord.AssetType, true) if err != nil { return nil, err } @@ -1324,10 +1324,10 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order. resp := &order.CancelBatchResponse{Status: make(map[string]string)} if len(cancelOrderParams) > 0 { var canceledOrders []*OrderData - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - canceledOrders, err = ok.WSCancelMultipleOrders(ctx, cancelOrderParams) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + canceledOrders, err = e.WSCancelMultipleOrders(ctx, cancelOrderParams) } else { - canceledOrders, err = ok.CancelMultipleOrders(ctx, cancelOrderParams) + canceledOrders, err = e.CancelMultipleOrders(ctx, cancelOrderParams) } if err != nil { return nil, err @@ -1342,7 +1342,7 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order. } } if len(cancelAlgoOrderParams) > 0 { - cancelationResponse, err := ok.CancelAdvanceAlgoOrder(ctx, cancelAlgoOrderParams) + cancelationResponse, err := e.CancelAdvanceAlgoOrder(ctx, cancelAlgoOrderParams) if err != nil { if len(resp.Status) > 0 { return resp, nil @@ -1362,7 +1362,7 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order. } // CancelAllOrders cancels all orders associated with a currency pair -func (ok *Okx) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { err := orderCancellation.Validate() if err != nil { return order.CancelAllResponse{}, err @@ -1374,7 +1374,7 @@ func (ok *Okx) CancelAllOrders(ctx context.Context, orderCancellation *order.Can // For asset.Spread asset orders cancellation if orderCancellation.AssetType == asset.Spread { var success bool - success, err = ok.CancelAllSpreadOrders(ctx, orderCancellation.OrderID) + success, err = e.CancelAllSpreadOrders(ctx, orderCancellation.OrderID) if err != nil { return cancelAllResponse, err } @@ -1384,7 +1384,7 @@ func (ok *Okx) CancelAllOrders(ctx context.Context, orderCancellation *order.Can var instrumentType string if orderCancellation.AssetType.IsValid() { - err = ok.CurrencyPairs.IsAssetEnabled(orderCancellation.AssetType) + err = e.CurrencyPairs.IsAssetEnabled(orderCancellation.AssetType) if err != nil { return order.CancelAllResponse{}, err } @@ -1401,7 +1401,7 @@ func (ok *Okx) CancelAllOrders(ctx context.Context, orderCancellation *order.Can if orderCancellation.Pair.IsPopulated() { curr = orderCancellation.Pair.Upper().String() } - myOrders, err := ok.GetOrderList(ctx, &OrderListRequestParams{ + myOrders, err := e.GetOrderList(ctx, &OrderListRequestParams{ InstrumentType: instrumentType, OrderType: oType, InstrumentID: curr, @@ -1442,17 +1442,17 @@ ordersLoop: for range loop { var response []*OrderData if len(remaining) > 20 { - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - response, err = ok.WSCancelMultipleOrders(ctx, remaining[:20]) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + response, err = e.WSCancelMultipleOrders(ctx, remaining[:20]) } else { - response, err = ok.CancelMultipleOrders(ctx, remaining[:20]) + response, err = e.CancelMultipleOrders(ctx, remaining[:20]) } remaining = remaining[20:] } else { - if ok.Websocket.CanUseAuthenticatedWebsocketForWrapper() { - response, err = ok.WSCancelMultipleOrders(ctx, remaining) + if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() { + response, err = e.WSCancelMultipleOrders(ctx, remaining) } else { - response, err = ok.CancelMultipleOrders(ctx, remaining) + response, err = e.CancelMultipleOrders(ctx, remaining) } } if err != nil { @@ -1472,13 +1472,13 @@ ordersLoop: } // GetOrderInfo returns order information based on order ID -func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { - if !ok.SupportsAsset(assetType) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { + if !e.SupportsAsset(assetType) { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, assetType) } if assetType == asset.Spread { var resp *SpreadOrder - resp, err := ok.GetSpreadOrderDetails(ctx, orderID, "") + resp, err := e.GetSpreadOrderDetails(ctx, orderID, "") if err != nil { return nil, err } @@ -1503,7 +1503,7 @@ func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.P } return &order.Detail{ Amount: resp.Size.Float64(), - Exchange: ok.Name, + Exchange: e.Name, OrderID: resp.OrderID, ClientOrderID: resp.ClientOrderID, Side: oSide, @@ -1523,10 +1523,10 @@ func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.P if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := ok.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } - pairFormat, err := ok.GetPairFormat(assetType, false) + pairFormat, err := e.GetPairFormat(assetType, false) if err != nil { return nil, err } @@ -1534,7 +1534,7 @@ func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.P return nil, currency.ErrCurrencyPairsEmpty } instrumentID := pairFormat.Format(pair) - orderDetail, err := ok.GetOrderDetail(ctx, &OrderDetailRequestParam{ + orderDetail, err := e.GetOrderDetail(ctx, &OrderDetailRequestParam{ InstrumentID: instrumentID, OrderID: orderID, }) @@ -1552,7 +1552,7 @@ func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.P return &order.Detail{ Amount: orderDetail.Size.Float64(), - Exchange: ok.Name, + Exchange: e.Name, OrderID: orderDetail.OrderID, ClientOrderID: orderDetail.ClientOrderID, Side: orderDetail.Side, @@ -1570,8 +1570,8 @@ func (ok *Okx) GetOrderInfo(ctx context.Context, orderID string, pair currency.P } // GetDepositAddress returns a deposit address for a specified currency -func (ok *Okx) GetDepositAddress(ctx context.Context, c currency.Code, _, chain string) (*deposit.Address, error) { - response, err := ok.GetCurrencyDepositAddress(ctx, c) +func (e *Exchange) GetDepositAddress(ctx context.Context, c currency.Code, _, chain string) (*deposit.Address, error) { + response, err := e.GetCurrencyDepositAddress(ctx, c) if err != nil { return nil, err } @@ -1607,7 +1607,7 @@ func (ok *Okx) GetDepositAddress(ctx context.Context, c currency.Code, _, chain } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (ok *Okx) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -1619,7 +1619,7 @@ func (ok *Okx) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest TransactionFee: withdrawRequest.Crypto.FeeAmount, WithdrawalDestination: "3", } - resp, err := ok.Withdrawal(ctx, &input) + resp, err := e.Withdrawal(ctx, &input) if err != nil { return nil, err } @@ -1630,17 +1630,17 @@ func (ok *Okx) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (ok *Okx) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted -func (ok *Okx) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (ok *Okx) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -1648,7 +1648,7 @@ func (ok *Okx) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest if !req.StartTime.IsZero() && req.StartTime.Before(time.Now().Add(-kline.ThreeMonth.Duration())) { return nil, errOnlyThreeMonthsSupported } - if !ok.SupportsAsset(req.AssetType) { + if !e.SupportsAsset(req.AssetType) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, req.AssetType) } @@ -1656,12 +1656,12 @@ func (ok *Okx) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest var format currency.PairFormat if req.AssetType == asset.Spread { var spreads []SpreadOrder - spreads, err = ok.GetActiveSpreadOrders(ctx, "", req.Type.String(), "", req.FromOrderID, "", 0) + spreads, err = e.GetActiveSpreadOrders(ctx, "", req.Type.String(), "", req.FromOrderID, "", 0) if err != nil { return nil, err } for x := range spreads { - format, err = ok.GetPairFormat(asset.Spread, true) + format, err = e.GetPairFormat(asset.Spread, true) if err != nil { return nil, err } @@ -1694,7 +1694,7 @@ func (ok *Okx) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest Price: spreads[x].Price.Float64(), ExecutedAmount: spreads[x].FillSize.Float64(), RemainingAmount: spreads[x].Size.Float64() - spreads[x].FillSize.Float64(), - Exchange: ok.Name, + Exchange: e.Name, OrderID: spreads[x].OrderID, ClientOrderID: spreads[x].ClientOrderID, Type: oType, @@ -1705,7 +1705,7 @@ func (ok *Okx) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest LastUpdated: spreads[x].UpdateTime.Time(), }) } - return req.Filter(ok.Name, resp), nil + return req.Filter(e.Name, resp), nil } instrumentType := GetInstrumentTypeFromAssetItem(req.AssetType) @@ -1725,7 +1725,7 @@ allOrders: InstrumentType: instrumentType, } var orderList []OrderDetail - orderList, err = ok.GetOrderList(ctx, requestParam) + orderList, err = e.GetOrderList(ctx, requestParam) if err != nil { return nil, err } @@ -1771,7 +1771,7 @@ allOrders: RemainingAmount: orderList[i].Size.Float64() - orderList[i].FillSize.Float64(), Fee: orderList[i].TransactionFee.Float64(), FeeAsset: currency.NewCode(orderList[i].FeeCurrency), - Exchange: ok.Name, + Exchange: e.Name, OrderID: orderList[i].OrderID, ClientOrderID: orderList[i].ClientOrderID, Type: oType, @@ -1791,18 +1791,18 @@ allOrders: } endTime = orderList[len(orderList)-1].CreationTime.Time() } - return req.Filter(ok.Name, resp), nil + return req.Filter(e.Name, resp), nil } // GetOrderHistory retrieves account order information Can Limit response to specific order status -func (ok *Okx) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { if err := req.Validate(); err != nil { return nil, err } if !req.StartTime.IsZero() && req.StartTime.Before(time.Now().Add(-kline.ThreeMonth.Duration())) { return nil, errOnlyThreeMonthsSupported } - if !ok.SupportsAsset(req.AssetType) { + if !e.SupportsAsset(req.AssetType) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, req.AssetType) } var resp []order.Detail @@ -1812,13 +1812,13 @@ func (ok *Okx) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest if err != nil { return nil, err } - spreadOrders, err := ok.GetCompletedSpreadOrdersLast7Days(ctx, "", oType, "", req.FromOrderID, "", req.StartTime, req.EndTime, 0) + spreadOrders, err := e.GetCompletedSpreadOrdersLast7Days(ctx, "", oType, "", req.FromOrderID, "", req.StartTime, req.EndTime, 0) if err != nil { return nil, err } for x := range spreadOrders { var format currency.PairFormat - format, err = ok.GetPairFormat(asset.Spread, true) + format, err = e.GetPairFormat(asset.Spread, true) if err != nil { return nil, err } @@ -1845,7 +1845,7 @@ func (ok *Okx) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest Amount: spreadOrders[x].Size.Float64(), ExecutedAmount: spreadOrders[x].FillSize.Float64(), RemainingAmount: spreadOrders[x].PendingFillSize.Float64(), - Exchange: ok.Name, + Exchange: e.Name, OrderID: spreadOrders[x].OrderID, ClientOrderID: spreadOrders[x].ClientOrderID, Type: oType, @@ -1857,7 +1857,7 @@ func (ok *Okx) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest Pair: pair, }) } - return req.Filter(ok.Name, resp), nil + return req.Filter(e.Name, resp), nil } if len(req.Pairs) == 0 { @@ -1867,7 +1867,7 @@ func (ok *Okx) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest endTime := req.EndTime allOrders: for { - orderList, err := ok.Get3MonthOrderHistory(ctx, &OrderHistoryRequestParams{ + orderList, err := e.Get3MonthOrderHistory(ctx, &OrderHistoryRequestParams{ OrderListRequestParams: OrderListRequestParams{ InstrumentType: instrumentType, End: endTime, @@ -1896,7 +1896,7 @@ allOrders: } orderStatus, err := order.StringToOrderStatus(strings.ToUpper(orderList[i].State)) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", ok.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } if orderStatus == order.Active { continue @@ -1923,7 +1923,7 @@ allOrders: RemainingAmount: remainingAmount, Fee: orderList[i].TransactionFee.Float64(), FeeAsset: currency.NewCode(orderList[i].FeeCurrency), - Exchange: ok.Name, + Exchange: e.Name, OrderID: orderList[i].OrderID, ClientOrderID: orderList[i].ClientOrderID, Type: oType, @@ -1944,33 +1944,33 @@ allOrders: } endTime = orderList[len(orderList)-1].CreationTime.Time() } - return req.Filter(ok.Name, resp), nil + return req.Filter(e.Name, resp), nil } // GetFeeByType returns an estimate of fee based on the type of transaction -func (ok *Okx) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !ok.AreCredentialsValid(ctx) && feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { + if !e.AreCredentialsValid(ctx) && feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return ok.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // ValidateAPICredentials validates current credentials used for wrapper -func (ok *Okx) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := ok.UpdateAccountInfo(ctx, assetType) - return ok.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (ok *Okx) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - if !ok.SupportsAsset(a) { +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, a) } - req, err := ok.GetKlineRequest(pair, a, interval, start, end, false) + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } @@ -1978,7 +1978,7 @@ func (ok *Okx) GetHistoricCandles(ctx context.Context, pair currency.Pair, a ass var timeSeries []kline.Candle switch a { case asset.Spread: - candles, err := ok.GetSpreadCandlesticksHistory(ctx, req.RequestFormatted.String(), req.ExchangeInterval, start.Add(-time.Nanosecond), end, 100) + candles, err := e.GetSpreadCandlesticksHistory(ctx, req.RequestFormatted.String(), req.ExchangeInterval, start.Add(-time.Nanosecond), end, 100) if err != nil { return nil, err } @@ -1994,7 +1994,7 @@ func (ok *Okx) GetHistoricCandles(ctx context.Context, pair currency.Pair, a ass } } default: - candles, err := ok.GetCandlesticksHistory(ctx, + candles, err := e.GetCandlesticksHistory(ctx, req.RequestFormatted.String(), req.ExchangeInterval, start.Add(-time.Nanosecond), // Start time not inclusive of candle. @@ -2021,12 +2021,12 @@ func (ok *Okx) GetHistoricCandles(ctx context.Context, pair currency.Pair, a ass } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (ok *Okx) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - if !ok.SupportsAsset(a) { +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, a) } - req, err := ok.GetKlineExtendedRequest(pair, a, interval, start, end) + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } @@ -2042,7 +2042,7 @@ func (ok *Okx) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pai for y := range req.RangeHolder.Ranges { switch a { case asset.Spread: - candles, err := ok.GetSpreadCandlesticksHistory(ctx, + candles, err := e.GetSpreadCandlesticksHistory(ctx, req.RequestFormatted.String(), req.ExchangeInterval, req.RangeHolder.Ranges[y].Start.Time.Add(-time.Nanosecond), // Start time not inclusive of candle. @@ -2062,7 +2062,7 @@ func (ok *Okx) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pai }) } default: - candles, err := ok.GetCandlesticksHistory(ctx, + candles, err := e.GetCandlesticksHistory(ctx, req.RequestFormatted.String(), req.ExchangeInterval, req.RangeHolder.Ranges[y].Start.Time.Add(-time.Nanosecond), // Start time not inclusive of candle. @@ -2086,10 +2086,9 @@ func (ok *Okx) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pai return req.ProcessResponse(timeSeries) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (ok *Okx) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - currencyChains, err := ok.GetFundingCurrencies(ctx, cryptocurrency) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + currencyChains, err := e.GetFundingCurrencies(ctx, cryptocurrency) if err != nil { return nil, err } @@ -2110,15 +2109,15 @@ func (ok *Okx) GetAvailableTransferChains(ctx context.Context, cryptocurrency cu } // getInstrumentsForOptions returns the instruments for options asset type -func (ok *Okx) getInstrumentsForOptions(ctx context.Context) ([]Instrument, error) { - underlyings, err := ok.GetPublicUnderlyings(ctx, instTypeOption) +func (e *Exchange) getInstrumentsForOptions(ctx context.Context) ([]Instrument, error) { + underlyings, err := e.GetPublicUnderlyings(ctx, instTypeOption) if err != nil { return nil, err } var insts []Instrument for x := range underlyings { var instruments []Instrument - instruments, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{ + instruments, err = e.GetInstruments(ctx, &InstrumentsFetchParams{ InstrumentType: instTypeOption, Underlying: underlyings[x], }) @@ -2131,8 +2130,8 @@ func (ok *Okx) getInstrumentsForOptions(ctx context.Context) ([]Instrument, erro } // getInstrumentsForAsset returns the instruments for an asset type -func (ok *Okx) getInstrumentsForAsset(ctx context.Context, a asset.Item) ([]Instrument, error) { - if !ok.SupportsAsset(a) { +func (e *Exchange) getInstrumentsForAsset(ctx context.Context, a asset.Item) ([]Instrument, error) { + if !e.SupportsAsset(a) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, a) } @@ -2141,13 +2140,13 @@ func (ok *Okx) getInstrumentsForAsset(ctx context.Context, a asset.Item) ([]Inst var err error switch a { case asset.Options: - instruments, err = ok.getInstrumentsForOptions(ctx) + instruments, err = e.getInstrumentsForOptions(ctx) if err != nil { return nil, err } - ok.instrumentsInfoMapLock.Lock() - ok.instrumentsInfoMap[instTypeOption] = instruments - ok.instrumentsInfoMapLock.Unlock() + e.instrumentsInfoMapLock.Lock() + e.instrumentsInfoMap[instTypeOption] = instruments + e.instrumentsInfoMapLock.Unlock() return instruments, nil case asset.Spot: instType = instTypeSpot @@ -2159,20 +2158,20 @@ func (ok *Okx) getInstrumentsForAsset(ctx context.Context, a asset.Item) ([]Inst instType = instTypeMargin } - instruments, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{ + instruments, err = e.GetInstruments(ctx, &InstrumentsFetchParams{ InstrumentType: instType, }) if err != nil { return nil, err } - ok.instrumentsInfoMapLock.Lock() - ok.instrumentsInfoMap[instType] = instruments - ok.instrumentsInfoMapLock.Unlock() + e.instrumentsInfoMapLock.Lock() + e.instrumentsInfoMap[instType] = instruments + e.instrumentsInfoMapLock.Unlock() return instruments, nil } // GetLatestFundingRates returns the latest funding rates data -func (ok *Okx) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { if r == nil { return nil, fmt.Errorf("%w LatestRateRequest", common.ErrNilPointer) } @@ -2182,25 +2181,25 @@ func (ok *Okx) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR if r.Pair.IsEmpty() { return nil, fmt.Errorf("%w, pair required", currency.ErrCurrencyPairEmpty) } - format, err := ok.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } fPair := r.Pair.Format(format) pairRate := fundingrate.LatestRateResponse{ TimeChecked: time.Now(), - Exchange: ok.Name, + Exchange: e.Name, Asset: r.Asset, Pair: fPair, } - fr, err := ok.GetSingleFundingRate(ctx, fPair.String()) + fr, err := e.GetSingleFundingRate(ctx, fPair.String()) if err != nil { return nil, err } var fri time.Duration - if len(ok.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { + if len(e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined - for k := range ok.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { + for k := range e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { fri = k.Duration() } } @@ -2220,13 +2219,13 @@ func (ok *Okx) GetLatestFundingRates(ctx context.Context, r *fundingrate.LatestR } // GetHistoricalFundingRates returns funding rates for a given asset and currency for a time period -func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { +func (e *Exchange) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.HistoricalRatesRequest) (*fundingrate.HistoricalRates, error) { if r == nil { return nil, fmt.Errorf("%w HistoricalRatesRequest", common.ErrNilPointer) } requestLimit := 100 sd := r.StartDate - maxLookback := time.Now().Add(-ok.Features.Supports.FuturesCapabilities.MaximumFundingRateHistory) + maxLookback := time.Now().Add(-e.Features.Supports.FuturesCapabilities.MaximumFundingRateHistory) if r.StartDate.Before(maxLookback) { if r.RespectHistoryLimits { r.StartDate = maxLookback @@ -2238,13 +2237,13 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His } r.StartDate = maxLookback } - format, err := ok.GetPairFormat(r.Asset, true) + format, err := e.GetPairFormat(r.Asset, true) if err != nil { return nil, err } fPair := r.Pair.Format(format) pairRate := fundingrate.HistoricalRates{ - Exchange: ok.Name, + Exchange: e.Name, Asset: r.Asset, Pair: fPair, StartDate: r.StartDate, @@ -2254,7 +2253,7 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His mti := make(map[int64]int) for sd.Before(r.EndDate) { var frh []FundingRateResponse - frh, err = ok.GetFundingRateHistory(ctx, fPair.String(), sd, r.EndDate, int64(requestLimit)) + frh, err = e.GetFundingRateHistory(ctx, fPair.String(), sd, r.EndDate, int64(requestLimit)) if err != nil { return nil, err } @@ -2276,7 +2275,7 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His sd = frh[len(frh)-1].FundingTime.Time() } var fr *FundingRateResponse - fr, err = ok.GetSingleFundingRate(ctx, fPair.String()) + fr, err = e.GetSingleFundingRate(ctx, fPair.String()) if err != nil { return nil, err } @@ -2300,15 +2299,15 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His pairRate.PaymentCurrency = r.PaymentCurrency } sd = r.StartDate - billDetailsFunc := ok.GetBillsDetail3Months + billDetailsFunc := e.GetBillsDetail3Months if time.Since(r.StartDate) < kline.OneWeek.Duration() { - billDetailsFunc = ok.GetBillsDetailLast7Days + billDetailsFunc = e.GetBillsDetailLast7Days } for sd.Before(r.EndDate) { var fri time.Duration - if len(ok.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { + if len(e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined - for k := range ok.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { + for k := range e.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies { fri = k.Duration() } } @@ -2344,27 +2343,27 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His } // IsPerpetualFutureCurrency ensures a given asset and currency is a perpetual future -func (ok *Okx) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { +func (e *Exchange) IsPerpetualFutureCurrency(a asset.Item, _ currency.Pair) (bool, error) { return a == asset.PerpetualSwap, nil } // SetMarginType sets the default margin type for when opening a new position // okx allows this to be set with an order, however this sets a default -func (ok *Okx) SetMarginType(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type) error { +func (e *Exchange) SetMarginType(_ context.Context, _ asset.Item, _ currency.Pair, _ margin.Type) error { return fmt.Errorf("%w margin type is set per order", common.ErrFunctionNotSupported) } // SetCollateralMode sets the collateral type for your account -func (ok *Okx) SetCollateralMode(_ context.Context, _ asset.Item, _ collateral.Mode) error { +func (e *Exchange) SetCollateralMode(_ context.Context, _ asset.Item, _ collateral.Mode) error { return fmt.Errorf("%w must be set via website", common.ErrFunctionNotSupported) } // GetCollateralMode returns the collateral type for your account -func (ok *Okx) GetCollateralMode(ctx context.Context, item asset.Item) (collateral.Mode, error) { - if !ok.SupportsAsset(item) { +func (e *Exchange) GetCollateralMode(ctx context.Context, item asset.Item) (collateral.Mode, error) { + if !e.SupportsAsset(item) { return 0, fmt.Errorf("%w: %v", asset.ErrNotSupported, item) } - cfg, err := ok.GetAccountConfiguration(ctx) + cfg, err := e.GetAccountConfiguration(ctx) if err != nil { return 0, err } @@ -2386,11 +2385,11 @@ func (ok *Okx) GetCollateralMode(ctx context.Context, item asset.Item) (collater } // ChangePositionMargin will modify a position/currencies margin parameters -func (ok *Okx) ChangePositionMargin(ctx context.Context, req *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { +func (e *Exchange) ChangePositionMargin(ctx context.Context, req *margin.PositionChangeRequest) (*margin.PositionChangeResponse, error) { if req == nil { return nil, fmt.Errorf("%w PositionChangeRequest", common.ErrNilPointer) } - if !ok.SupportsAsset(req.Asset) { + if !e.SupportsAsset(req.Asset) { return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, req.Asset) } if req.NewAllocatedMargin == 0 { @@ -2402,7 +2401,7 @@ func (ok *Okx) ChangePositionMargin(ctx context.Context, req *margin.PositionCha if req.MarginType != margin.Isolated { return nil, fmt.Errorf("%w %v", margin.ErrMarginTypeUnsupported, req.MarginType) } - pairFormat, err := ok.GetPairFormat(req.Asset, true) + pairFormat, err := e.GetPairFormat(req.Asset, true) if err != nil { return nil, err } @@ -2427,12 +2426,12 @@ func (ok *Okx) ChangePositionMargin(ctx context.Context, req *margin.PositionCha r.Currency = req.Pair.Base.Item.Symbol } - resp, err := ok.IncreaseDecreaseMargin(ctx, r) + resp, err := e.IncreaseDecreaseMargin(ctx, r) if err != nil { return nil, err } return &margin.PositionChangeResponse{ - Exchange: ok.Name, + Exchange: e.Name, Pair: req.Pair, Asset: req.Asset, AllocatedMargin: resp.Amount.Float64(), @@ -2441,24 +2440,24 @@ func (ok *Okx) ChangePositionMargin(ctx context.Context, req *margin.PositionCha } // GetFuturesPositionSummary returns position summary details for an active position -func (ok *Okx) GetFuturesPositionSummary(ctx context.Context, req *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { +func (e *Exchange) GetFuturesPositionSummary(ctx context.Context, req *futures.PositionSummaryRequest) (*futures.PositionSummary, error) { if req == nil { return nil, fmt.Errorf("%w PositionSummaryRequest", common.ErrNilPointer) } if req.CalculateOffline { return nil, common.ErrCannotCalculateOffline } - if !ok.SupportsAsset(req.Asset) || !req.Asset.IsFutures() { + if !e.SupportsAsset(req.Asset) || !req.Asset.IsFutures() { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, req.Asset) } - fPair, err := ok.FormatExchangeCurrency(req.Pair, req.Asset) + fPair, err := e.FormatExchangeCurrency(req.Pair, req.Asset) if err != nil { return nil, err } instrumentType := GetInstrumentTypeFromAssetItem(req.Asset) var contracts []futures.Contract - contracts, err = ok.GetFuturesContractDetails(ctx, req.Asset) + contracts, err = e.GetFuturesContractDetails(ctx, req.Asset) if err != nil { return nil, err } @@ -2473,7 +2472,7 @@ func (ok *Okx) GetFuturesPositionSummary(ctx context.Context, req *futures.Posit break } - positionSummaries, err := ok.GetPositions(ctx, instrumentType, fPair.String(), "") + positionSummaries, err := e.GetPositions(ctx, instrumentType, fPair.String(), "") if err != nil { return nil, err } @@ -2493,7 +2492,7 @@ func (ok *Okx) GetFuturesPositionSummary(ctx context.Context, req *futures.Posit marginMode = margin.Multi } - acc, err := ok.AccountBalance(ctx, currency.EMPTYCODE) + acc, err := e.AccountBalance(ctx, currency.EMPTYCODE) if err != nil { return nil, err } @@ -2527,7 +2526,7 @@ func (ok *Okx) GetFuturesPositionSummary(ctx context.Context, req *futures.Posit break } - collateralMode, err := ok.GetCollateralMode(ctx, req.Asset) + collateralMode, err := e.GetCollateralMode(ctx, req.Asset) if err != nil { return nil, err } @@ -2571,18 +2570,18 @@ func (ok *Okx) GetFuturesPositionSummary(ctx context.Context, req *futures.Posit } // GetFuturesPositionOrders returns the orders for futures positions -func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.PositionsRequest) ([]futures.PositionResponse, error) { +func (e *Exchange) GetFuturesPositionOrders(ctx context.Context, req *futures.PositionsRequest) ([]futures.PositionResponse, error) { if req == nil { return nil, fmt.Errorf("%w PositionSummaryRequest", common.ErrNilPointer) } - if !ok.SupportsAsset(req.Asset) || !req.Asset.IsFutures() { + if !e.SupportsAsset(req.Asset) || !req.Asset.IsFutures() { return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, req.Asset) } - if time.Since(req.StartDate) > ok.Features.Supports.MaximumOrderHistory { + if time.Since(req.StartDate) > e.Features.Supports.MaximumOrderHistory { if req.RespectOrderHistoryLimits { - req.StartDate = time.Now().Add(-ok.Features.Supports.MaximumOrderHistory) + req.StartDate = time.Now().Add(-e.Features.Supports.MaximumOrderHistory) } else { - return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-ok.Features.Supports.MaximumOrderHistory)) + return nil, fmt.Errorf("%w max lookup %v", futures.ErrOrderHistoryTooLarge, time.Now().Add(-e.Features.Supports.MaximumOrderHistory)) } } err := common.StartEndTimeCheck(req.StartDate, req.EndDate) @@ -2591,7 +2590,7 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi } resp := make([]futures.PositionResponse, len(req.Pairs)) var contracts []futures.Contract - contracts, err = ok.GetFuturesContractDetails(ctx, req.Asset) + contracts, err = e.GetFuturesContractDetails(ctx, req.Asset) if err != nil { return nil, err } @@ -2600,7 +2599,7 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi contractsMap[contracts[i].Name] = &contracts[i] } for i := range req.Pairs { - fPair, err := ok.FormatExchangeCurrency(req.Pairs[i], req.Asset) + fPair, err := e.FormatExchangeCurrency(req.Pairs[i], req.Asset) if err != nil { return nil, err } @@ -2629,9 +2628,9 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi }, } if time.Since(req.StartDate) <= time.Hour*24*7 { - positions, err = ok.Get7DayOrderHistory(ctx, historyRequest) + positions, err = e.Get7DayOrderHistory(ctx, historyRequest) } else { - positions, err = ok.Get3MonthOrderHistory(ctx, historyRequest) + positions, err = e.Get3MonthOrderHistory(ctx, historyRequest) } if err != nil { return nil, err @@ -2642,7 +2641,7 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi } orderStatus, err := order.StringToOrderStatus(strings.ToUpper(positions[j].State)) if err != nil { - log.Errorf(log.ExchangeSys, "%s %v", ok.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } oType, tif, err := orderTypeFromString(positions[j].OrderType) if err != nil { @@ -2671,7 +2670,7 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi RemainingAmount: remainingAmount, Fee: positions[j].TransactionFee.Float64(), FeeAsset: currency.NewCode(positions[j].FeeCurrency), - Exchange: ok.Name, + Exchange: e.Name, OrderID: positions[j].OrderID, ClientOrderID: positions[j].ClientOrderID, Type: oType, @@ -2691,7 +2690,7 @@ func (ok *Okx) GetFuturesPositionOrders(ctx context.Context, req *futures.Positi } // SetLeverage sets the account's initial leverage for the asset type and pair -func (ok *Okx) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, marginType margin.Type, amount float64, orderSide order.Side) error { +func (e *Exchange) SetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, marginType margin.Type, amount float64, orderSide order.Side) error { posSide := "net" switch item { case asset.Futures, asset.PerpetualSwap: @@ -2709,13 +2708,13 @@ func (ok *Okx) SetLeverage(ctx context.Context, item asset.Item, pair currency.P } fallthrough case asset.Margin, asset.Options: - instrumentID, err := ok.FormatSymbol(pair, item) + instrumentID, err := e.FormatSymbol(pair, item) if err != nil { return err } - marginMode := ok.marginTypeToString(marginType) - _, err = ok.SetLeverageRate(ctx, &SetLeverageInput{ + marginMode := e.marginTypeToString(marginType) + _, err = e.SetLeverageRate(ctx, &SetLeverageInput{ Leverage: amount, MarginMode: marginMode, InstrumentID: instrumentID, @@ -2728,7 +2727,7 @@ func (ok *Okx) SetLeverage(ctx context.Context, item asset.Item, pair currency.P } // GetLeverage gets the account's initial leverage for the asset type and pair -func (ok *Okx) GetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, marginType margin.Type, orderSide order.Side) (float64, error) { +func (e *Exchange) GetLeverage(ctx context.Context, item asset.Item, pair currency.Pair, marginType margin.Type, orderSide order.Side) (float64, error) { var inspectLeverage bool switch item { case asset.Futures, asset.PerpetualSwap: @@ -2744,12 +2743,12 @@ func (ok *Okx) GetLeverage(ctx context.Context, item asset.Item, pair currency.P } fallthrough case asset.Margin, asset.Options: - instrumentID, err := ok.FormatSymbol(pair, item) + instrumentID, err := e.FormatSymbol(pair, item) if err != nil { return -1, err } - marginMode := ok.marginTypeToString(marginType) - lev, err := ok.GetLeverageRate(ctx, instrumentID, marginMode, currency.EMPTYCODE) + marginMode := e.marginTypeToString(marginType) + lev, err := e.GetLeverageRate(ctx, instrumentID, marginMode, currency.EMPTYCODE) if err != nil { return -1, err } @@ -2772,14 +2771,14 @@ func (ok *Okx) GetLeverage(ctx context.Context, item asset.Item, pair currency.P } // GetFuturesContractDetails returns details about futures contracts -func (ok *Okx) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) { if !item.IsFutures() { return nil, futures.ErrNotFuturesAsset } switch item { case asset.Futures, asset.PerpetualSwap: instType := GetInstrumentTypeFromAssetItem(item) - result, err := ok.GetInstruments(ctx, &InstrumentsFetchParams{ + result, err := e.GetInstruments(ctx, &InstrumentsFetchParams{ InstrumentType: instType, }) if err != nil { @@ -2820,7 +2819,7 @@ func (ok *Okx) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( } resp[i] = futures.Contract{ - Exchange: ok.Name, + Exchange: e.Name, Name: result[i].InstrumentID, Underlying: underlying, Asset: item, @@ -2841,7 +2840,7 @@ func (ok *Okx) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( } return resp, nil case asset.Spread: - results, err := ok.GetPublicSpreads(ctx, "", "", "", "") + results, err := e.GetPublicSpreads(ctx, "", "", "", "") if err != nil { return nil, err } @@ -2852,7 +2851,7 @@ func (ok *Okx) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( return nil, err } resp[s] = futures.Contract{ - Exchange: ok.Name, + Exchange: e.Name, Name: results[s].SpreadID, Asset: asset.Spread, StartDate: results[s].ListTime.Time(), @@ -2871,7 +2870,7 @@ func (ok *Okx) GetFuturesContractDetails(ctx context.Context, item asset.Item) ( } // GetOpenInterest returns the open interest rate for a given asset pair -func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { +func (e *Exchange) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futures.OpenInterest, error) { for i := range k { switch k[i].Asset { case asset.Futures, asset.PerpetualSwap, asset.Options: @@ -2894,13 +2893,13 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur switch instType { case instTypeOption: var underlyings []string - underlyings, err = ok.GetPublicUnderlyings(ctx, instTypeOption) + underlyings, err = e.GetPublicUnderlyings(ctx, instTypeOption) if err != nil { return nil, err } for u := range underlyings { var incOID []OpenInterest - incOID, err = ok.GetOpenInterestData(ctx, instType, underlyings[u], "", "") + incOID, err = e.GetOpenInterestData(ctx, instType, underlyings[u], "", "") if err != nil { return nil, err } @@ -2908,7 +2907,7 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } case instTypeSwap, instTypeFutures: - oid, err = ok.GetOpenInterestData(ctx, instType, "", "", "") + oid, err = e.GetOpenInterestData(ctx, instType, "", "", "") if err != nil { return nil, err } @@ -2916,7 +2915,7 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur for j := range oid { var isEnabled bool var p currency.Pair - p, isEnabled, err = ok.MatchSymbolCheckEnabled(oid[j].InstrumentID, v, true) + p, isEnabled, err = e.MatchSymbolCheckEnabled(oid[j].InstrumentID, v, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2935,7 +2934,7 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } resp = append(resp, futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: ok.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: v, @@ -2951,7 +2950,7 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur asset.PerpetualSwap: "SWAP", asset.Futures: "FUTURES", } - pFmt, err := ok.FormatSymbol(k[0].Pair(), k[0].Asset) + pFmt, err := e.FormatSymbol(k[0].Pair(), k[0].Asset) if err != nil { return nil, err } @@ -2959,26 +2958,26 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur switch instTypes[k[0].Asset] { case instTypeOption: var underlyings []string - underlyings, err = ok.GetPublicUnderlyings(ctx, instTypeOption) + underlyings, err = e.GetPublicUnderlyings(ctx, instTypeOption) if err != nil { return nil, err } for u := range underlyings { var incOID []OpenInterest - incOID, err = ok.GetOpenInterestData(ctx, instTypes[k[0].Asset], underlyings[u], "", "") + incOID, err = e.GetOpenInterestData(ctx, instTypes[k[0].Asset], underlyings[u], "", "") if err != nil { return nil, err } oid = append(oid, incOID...) } case instTypeSwap, instTypeFutures: - oid, err = ok.GetOpenInterestData(ctx, instTypes[k[0].Asset], "", "", pFmt) + oid, err = e.GetOpenInterestData(ctx, instTypes[k[0].Asset], "", "", pFmt) if err != nil { return nil, err } } for i := range oid { - p, isEnabled, err := ok.MatchSymbolCheckEnabled(oid[i].InstrumentID, k[0].Asset, true) + p, isEnabled, err := e.MatchSymbolCheckEnabled(oid[i].InstrumentID, k[0].Asset, true) if err != nil && !errors.Is(err, currency.ErrPairNotFound) { return nil, err } @@ -2987,7 +2986,7 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } resp[0] = futures.OpenInterest{ Key: key.ExchangePairAsset{ - Exchange: ok.Name, + Exchange: e.Name, Base: p.Base.Item, Quote: p.Quote.Item, Asset: k[0].Asset, @@ -2999,8 +2998,8 @@ func (ok *Okx) GetOpenInterest(ctx context.Context, k ...key.PairAsset) ([]futur } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (ok *Okx) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := ok.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } @@ -3017,11 +3016,11 @@ func (ok *Okx) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp currenc case asset.Spread: return baseURL, nil case asset.Futures: - cp, err = ok.FormatExchangeCurrency(cp, a) + cp, err = e.FormatExchangeCurrency(cp, a) if err != nil { return "", err } - insts, err := ok.GetInstruments(ctx, &InstrumentsFetchParams{ + insts, err := e.GetInstruments(ctx, &InstrumentsFetchParams{ InstrumentType: instTypeFutures, InstrumentID: cp.String(), }) diff --git a/exchanges/okx/ws_requests.go b/exchanges/okx/ws_requests.go index 73e7224f2f3..b4084e3c04d 100644 --- a/exchanges/okx/ws_requests.go +++ b/exchanges/okx/ws_requests.go @@ -23,22 +23,22 @@ var ( ) // WSPlaceOrder submits an order -func (ok *Okx) WSPlaceOrder(ctx context.Context, arg *PlaceOrderRequestParam) (*OrderData, error) { +func (e *Exchange) WSPlaceOrder(ctx context.Context, arg *PlaceOrderRequestParam) (*OrderData, error) { if err := arg.Validate(); err != nil { return nil, err } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - if err := ok.SendAuthenticatedWebsocketRequest(ctx, placeOrderEPL, id, "order", []PlaceOrderRequestParam{*arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, placeOrderEPL, id, "order", []PlaceOrderRequestParam{*arg}, &resp); err != nil { return nil, err } return singleItem(resp) } // WSPlaceMultipleOrders submits multiple orders -func (ok *Okx) WSPlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequestParam) ([]*OrderData, error) { +func (e *Exchange) WSPlaceMultipleOrders(ctx context.Context, args []PlaceOrderRequestParam) ([]*OrderData, error) { if len(args) == 0 { return nil, fmt.Errorf("%T: %w", args, order.ErrSubmissionIsNil) } @@ -49,14 +49,14 @@ func (ok *Okx) WSPlaceMultipleOrders(ctx context.Context, args []PlaceOrderReque } } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - return resp, ok.SendAuthenticatedWebsocketRequest(ctx, placeMultipleOrdersEPL, id, "batch-orders", args, &resp) + return resp, e.SendAuthenticatedWebsocketRequest(ctx, placeMultipleOrdersEPL, id, "batch-orders", args, &resp) } // WSCancelOrder cancels an order -func (ok *Okx) WSCancelOrder(ctx context.Context, arg *CancelOrderRequestParam) (*OrderData, error) { +func (e *Exchange) WSCancelOrder(ctx context.Context, arg *CancelOrderRequestParam) (*OrderData, error) { if arg == nil { return nil, fmt.Errorf("%T: %w", arg, common.ErrNilPointer) } @@ -67,10 +67,10 @@ func (ok *Okx) WSCancelOrder(ctx context.Context, arg *CancelOrderRequestParam) return nil, order.ErrOrderIDNotSet } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - if err := ok.SendAuthenticatedWebsocketRequest(ctx, cancelOrderEPL, id, "cancel-order", []CancelOrderRequestParam{*arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, cancelOrderEPL, id, "cancel-order", []CancelOrderRequestParam{*arg}, &resp); err != nil { return nil, err } @@ -78,7 +78,7 @@ func (ok *Okx) WSCancelOrder(ctx context.Context, arg *CancelOrderRequestParam) } // WSCancelMultipleOrders cancels multiple orders -func (ok *Okx) WSCancelMultipleOrders(ctx context.Context, args []CancelOrderRequestParam) ([]*OrderData, error) { +func (e *Exchange) WSCancelMultipleOrders(ctx context.Context, args []CancelOrderRequestParam) ([]*OrderData, error) { if len(args) == 0 { return nil, fmt.Errorf("%T: %w", args, order.ErrSubmissionIsNil) } @@ -92,14 +92,14 @@ func (ok *Okx) WSCancelMultipleOrders(ctx context.Context, args []CancelOrderReq } } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - return resp, ok.SendAuthenticatedWebsocketRequest(ctx, cancelMultipleOrdersEPL, id, "batch-cancel-orders", args, &resp) + return resp, e.SendAuthenticatedWebsocketRequest(ctx, cancelMultipleOrdersEPL, id, "batch-cancel-orders", args, &resp) } // WSAmendOrder amends an order -func (ok *Okx) WSAmendOrder(ctx context.Context, arg *AmendOrderRequestParams) (*OrderData, error) { +func (e *Exchange) WSAmendOrder(ctx context.Context, arg *AmendOrderRequestParams) (*OrderData, error) { if arg == nil { return nil, fmt.Errorf("%T: %w", arg, common.ErrNilPointer) } @@ -113,17 +113,17 @@ func (ok *Okx) WSAmendOrder(ctx context.Context, arg *AmendOrderRequestParams) ( return nil, errInvalidNewSizeOrPriceInformation } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - if err := ok.SendAuthenticatedWebsocketRequest(ctx, amendOrderEPL, id, "amend-order", []AmendOrderRequestParams{*arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, amendOrderEPL, id, "amend-order", []AmendOrderRequestParams{*arg}, &resp); err != nil { return nil, err } return singleItem(resp) } // WSAmendMultipleOrders amends multiple orders -func (ok *Okx) WSAmendMultipleOrders(ctx context.Context, args []AmendOrderRequestParams) ([]*OrderData, error) { +func (e *Exchange) WSAmendMultipleOrders(ctx context.Context, args []AmendOrderRequestParams) ([]*OrderData, error) { if len(args) == 0 { return nil, fmt.Errorf("%T: %w", args, order.ErrSubmissionIsNil) } @@ -140,14 +140,14 @@ func (ok *Okx) WSAmendMultipleOrders(ctx context.Context, args []AmendOrderReque } } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*OrderData - return resp, ok.SendAuthenticatedWebsocketRequest(ctx, amendMultipleOrdersEPL, id, "batch-amend-orders", args, &resp) + return resp, e.SendAuthenticatedWebsocketRequest(ctx, amendMultipleOrdersEPL, id, "batch-amend-orders", args, &resp) } // WSMassCancelOrders cancels all MMP pending orders of an instrument family. Only applicable to Option in Portfolio Margin mode, and MMP privilege is required. -func (ok *Okx) WSMassCancelOrders(ctx context.Context, args []CancelMassReqParam) error { +func (e *Exchange) WSMassCancelOrders(ctx context.Context, args []CancelMassReqParam) error { if len(args) == 0 { return fmt.Errorf("%T: %w", args, order.ErrSubmissionIsNil) } @@ -161,12 +161,12 @@ func (ok *Okx) WSMassCancelOrders(ctx context.Context, args []CancelMassReqParam } } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resps []*struct { Result bool `json:"result"` } - if err := ok.SendAuthenticatedWebsocketRequest(ctx, amendOrderEPL, id, "mass-cancel", args, &resps); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, amendOrderEPL, id, "mass-cancel", args, &resps); err != nil { return err } @@ -183,15 +183,15 @@ func (ok *Okx) WSMassCancelOrders(ctx context.Context, args []CancelMassReqParam } // WSPlaceSpreadOrder submits a spread order -func (ok *Okx) WSPlaceSpreadOrder(ctx context.Context, arg *SpreadOrderParam) (*SpreadOrderResponse, error) { +func (e *Exchange) WSPlaceSpreadOrder(ctx context.Context, arg *SpreadOrderParam) (*SpreadOrderResponse, error) { if err := arg.Validate(); err != nil { return nil, err } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*SpreadOrderResponse - if err := ok.SendAuthenticatedWebsocketRequest(ctx, placeSpreadOrderEPL, id, "sprd-order", []SpreadOrderParam{*arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, placeSpreadOrderEPL, id, "sprd-order", []SpreadOrderParam{*arg}, &resp); err != nil { return nil, err } @@ -199,7 +199,7 @@ func (ok *Okx) WSPlaceSpreadOrder(ctx context.Context, arg *SpreadOrderParam) (* } // WSAmendSpreadOrder amends a spread order -func (ok *Okx) WSAmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderParam) (*SpreadOrderResponse, error) { +func (e *Exchange) WSAmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderParam) (*SpreadOrderResponse, error) { if arg == nil { return nil, fmt.Errorf("%T: %w", arg, common.ErrNilPointer) } @@ -210,10 +210,10 @@ func (ok *Okx) WSAmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderPara return nil, errSizeOrPriceIsRequired } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*SpreadOrderResponse - if err := ok.SendAuthenticatedWebsocketRequest(ctx, amendSpreadOrderEPL, id, "sprd-amend-order", []AmendSpreadOrderParam{*arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, amendSpreadOrderEPL, id, "sprd-amend-order", []AmendSpreadOrderParam{*arg}, &resp); err != nil { return nil, err } @@ -221,7 +221,7 @@ func (ok *Okx) WSAmendSpreadOrder(ctx context.Context, arg *AmendSpreadOrderPara } // WSCancelSpreadOrder cancels an incomplete spread order through the websocket connection. -func (ok *Okx) WSCancelSpreadOrder(ctx context.Context, orderID, clientOrderID string) (*SpreadOrderResponse, error) { +func (e *Exchange) WSCancelSpreadOrder(ctx context.Context, orderID, clientOrderID string) (*SpreadOrderResponse, error) { if orderID == "" && clientOrderID == "" { return nil, order.ErrOrderIDNotSet } @@ -234,10 +234,10 @@ func (ok *Okx) WSCancelSpreadOrder(ctx context.Context, orderID, clientOrderID s arg["clOrdId"] = clientOrderID } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resp []*SpreadOrderResponse - if err := ok.SendAuthenticatedWebsocketRequest(ctx, cancelSpreadOrderEPL, id, "sprd-cancel-order", []map[string]string{arg}, &resp); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, cancelSpreadOrderEPL, id, "sprd-cancel-order", []map[string]string{arg}, &resp); err != nil { return nil, err } @@ -245,16 +245,16 @@ func (ok *Okx) WSCancelSpreadOrder(ctx context.Context, orderID, clientOrderID s } // WSCancelAllSpreadOrders cancels all spread orders and return success message through the websocket channel. -func (ok *Okx) WSCancelAllSpreadOrders(ctx context.Context, spreadID string) error { +func (e *Exchange) WSCancelAllSpreadOrders(ctx context.Context, spreadID string) error { arg := make(map[string]string, 1) if spreadID != "" { arg["sprdId"] = spreadID } - id := strconv.FormatInt(ok.Websocket.AuthConn.GenerateMessageID(false), 10) + id := strconv.FormatInt(e.Websocket.AuthConn.GenerateMessageID(false), 10) var resps []*ResponseResult - if err := ok.SendAuthenticatedWebsocketRequest(ctx, cancelAllSpreadOrderEPL, id, "sprd-mass-cancel", []map[string]string{arg}, &resps); err != nil { + if err := e.SendAuthenticatedWebsocketRequest(ctx, cancelAllSpreadOrderEPL, id, "sprd-mass-cancel", []map[string]string{arg}, &resps); err != nil { return err } @@ -271,7 +271,7 @@ func (ok *Okx) WSCancelAllSpreadOrders(ctx context.Context, spreadID string) err } // SendAuthenticatedWebsocketRequest sends a websocket request to the server -func (ok *Okx) SendAuthenticatedWebsocketRequest(ctx context.Context, epl request.EndpointLimit, id, operation string, payload, result any) error { +func (e *Exchange) SendAuthenticatedWebsocketRequest(ctx context.Context, epl request.EndpointLimit, id, operation string, payload, result any) error { if operation == "" || payload == nil { return errInvalidWebsocketRequest } @@ -289,7 +289,7 @@ func (ok *Okx) SendAuthenticatedWebsocketRequest(ctx context.Context, epl reques Arguments: payload, } - incoming, err := ok.Websocket.AuthConn.SendMessageReturnResponse(ctx, epl, id, outbound) + incoming, err := e.Websocket.AuthConn.SendMessageReturnResponse(ctx, epl, id, outbound) if err != nil { return err } diff --git a/exchanges/okx/ws_requests_test.go b/exchanges/okx/ws_requests_test.go index d65640a6895..48893d63ab9 100644 --- a/exchanges/okx/ws_requests_test.go +++ b/exchanges/okx/ws_requests_test.go @@ -16,12 +16,12 @@ import ( func TestWSPlaceOrder(t *testing.T) { t.Parallel() - _, err := ok.WSPlaceOrder(t.Context(), nil) + _, err := e.WSPlaceOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.SetupWs(t, ok) + testexch.SetupWs(t, e) out := &PlaceOrderRequestParam{ InstrumentID: mainPair.String(), @@ -33,7 +33,7 @@ func TestWSPlaceOrder(t *testing.T) { Currency: "USDT", } - got, err := ok.WSPlaceOrder(request.WithVerbose(t.Context()), out) + got, err := e.WSPlaceOrder(request.WithVerbose(t.Context()), out) require.NoError(t, err) require.NotEmpty(t, got) } @@ -41,15 +41,15 @@ func TestWSPlaceOrder(t *testing.T) { func TestWSPlaceMultipleOrders(t *testing.T) { t.Parallel() - _, err := ok.WSPlaceMultipleOrders(t.Context(), nil) + _, err := e.WSPlaceMultipleOrders(t.Context(), nil) require.ErrorIs(t, err, order.ErrSubmissionIsNil) - _, err = ok.WSPlaceMultipleOrders(t.Context(), []PlaceOrderRequestParam{{}}) + _, err = e.WSPlaceMultipleOrders(t.Context(), []PlaceOrderRequestParam{{}}) require.ErrorIs(t, err, errMissingInstrumentID) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.SetupWs(t, ok) + testexch.SetupWs(t, e) out := PlaceOrderRequestParam{ InstrumentID: mainPair.String(), @@ -61,7 +61,7 @@ func TestWSPlaceMultipleOrders(t *testing.T) { Currency: "USDT", } - got, err := ok.WSPlaceMultipleOrders(request.WithVerbose(t.Context()), []PlaceOrderRequestParam{out}) + got, err := e.WSPlaceMultipleOrders(request.WithVerbose(t.Context()), []PlaceOrderRequestParam{out}) require.NoError(t, err) require.NotEmpty(t, got) } @@ -69,20 +69,20 @@ func TestWSPlaceMultipleOrders(t *testing.T) { func TestWSCancelOrder(t *testing.T) { t.Parallel() - _, err := ok.WSCancelOrder(t.Context(), nil) + _, err := e.WSCancelOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ok.WSCancelOrder(t.Context(), &CancelOrderRequestParam{}) + _, err = e.WSCancelOrder(t.Context(), &CancelOrderRequestParam{}) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.WSCancelOrder(t.Context(), &CancelOrderRequestParam{InstrumentID: mainPair.String()}) + _, err = e.WSCancelOrder(t.Context(), &CancelOrderRequestParam{InstrumentID: mainPair.String()}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.SetupWs(t, ok) + testexch.SetupWs(t, e) - got, err := ok.WSCancelOrder(request.WithVerbose(t.Context()), &CancelOrderRequestParam{InstrumentID: mainPair.String(), OrderID: "2341161427393388544"}) + got, err := e.WSCancelOrder(request.WithVerbose(t.Context()), &CancelOrderRequestParam{InstrumentID: mainPair.String(), OrderID: "2341161427393388544"}) require.NoError(t, err) require.NotEmpty(t, got) } @@ -90,20 +90,20 @@ func TestWSCancelOrder(t *testing.T) { func TestWSCancelMultipleOrders(t *testing.T) { t.Parallel() - _, err := ok.WSCancelMultipleOrders(t.Context(), nil) + _, err := e.WSCancelMultipleOrders(t.Context(), nil) require.ErrorIs(t, err, order.ErrSubmissionIsNil) - _, err = ok.WSCancelMultipleOrders(t.Context(), []CancelOrderRequestParam{{}}) + _, err = e.WSCancelMultipleOrders(t.Context(), []CancelOrderRequestParam{{}}) require.ErrorIs(t, err, errMissingInstrumentID) - _, err = ok.WSCancelMultipleOrders(t.Context(), []CancelOrderRequestParam{{InstrumentID: mainPair.String()}}) + _, err = e.WSCancelMultipleOrders(t.Context(), []CancelOrderRequestParam{{InstrumentID: mainPair.String()}}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.SetupWs(t, ok) + testexch.SetupWs(t, e) - got, err := ok.WSCancelMultipleOrders(request.WithVerbose(t.Context()), []CancelOrderRequestParam{{InstrumentID: mainPair.String(), OrderID: "2341184920998715392"}}) + got, err := e.WSCancelMultipleOrders(request.WithVerbose(t.Context()), []CancelOrderRequestParam{{InstrumentID: mainPair.String(), OrderID: "2341184920998715392"}}) require.NoError(t, err) require.NotEmpty(t, got) } @@ -111,27 +111,27 @@ func TestWSCancelMultipleOrders(t *testing.T) { func TestWSAmendOrder(t *testing.T) { t.Parallel() - _, err := ok.WSAmendOrder(t.Context(), nil) + _, err := e.WSAmendOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) out := &AmendOrderRequestParams{} - _, err = ok.WSAmendOrder(t.Context(), out) + _, err = e.WSAmendOrder(t.Context(), out) require.ErrorIs(t, err, errMissingInstrumentID) out.InstrumentID = mainPair.String() - _, err = ok.WSAmendOrder(t.Context(), out) + _, err = e.WSAmendOrder(t.Context(), out) require.ErrorIs(t, err, order.ErrOrderIDNotSet) out.OrderID = "2341200629875154944" - _, err = ok.WSAmendOrder(t.Context(), out) + _, err = e.WSAmendOrder(t.Context(), out) require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) - testexch.SetupWs(t, ok) + testexch.SetupWs(t, e) out.NewPrice = 21000 - got, err := ok.WSAmendOrder(request.WithVerbose(t.Context()), out) + got, err := e.WSAmendOrder(request.WithVerbose(t.Context()), out) require.NoError(t, err) require.NotEmpty(t, got) } @@ -139,44 +139,44 @@ func TestWSAmendOrder(t *testing.T) { func TestWSAmendMultipleOrders(t *testing.T) { t.Parallel() - _, err := ok.WSAmendMultipleOrders(t.Context(), nil) + _, err := e.WSAmendMultipleOrders(t.Context(), nil) require.ErrorIs(t, err, order.ErrSubmissionIsNil) out := AmendOrderRequestParams{} - _, err = ok.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) + _, err = e.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) require.ErrorIs(t, err, errMissingInstrumentID) out.InstrumentID = mainPair.String() - _, err = ok.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) + _, err = e.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) out.OrderID = "2341200629875154944" - _, err = ok.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) + _, err = e.WSAmendMultipleOrders(t.Context(), []AmendOrderRequestParams{out}) require.ErrorIs(t, err, errInvalidNewSizeOrPriceInformation) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) out.NewPrice = 20000 - got, err := ok.WSAmendMultipleOrders(request.WithVerbose(t.Context()), []AmendOrderRequestParams{out}) + got, err := e.WSAmendMultipleOrders(request.WithVerbose(t.Context()), []AmendOrderRequestParams{out}) require.NoError(t, err) require.NotEmpty(t, got) } func TestWSMassCancelOrders(t *testing.T) { t.Parallel() - err := ok.WSMassCancelOrders(t.Context(), nil) + err := e.WSMassCancelOrders(t.Context(), nil) require.ErrorIs(t, err, order.ErrSubmissionIsNil) - err = ok.WSMassCancelOrders(t.Context(), []CancelMassReqParam{{}}) + err = e.WSMassCancelOrders(t.Context(), []CancelMassReqParam{{}}) require.ErrorIs(t, err, errInvalidInstrumentType) - err = ok.WSMassCancelOrders(t.Context(), []CancelMassReqParam{{InstrumentType: "OPTION"}}) + err = e.WSMassCancelOrders(t.Context(), []CancelMassReqParam{{InstrumentType: "OPTION"}}) require.ErrorIs(t, err, errInstrumentFamilyRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) - err = ok.WSMassCancelOrders(request.WithVerbose(t.Context()), []CancelMassReqParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err = e.WSMassCancelOrders(request.WithVerbose(t.Context()), []CancelMassReqParam{ { InstrumentType: "OPTION", InstrumentFamily: optionsPair.String(), @@ -187,12 +187,12 @@ func TestWSMassCancelOrders(t *testing.T) { func TestWSPlaceSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.WSPlaceSpreadOrder(t.Context(), nil) + _, err := e.WSPlaceSpreadOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) - result, err := ok.WSPlaceSpreadOrder(request.WithVerbose(t.Context()), &SpreadOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + result, err := e.WSPlaceSpreadOrder(request.WithVerbose(t.Context()), &SpreadOrderParam{ SpreadID: spreadPair.String(), ClientOrderID: "b15", Side: order.Buy.Lower(), @@ -206,16 +206,16 @@ func TestWSPlaceSpreadOrder(t *testing.T) { func TestWSAmendSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.WSAmendSpreadOrder(t.Context(), nil) + _, err := e.WSAmendSpreadOrder(t.Context(), nil) require.ErrorIs(t, err, common.ErrNilPointer) - _, err = ok.WSAmendSpreadOrder(t.Context(), &AmendSpreadOrderParam{NewSize: 2}) + _, err = e.WSAmendSpreadOrder(t.Context(), &AmendSpreadOrderParam{NewSize: 2}) require.ErrorIs(t, err, order.ErrOrderIDNotSet) - _, err = ok.WSAmendSpreadOrder(t.Context(), &AmendSpreadOrderParam{OrderID: "2510789768709120"}) + _, err = e.WSAmendSpreadOrder(t.Context(), &AmendSpreadOrderParam{OrderID: "2510789768709120"}) require.ErrorIs(t, err, errSizeOrPriceIsRequired) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) - result, err := ok.WSAmendSpreadOrder(request.WithVerbose(t.Context()), &AmendSpreadOrderParam{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + result, err := e.WSAmendSpreadOrder(request.WithVerbose(t.Context()), &AmendSpreadOrderParam{ OrderID: "2510789768709120", NewSize: 2, }) @@ -225,20 +225,20 @@ func TestWSAmendSpreadOrder(t *testing.T) { func TestWSCancelSpreadOrder(t *testing.T) { t.Parallel() - _, err := ok.WSCancelSpreadOrder(t.Context(), "", "") + _, err := e.WSCancelSpreadOrder(t.Context(), "", "") require.ErrorIs(t, err, order.ErrOrderIDNotSet) - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) - result, err := ok.WSCancelSpreadOrder(request.WithVerbose(t.Context()), "1234", "") + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + result, err := e.WSCancelSpreadOrder(request.WithVerbose(t.Context()), "1234", "") require.NoError(t, err) assert.NotNil(t, result) } func TestWSCancelAllSpreadOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, ok, canManipulateRealOrders) - testexch.SetupWs(t, ok) - err := ok.WSCancelAllSpreadOrders(request.WithVerbose(t.Context()), spreadPair.String()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + testexch.SetupWs(t, e) + err := e.WSCancelAllSpreadOrders(request.WithVerbose(t.Context()), spreadPair.String()) require.NoError(t, err) } diff --git a/exchanges/orderbook/simulator/simulator_test.go b/exchanges/orderbook/simulator/simulator_test.go index 63e1d739a3c..cc6f1cbde35 100644 --- a/exchanges/orderbook/simulator/simulator_test.go +++ b/exchanges/orderbook/simulator/simulator_test.go @@ -9,7 +9,7 @@ import ( ) func TestSimulate(t *testing.T) { - b := bitstamp.Bitstamp{} + b := bitstamp.Exchange{} b.SetDefaults() b.Verbose = false b.CurrencyPairs = currency.PairsManager{ diff --git a/exchanges/poloniex/currency_details_test.go b/exchanges/poloniex/currency_details_test.go index e13642d6b83..dafd08bbef9 100644 --- a/exchanges/poloniex/currency_details_test.go +++ b/exchanges/poloniex/currency_details_test.go @@ -44,7 +44,7 @@ func TestWsCurrencyMap(t *testing.T) { _, err = m.IsPostOnlyForPair(currency.EMPTYPAIR) require.ErrorIs(t, err, errCodeMapIsNil) - c, err := p.GetCurrencies(t.Context()) + c, err := e.GetCurrencies(t.Context()) if err != nil { t.Fatal(err) } @@ -54,7 +54,7 @@ func TestWsCurrencyMap(t *testing.T) { t.Fatal(err) } - tick, err := p.GetTicker(t.Context()) + tick, err := e.GetTicker(t.Context()) if err != nil { t.Fatal(err) } diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 3d4c1060e38..915fc4d4e73 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -62,14 +62,14 @@ const ( poloniexMaxOrderbookDepth = 100 ) -// Poloniex is the overarching type across the poloniex package -type Poloniex struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Poloniex +type Exchange struct { exchange.Base details CurrencyDetails } // GetTicker returns current ticker information -func (p *Poloniex) GetTicker(ctx context.Context) (map[string]Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context) (map[string]Ticker, error) { type response struct { Data map[string]Ticker } @@ -77,19 +77,19 @@ func (p *Poloniex) GetTicker(ctx context.Context) (map[string]Ticker, error) { resp := response{} path := "/public?command=returnTicker" - return resp.Data, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) + return resp.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) } // GetVolume returns a list of currencies with associated volume -func (p *Poloniex) GetVolume(ctx context.Context) (any, error) { +func (e *Exchange) GetVolume(ctx context.Context) (any, error) { var resp any path := "/public?command=return24hVolume" - return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetOrderbook returns the full orderbook from poloniex -func (p *Poloniex) GetOrderbook(ctx context.Context, currencyPair string, depth int) (OrderbookAll, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, currencyPair string, depth int) (OrderbookAll, error) { vals := url.Values{} if depth != 0 { @@ -101,12 +101,12 @@ func (p *Poloniex) GetOrderbook(ctx context.Context, currencyPair string, depth vals.Set("currencyPair", currencyPair) resp := OrderbookResponse{} path := "/public?command=returnOrderBook&" + vals.Encode() - err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return oba, err } if resp.Error != "" { - return oba, fmt.Errorf("%s GetOrderbook() error: %s", p.Name, resp.Error) + return oba, fmt.Errorf("%s GetOrderbook() error: %s", e.Name, resp.Error) } ob := Orderbook{ Bids: make([]OrderbookItem, len(resp.Bids)), @@ -129,7 +129,7 @@ func (p *Poloniex) GetOrderbook(ctx context.Context, currencyPair string, depth vals.Set("currencyPair", "all") resp := OrderbookResponseAll{} path := "/public?command=returnOrderBook&" + vals.Encode() - err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) if err != nil { return oba, err } @@ -157,7 +157,7 @@ func (p *Poloniex) GetOrderbook(ctx context.Context, currencyPair string, depth } // GetTradeHistory returns trades history from poloniex -func (p *Poloniex) GetTradeHistory(ctx context.Context, currencyPair string, start, end int64) ([]TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, currencyPair string, start, end int64) ([]TradeHistory, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -171,11 +171,11 @@ func (p *Poloniex) GetTradeHistory(ctx context.Context, currencyPair string, sta var resp []TradeHistory path := "/public?command=returnTradeHistory&" + vals.Encode() - return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetChartData returns chart data for a specific currency pair -func (p *Poloniex) GetChartData(ctx context.Context, currencyPair string, start, end time.Time, period string) ([]ChartData, error) { +func (e *Exchange) GetChartData(ctx context.Context, currencyPair string, start, end time.Time, period string) ([]ChartData, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -193,7 +193,7 @@ func (p *Poloniex) GetChartData(ctx context.Context, currencyPair string, start, var temp json.RawMessage path := "/public?command=returnChartData&" + vals.Encode() - err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &temp) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &temp) if err != nil { return nil, err } @@ -216,12 +216,12 @@ func (p *Poloniex) GetChartData(ctx context.Context, currencyPair string, start, } // GetCurrencies returns information about currencies -func (p *Poloniex) GetCurrencies(ctx context.Context) (map[string]*Currencies, error) { +func (e *Exchange) GetCurrencies(ctx context.Context) (map[string]*Currencies, error) { type Response struct { Data map[string]*Currencies } resp := Response{} - return resp.Data, p.SendHTTPRequest(ctx, + return resp.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, "/public?command=returnCurrencies&includeMultiChainCurrencies=true", &resp.Data, @@ -229,9 +229,9 @@ func (p *Poloniex) GetCurrencies(ctx context.Context) (map[string]*Currencies, e } // GetTimestamp returns server time -func (p *Poloniex) GetTimestamp(ctx context.Context) (time.Time, error) { +func (e *Exchange) GetTimestamp(ctx context.Context) (time.Time, error) { var resp TimeStampResponse - err := p.SendHTTPRequest(ctx, + err := e.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, poloniexTimestamp, &resp, @@ -244,16 +244,16 @@ func (p *Poloniex) GetTimestamp(ctx context.Context) (time.Time, error) { // GetLoanOrders returns the list of loan offers and demands for a given // currency, specified by the "currency" GET parameter. -func (p *Poloniex) GetLoanOrders(ctx context.Context, currency string) (LoanOrders, error) { +func (e *Exchange) GetLoanOrders(ctx context.Context, currency string) (LoanOrders, error) { resp := LoanOrders{} path := "/public?command=returnLoanOrders¤cy=" + currency - return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetBalances returns balances for your account. -func (p *Poloniex) GetBalances(ctx context.Context) (Balance, error) { +func (e *Exchange) GetBalances(ctx context.Context) (Balance, error) { var result any - if err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexBalances, url.Values{}, &result); err != nil { + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexBalances, url.Values{}, &result); err != nil { return Balance{}, err } @@ -283,11 +283,11 @@ func (p *Poloniex) GetBalances(ctx context.Context) (Balance, error) { } // GetCompleteBalances returns complete balances from your account. -func (p *Poloniex) GetCompleteBalances(ctx context.Context) (CompleteBalances, error) { +func (e *Exchange) GetCompleteBalances(ctx context.Context) (CompleteBalances, error) { var result CompleteBalances vals := url.Values{} vals.Set("account", "all") - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexBalancesComplete, vals, @@ -296,11 +296,11 @@ func (p *Poloniex) GetCompleteBalances(ctx context.Context) (CompleteBalances, e } // GetDepositAddresses returns deposit addresses for all enabled cryptos. -func (p *Poloniex) GetDepositAddresses(ctx context.Context) (DepositAddresses, error) { +func (e *Exchange) GetDepositAddresses(ctx context.Context) (DepositAddresses, error) { var result any addresses := DepositAddresses{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositAddresses, url.Values{}, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositAddresses, url.Values{}, &result) if err != nil { return addresses, err } @@ -322,7 +322,7 @@ func (p *Poloniex) GetDepositAddresses(ctx context.Context) (DepositAddresses, e } // GenerateNewAddress generates a new address for a currency -func (p *Poloniex) GenerateNewAddress(ctx context.Context, curr string) (string, error) { +func (e *Exchange) GenerateNewAddress(ctx context.Context, curr string) (string, error) { type Response struct { Success int Error string @@ -332,7 +332,7 @@ func (p *Poloniex) GenerateNewAddress(ctx context.Context, curr string) (string, values := url.Values{} values.Set("currency", curr) - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexGenerateNewAddress, values, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexGenerateNewAddress, values, &resp) if err != nil { return "", err } @@ -345,7 +345,7 @@ func (p *Poloniex) GenerateNewAddress(ctx context.Context, curr string) (string, } // GetDepositsWithdrawals returns a list of deposits and withdrawals -func (p *Poloniex) GetDepositsWithdrawals(ctx context.Context, start, end string) (DepositsWithdrawals, error) { +func (e *Exchange) GetDepositsWithdrawals(ctx context.Context, start, end string) (DepositsWithdrawals, error) { resp := DepositsWithdrawals{} values := url.Values{} @@ -361,27 +361,27 @@ func (p *Poloniex) GetDepositsWithdrawals(ctx context.Context, start, end string values.Set("end", strconv.FormatInt(time.Now().Unix(), 10)) } - return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositsWithdrawals, values, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositsWithdrawals, values, &resp) } // GetOpenOrders returns current unfilled opened orders -func (p *Poloniex) GetOpenOrders(ctx context.Context, currency string) (OpenOrdersResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, currency string) (OpenOrdersResponse, error) { values := url.Values{} values.Set("currencyPair", currency) result := OpenOrdersResponse{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) } // GetOpenOrdersForAllCurrencies returns all open orders -func (p *Poloniex) GetOpenOrdersForAllCurrencies(ctx context.Context) (OpenOrdersResponseAll, error) { +func (e *Exchange) GetOpenOrdersForAllCurrencies(ctx context.Context) (OpenOrdersResponseAll, error) { values := url.Values{} values.Set("currencyPair", "all") result := OpenOrdersResponseAll{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) } // GetAuthenticatedTradeHistoryForCurrency returns account trade history -func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { +func (e *Exchange) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start > 0 { @@ -398,11 +398,11 @@ func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, values.Set("currencyPair", currency) result := AuthenticatedTradeHistoryResponse{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result.Data) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result.Data) } // GetAuthenticatedTradeHistory returns account trade history -func (p *Poloniex) GetAuthenticatedTradeHistory(ctx context.Context, start, end, limit int64) (AuthenticatedTradeHistoryAll, error) { +func (e *Exchange) GetAuthenticatedTradeHistory(ctx context.Context, start, end, limit int64) (AuthenticatedTradeHistoryAll, error) { values := url.Values{} if start > 0 { @@ -420,7 +420,7 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(ctx context.Context, start, end, values.Set("currencyPair", "all") var result json.RawMessage - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result) if err != nil { return AuthenticatedTradeHistoryAll{}, err } @@ -436,7 +436,7 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(ctx context.Context, start, end, } // GetAuthenticatedOrderStatus returns the status of a given orderId. -func (p *Poloniex) GetAuthenticatedOrderStatus(ctx context.Context, orderID string) (o OrderStatusData, err error) { +func (e *Exchange) GetAuthenticatedOrderStatus(ctx context.Context, orderID string) (o OrderStatusData, err error) { values := url.Values{} if orderID == "" { @@ -445,7 +445,7 @@ func (p *Poloniex) GetAuthenticatedOrderStatus(ctx context.Context, orderID stri values.Set("orderNumber", orderID) var rawOrderStatus OrderStatus - err = p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderStatus, values, &rawOrderStatus) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderStatus, values, &rawOrderStatus) if err != nil { return o, err } @@ -474,7 +474,7 @@ func (p *Poloniex) GetAuthenticatedOrderStatus(ctx context.Context, orderID stri } // GetAuthenticatedOrderTrades returns all trades involving a given orderId. -func (p *Poloniex) GetAuthenticatedOrderTrades(ctx context.Context, orderID string) (o []OrderTrade, err error) { +func (e *Exchange) GetAuthenticatedOrderTrades(ctx context.Context, orderID string) (o []OrderTrade, err error) { values := url.Values{} if orderID == "" { @@ -483,7 +483,7 @@ func (p *Poloniex) GetAuthenticatedOrderTrades(ctx context.Context, orderID stri values.Set("orderNumber", orderID) var result json.RawMessage - err = p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderTrades, values, &result) + err = e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderTrades, values, &result) if err != nil { return nil, err } @@ -512,7 +512,7 @@ func (p *Poloniex) GetAuthenticatedOrderTrades(ctx context.Context, orderID stri } // PlaceOrder places a new order on the exchange -func (p *Poloniex) PlaceOrder(ctx context.Context, currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -535,16 +535,16 @@ func (p *Poloniex) PlaceOrder(ctx context.Context, currency string, rate, amount values.Set("fillOrKill", "1") } - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) } // CancelExistingOrder cancels and order by orderID -func (p *Poloniex) CancelExistingOrder(ctx context.Context, orderID int64) error { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) error { result := GenericResponse{} values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderID, 10)) - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderCancel, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderCancel, values, &result) if err != nil { return err } @@ -557,7 +557,7 @@ func (p *Poloniex) CancelExistingOrder(ctx context.Context, orderID int64) error } // MoveOrder moves an order -func (p *Poloniex) MoveOrder(ctx context.Context, orderID int64, rate, amount float64, postOnly, immediateOrCancel bool) (MoveOrderResponse, error) { +func (e *Exchange) MoveOrder(ctx context.Context, orderID int64, rate, amount float64, postOnly, immediateOrCancel bool) (MoveOrderResponse, error) { result := MoveOrderResponse{} values := url.Values{} @@ -584,7 +584,7 @@ func (p *Poloniex) MoveOrder(ctx context.Context, orderID int64, rate, amount fl values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) } - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderMove, values, &result) @@ -603,7 +603,7 @@ func (p *Poloniex) MoveOrder(ctx context.Context, orderID int64, rate, amount fl // For currencies where there are multiple networks to choose from (like USDT or BTC), // you can specify the chain by setting the "currency" parameter to be a multiChain currency // name, like USDTTRON, USDTETH, or BTCTRON -func (p *Poloniex) Withdraw(ctx context.Context, currency, address string, amount float64) (*Withdraw, error) { +func (e *Exchange) Withdraw(ctx context.Context, currency, address string, amount float64) (*Withdraw, error) { result := &Withdraw{} values := url.Values{} @@ -611,7 +611,7 @@ func (p *Poloniex) Withdraw(ctx context.Context, currency, address string, amoun values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexWithdraw, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexWithdraw, values, &result) if err != nil { return nil, err } @@ -624,20 +624,20 @@ func (p *Poloniex) Withdraw(ctx context.Context, currency, address string, amoun } // GetFeeInfo returns fee information -func (p *Poloniex) GetFeeInfo(ctx context.Context) (Fee, error) { +func (e *Exchange) GetFeeInfo(ctx context.Context) (Fee, error) { result := Fee{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexFeeInfo, url.Values{}, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexFeeInfo, url.Values{}, &result) } // GetTradableBalances returns tradable balances -func (p *Poloniex) GetTradableBalances(ctx context.Context) (map[string]map[string]float64, error) { +func (e *Exchange) GetTradableBalances(ctx context.Context) (map[string]map[string]float64, error) { type Response struct { Data map[string]map[string]any } result := Response{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradableBalances, url.Values{}, &result.Data) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradableBalances, url.Values{}, &result.Data) if err != nil { return nil, err } @@ -662,7 +662,7 @@ func (p *Poloniex) GetTradableBalances(ctx context.Context) (map[string]map[stri } // TransferBalance transfers balances between your accounts -func (p *Poloniex) TransferBalance(ctx context.Context, currency, from, to string, amount float64) (bool, error) { +func (e *Exchange) TransferBalance(ctx context.Context, currency, from, to string, amount float64) (bool, error) { values := url.Values{} result := GenericResponse{} @@ -671,7 +671,7 @@ func (p *Poloniex) TransferBalance(ctx context.Context, currency, from, to strin values.Set("fromAccount", from) values.Set("toAccount", to) - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTransferBalance, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTransferBalance, values, &result) if err != nil { return false, err } @@ -684,13 +684,13 @@ func (p *Poloniex) TransferBalance(ctx context.Context, currency, from, to strin } // GetMarginAccountSummary returns a summary on your margin accounts -func (p *Poloniex) GetMarginAccountSummary(ctx context.Context) (Margin, error) { +func (e *Exchange) GetMarginAccountSummary(ctx context.Context) (Margin, error) { result := Margin{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginAccountSummary, url.Values{}, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginAccountSummary, url.Values{}, &result) } // PlaceMarginOrder places a margin order -func (p *Poloniex) PlaceMarginOrder(ctx context.Context, currency string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { +func (e *Exchange) PlaceMarginOrder(ctx context.Context, currency string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -709,17 +709,17 @@ func (p *Poloniex) PlaceMarginOrder(ctx context.Context, currency string, rate, values.Set("lendingRate", strconv.FormatFloat(lendingRate, 'f', -1, 64)) } - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) } // GetMarginPosition returns a position on a margin order -func (p *Poloniex) GetMarginPosition(ctx context.Context, currency string) (any, error) { +func (e *Exchange) GetMarginPosition(ctx context.Context, currency string) (any, error) { values := url.Values{} if currency != "" && currency != "all" { values.Set("currencyPair", currency) result := MarginPosition{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result) } values.Set("currencyPair", "all") @@ -727,16 +727,16 @@ func (p *Poloniex) GetMarginPosition(ctx context.Context, currency string) (any, Data map[string]MarginPosition } result := Response{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result.Data) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result.Data) } // CloseMarginPosition closes a current margin position -func (p *Poloniex) CloseMarginPosition(ctx context.Context, currency string) (bool, error) { +func (e *Exchange) CloseMarginPosition(ctx context.Context, currency string) (bool, error) { values := url.Values{} values.Set("currencyPair", currency) result := GenericResponse{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPositionClose, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPositionClose, values, &result) if err != nil { return false, err } @@ -749,7 +749,7 @@ func (p *Poloniex) CloseMarginPosition(ctx context.Context, currency string) (bo } // CreateLoanOffer places a loan offer on the exchange -func (p *Poloniex) CreateLoanOffer(ctx context.Context, currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) { +func (e *Exchange) CreateLoanOffer(ctx context.Context, currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) { values := url.Values{} values.Set("currency", currency) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -771,7 +771,7 @@ func (p *Poloniex) CreateLoanOffer(ctx context.Context, currency string, amount, result := Response{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCreateLoanOffer, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCreateLoanOffer, values, &result) if err != nil { return 0, err } @@ -784,12 +784,12 @@ func (p *Poloniex) CreateLoanOffer(ctx context.Context, currency string, amount, } // CancelLoanOffer cancels a loan offer order -func (p *Poloniex) CancelLoanOffer(ctx context.Context, orderNumber int64) (bool, error) { +func (e *Exchange) CancelLoanOffer(ctx context.Context, orderNumber int64) (bool, error) { result := GenericResponse{} values := url.Values{} values.Set("orderID", strconv.FormatInt(orderNumber, 10)) - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCancelLoanOffer, values, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCancelLoanOffer, values, &result) if err != nil { return false, err } @@ -802,13 +802,13 @@ func (p *Poloniex) CancelLoanOffer(ctx context.Context, orderNumber int64) (bool } // GetOpenLoanOffers returns all open loan offers -func (p *Poloniex) GetOpenLoanOffers(ctx context.Context) (map[string][]LoanOffer, error) { +func (e *Exchange) GetOpenLoanOffers(ctx context.Context) (map[string][]LoanOffer, error) { type Response struct { Data map[string][]LoanOffer } result := Response{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOpenLoanOffers, url.Values{}, &result.Data) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOpenLoanOffers, url.Values{}, &result.Data) if err != nil { return nil, err } @@ -821,13 +821,13 @@ func (p *Poloniex) GetOpenLoanOffers(ctx context.Context) (map[string][]LoanOffe } // GetActiveLoans returns active loans -func (p *Poloniex) GetActiveLoans(ctx context.Context) (ActiveLoans, error) { +func (e *Exchange) GetActiveLoans(ctx context.Context) (ActiveLoans, error) { result := ActiveLoans{} - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexActiveLoans, url.Values{}, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexActiveLoans, url.Values{}, &result) } // GetLendingHistory returns lending history for the account -func (p *Poloniex) GetLendingHistory(ctx context.Context, start, end string) ([]LendingHistory, error) { +func (e *Exchange) GetLendingHistory(ctx context.Context, start, end string) ([]LendingHistory, error) { vals := url.Values{} if start != "" { @@ -839,19 +839,19 @@ func (p *Poloniex) GetLendingHistory(ctx context.Context, start, end string) ([] } var resp []LendingHistory - return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexLendingHistory, vals, &resp) } // ToggleAutoRenew allows for the autorenew of a contract -func (p *Poloniex) ToggleAutoRenew(ctx context.Context, orderNumber int64) (bool, error) { +func (e *Exchange) ToggleAutoRenew(ctx context.Context, orderNumber int64) (bool, error) { values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderNumber, 10)) result := GenericResponse{} - err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexAutoRenew, values, &result) @@ -867,7 +867,7 @@ func (p *Poloniex) ToggleAutoRenew(ctx context.Context, orderNumber int64) (bool } // WalletActivity returns the wallet activity between set start and end time -func (p *Poloniex) WalletActivity(ctx context.Context, start, end time.Time, activityType string) (*WalletActivityResponse, error) { +func (e *Exchange) WalletActivity(ctx context.Context, start, end time.Time, activityType string) (*WalletActivityResponse, error) { values := url.Values{} err := common.StartEndTimeCheck(start, end) if err != nil { @@ -879,14 +879,14 @@ func (p *Poloniex) WalletActivity(ctx context.Context, start, end time.Time, act values.Set("activityType", activityType) } var resp WalletActivityResponse - return &resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, + return &resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, poloniexWalletActivity, values, &resp) } // CancelMultipleOrdersByIDs Batch cancel one or many smart orders in an account by IDs. -func (p *Poloniex) CancelMultipleOrdersByIDs(ctx context.Context, orderIDs, clientOrderIDs []string) ([]CancelOrdersResponse, error) { +func (e *Exchange) CancelMultipleOrdersByIDs(ctx context.Context, orderIDs, clientOrderIDs []string) ([]CancelOrdersResponse, error) { values := url.Values{} if len(orderIDs) > 0 { values.Set("orderIds", strings.Join(orderIDs, ",")) @@ -895,15 +895,15 @@ func (p *Poloniex) CancelMultipleOrdersByIDs(ctx context.Context, orderIDs, clie values.Set("clientOrderIds", strings.Join(clientOrderIDs, ",")) } var result []CancelOrdersResponse - return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, poloniexCancelByIDs, values, &result) } // SendHTTPRequest sends an unauthenticated HTTP request -func (p *Poloniex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := p.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -912,32 +912,32 @@ func (p *Poloniex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: p.Verbose, - HTTPDebugging: p.HTTPDebugging, - HTTPRecording: p.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return p.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (p *Poloniex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, result any) error { - creds, err := p.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, result any) error { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - ePoint, err := p.API.Endpoints.GetURL(ep) + ePoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } - return p.SendPayload(ctx, request.Auth, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Auth, func() (*request.Item, error) { headers := make(map[string]string) headers["Content-Type"] = "application/x-www-form-urlencoded" headers["Key"] = creds.Key - values.Set("nonce", p.Requester.GetNonce(nonce.UnixNano).String()) + values.Set("nonce", e.Requester.GetNonce(nonce.UnixNano).String()) values.Set("command", endpoint) hmac, err := crypto.GetHMAC(crypto.HashSHA512, []byte(values.Encode()), []byte(creds.Secret)) @@ -954,19 +954,19 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange Body: bytes.NewBufferString(values.Encode()), Result: result, NonceEnabled: true, - Verbose: p.Verbose, - HTTPDebugging: p.HTTPDebugging, - HTTPRecording: p.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (p *Poloniex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feeInfo, err := p.GetFeeInfo(ctx) + feeInfo, err := e.GetFeeInfo(ctx) if err != nil { return 0, err } diff --git a/exchanges/poloniex/poloniex_live_test.go b/exchanges/poloniex/poloniex_live_test.go index 402e42fc720..86ef2f6a2f3 100644 --- a/exchanges/poloniex/poloniex_live_test.go +++ b/exchanges/poloniex/poloniex_live_test.go @@ -16,16 +16,16 @@ import ( var mockTests = false func TestMain(m *testing.M) { - p = new(Poloniex) - if err := testexch.Setup(p); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Poloniex Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - p.API.AuthenticatedSupport = true - p.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } - log.Printf(sharedtestvalues.LiveTesting, p.Name) - p.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride() - p.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride() + log.Printf(sharedtestvalues.LiveTesting, e.Name) + e.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride() + e.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride() os.Exit(m.Run()) } diff --git a/exchanges/poloniex/poloniex_mock_test.go b/exchanges/poloniex/poloniex_mock_test.go index aa044bb4ee5..e9ce8049890 100644 --- a/exchanges/poloniex/poloniex_mock_test.go +++ b/exchanges/poloniex/poloniex_mock_test.go @@ -15,12 +15,12 @@ import ( var mockTests = true func TestMain(m *testing.M) { - p = new(Poloniex) - if err := testexch.Setup(p); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Poloniex Setup error: %s", err) } - if err := testexch.MockHTTPInstance(p); err != nil { + if err := testexch.MockHTTPInstance(e); err != nil { log.Fatalf("Poloniex MockHTTPInstance error: %s", err) } diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 68e1a10c9e1..78f8b52da14 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -31,11 +31,11 @@ const ( var testPair = currency.NewPair(currency.BTC, currency.LTC) -var p = &Poloniex{} +var e *Exchange func TestTimestamp(t *testing.T) { t.Parallel() - _, err := p.GetTimestamp(t.Context()) + _, err := e.GetTimestamp(t.Context()) if err != nil { t.Error(err) } @@ -43,7 +43,7 @@ func TestTimestamp(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := p.GetTicker(t.Context()) + _, err := e.GetTicker(t.Context()) if err != nil { t.Error("Poloniex GetTicker() error", err) } @@ -51,7 +51,7 @@ func TestGetTicker(t *testing.T) { func TestGetVolume(t *testing.T) { t.Parallel() - _, err := p.GetVolume(t.Context()) + _, err := e.GetVolume(t.Context()) if err != nil { t.Error("Test failed - Poloniex GetVolume() error") } @@ -59,7 +59,7 @@ func TestGetVolume(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := p.GetOrderbook(t.Context(), "BTC_XMR", 50) + _, err := e.GetOrderbook(t.Context(), "BTC_XMR", 50) if err != nil { t.Error("Test failed - Poloniex GetOrderbook() error", err) } @@ -67,7 +67,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := p.GetTradeHistory(t.Context(), "BTC_XMR", 0, 0) + _, err := e.GetTradeHistory(t.Context(), "BTC_XMR", 0, 0) if err != nil { t.Error("Test failed - Poloniex GetTradeHistory() error", err) } @@ -75,7 +75,7 @@ func TestGetTradeHistory(t *testing.T) { func TestGetChartData(t *testing.T) { t.Parallel() - _, err := p.GetChartData(t.Context(), + _, err := e.GetChartData(t.Context(), "BTC_XMR", time.Unix(1405699200, 0), time.Unix(1405699400, 0), "300") if err != nil { @@ -85,7 +85,7 @@ func TestGetChartData(t *testing.T) { func TestGetCurrencies(t *testing.T) { t.Parallel() - _, err := p.GetCurrencies(t.Context()) + _, err := e.GetCurrencies(t.Context()) if err != nil { t.Error("Test failed - Poloniex GetCurrencies() error", err) } @@ -93,7 +93,7 @@ func TestGetCurrencies(t *testing.T) { func TestGetLoanOrders(t *testing.T) { t.Parallel() - _, err := p.GetLoanOrders(t.Context(), "BTC") + _, err := e.GetLoanOrders(t.Context(), "BTC") if err != nil { t.Error("Test failed - Poloniex GetLoanOrders() error", err) } @@ -117,11 +117,11 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - _, err := p.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(p) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, @@ -140,9 +140,9 @@ func TestGetFee(t *testing.T) { t.Parallel() feeBuilder := setFeeBuilder() - if sharedtestvalues.AreAPICredentialsSet(p) || mockTests { + if sharedtestvalues.AreAPICredentialsSet(e) || mockTests { // CryptocurrencyTradeFee Basic - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -150,21 +150,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -172,21 +172,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } @@ -194,7 +194,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := p.GetFee(t.Context(), feeBuilder); err != nil { + if _, err := e.GetFee(t.Context(), feeBuilder); err != nil { t.Error(err) } } @@ -204,7 +204,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText - withdrawPermissions := p.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, @@ -220,11 +220,11 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := p.GetActiveOrders(t.Context(), &getOrdersRequest) + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetActiveOrders() error", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock GetActiveOrders() err", err) @@ -239,11 +239,11 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := p.GetOrderHistory(t.Context(), &getOrdersRequest) + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not get order history: %s", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: t.Errorf("Could not mock get order history: %s", err) @@ -283,12 +283,12 @@ func TestGetOrderStatus(t *testing.T) { t.Skip("mock mismatch, skipping") } - _, err := p.GetAuthenticatedOrderStatus(t.Context(), + _, err := e.GetAuthenticatedOrderStatus(t.Context(), tt.orderID) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not get order status: %s", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: if !tt.errExpected { @@ -338,11 +338,11 @@ func TestGetOrderTrades(t *testing.T) { t.Skip("mock mismatch, skipping") } - _, err := p.GetAuthenticatedOrderTrades(t.Context(), tt.orderID) + _, err := e.GetAuthenticatedOrderTrades(t.Context(), tt.orderID) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not get order trades: %s", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && err == nil && !mockTests: + case !sharedtestvalues.AreAPICredentialsSet(e) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: assert.ErrorContains(t, err, tt.errMsgExpected) @@ -357,11 +357,11 @@ func TestGetOrderTrades(t *testing.T) { func TestSubmitOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderSubmission := &order.Submit{ - Exchange: p.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: currency.UnderscoreDelimiter, Base: currency.BTC, @@ -375,11 +375,11 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := p.SubmitOrder(t.Context(), orderSubmission) + response, err := e.SubmitOrder(t.Context(), orderSubmission) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && (err != nil || response.Status != order.Filled): + case sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.Filled): t.Errorf("Order failed to be placed: %v", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: t.Error("Mock SubmitOrder() err", err) @@ -389,7 +389,7 @@ func TestSubmitOrder(t *testing.T) { func TestCancelExchangeOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } orderCancellation := &order.Cancel{ OrderID: "1", @@ -398,11 +398,11 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := p.CancelOrder(t.Context(), orderCancellation) + err := e.CancelOrder(t.Context(), orderCancellation) switch { - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not cancel orders: %v", err) case mockTests && err != nil: t.Error("Mock CancelExchangeOrder() err", err) @@ -412,7 +412,7 @@ func TestCancelExchangeOrder(t *testing.T) { func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } currencyPair := currency.NewPair(currency.LTC, currency.BTC) @@ -423,11 +423,11 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := p.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) switch { - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Could not cancel orders: %v", err) case mockTests && err != nil: t.Error("Mock CancelAllExchangeOrders() err", err) @@ -440,19 +440,19 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } - _, err := p.ModifyOrder(t.Context(), &order.Modify{ + _, err := e.ModifyOrder(t.Context(), &order.Modify{ OrderID: "1337", Price: 1337, AssetType: asset.Spot, Pair: currency.NewBTCUSDT(), }) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil && mockTests: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil && mockTests: t.Error("ModifyOrder() error", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("ModifyOrder() error cannot be nil") case mockTests && err != nil: t.Error("Mock ModifyOrder() err", err) @@ -462,7 +462,7 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() withdrawCryptoRequest := withdraw.Request{ - Exchange: p.Name, + Exchange: e.Name, Crypto: withdraw.CryptoRequest{ Address: core.BitcoinDonationAddress, FeeAmount: 0, @@ -473,15 +473,15 @@ func TestWithdraw(t *testing.T) { TradePassword: "Password", } if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } - _, err := p.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Errorf("Withdraw failed to be placed: %v", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") case mockTests && err == nil: t.Error("should error due to invalid amount") @@ -491,11 +491,11 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } var withdrawFiatRequest withdraw.Request - _, err := p.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -505,11 +505,11 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, p, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) } var withdrawFiatRequest withdraw.Request - _, err := p.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", @@ -519,11 +519,11 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := p.GetDepositAddress(t.Context(), currency.USDT, "", "USDTETH") + _, err := e.GetDepositAddress(t.Context(), currency.USDT, "", "USDTETH") switch { - case sharedtestvalues.AreAPICredentialsSet(p) && err != nil: + case sharedtestvalues.AreAPICredentialsSet(e) && err != nil: t.Error("GetDepositAddress()", err) - case !sharedtestvalues.AreAPICredentialsSet(p) && !mockTests && err == nil: + case !sharedtestvalues.AreAPICredentialsSet(e) && !mockTests && err == nil: t.Error("GetDepositAddress() cannot be nil") case mockTests && err != nil: t.Error("Mock GetDepositAddress() err", err) @@ -532,9 +532,9 @@ func TestGetDepositAddress(t *testing.T) { func TestGenerateNewAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := p.GenerateNewAddress(t.Context(), currency.XRP.String()) + _, err := e.GenerateNewAddress(t.Context(), currency.XRP.String()) if err != nil { t.Fatal(err) } @@ -544,26 +544,26 @@ func TestGenerateNewAddress(t *testing.T) { // Will receive a message only on failure func TestWsAuth(t *testing.T) { t.Parallel() - if !p.Websocket.IsEnabled() && !p.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(p) { + if !e.Websocket.IsEnabled() && !e.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(e) { t.Skip(websocket.ErrWebsocketNotEnabled.Error()) } var dialer gws.Dialer - err := p.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(t.Context(), &dialer, http.Header{}) if err != nil { t.Fatal(err) } - go p.wsReadData() - creds, err := p.GetCredentials(t.Context()) + go e.wsReadData() + creds, err := e.GetCredentials(t.Context()) if err != nil { t.Fatal(err) } - err = p.wsSendAuthorisedCommand(t.Context(), creds.Secret, creds.Key, "subscribe") + err = e.wsSendAuthorisedCommand(t.Context(), creds.Secret, creds.Key, "subscribe") if err != nil { t.Fatal(err) } timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout) select { - case response := <-p.Websocket.DataHandler: + case response := <-e.Websocket.DataHandler: t.Error(response) case <-timer.C: } @@ -572,62 +572,62 @@ func TestWsAuth(t *testing.T) { func TestWsSubAck(t *testing.T) { pressXToJSON := []byte(`[1002, 1]`) - err := p.wsHandleData(pressXToJSON) + err := e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } } func TestWsTicker(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } pressXToJSON := []byte(`[1002, null, [ 50, "382.98901522", "381.99755898", "379.41296309", "-0.04312950", "14969820.94951828", "38859.58435407", 0, "412.25844455", "364.56122072" ] ]`) - err = p.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } } func TestWsExchangeVolume(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } pressXToJSON := []byte(`[1003,null,["2018-11-07 16:26",5804,{"BTC":"3418.409","ETH":"2645.921","USDT":"10832502.689","USDC":"1578020.908"}]]`) - err = p.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } } func TestWsTrades(t *testing.T) { - p.SetSaveTradeDataStatus(true) - err := p.loadCurrencyDetails(t.Context()) + e.SetSaveTradeDataStatus(true) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } pressXToJSON := []byte(`[14, 8768, [["t", "42706057", 1, "0.05567134", "0.00181421", 1522877119]]]`) - err = p.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } } func TestWsPriceAggregateOrderbook(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } pressXToJSON := []byte(`[50,141160924,[["i",{"currencyPair":"BTC_LTC","orderBook":[{"0.002784":"17.55","0.002786":"1.47","0.002792":"13.25","0.0028":"0.21","0.002804":"0.02","0.00281":"1.5","0.002811":"258.82","0.002812":"3.81","0.002817":"0.06","0.002824":"3","0.002825":"0.02","0.002836":"18.01","0.002837":"0.03","0.00284":"0.03","0.002842":"12.7","0.00285":"0.02","0.002852":"0.02","0.002855":"1.3","0.002857":"15.64","0.002864":"0.01"},{"0.002782":"45.93","0.002781":"1.46","0.002774":"13.34","0.002773":"0.04","0.002771":"0.05","0.002765":"6.21","0.002764":"3","0.00276":"10.77","0.002758":"3.11","0.002754":"0.02","0.002751":"288.94","0.00275":"24.06","0.002745":"187.27","0.002743":"0.04","0.002742":"0.96","0.002731":"0.06","0.00273":"12.13","0.002727":"0.02","0.002725":"0.03","0.002719":"1.09"}]}, "1692080077892"]]]`) - err = p.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } pressXToJSON = []byte(`[50,141160925,[["o",1,"0.002742","0", "1692080078806"],["o",1,"0.002718","0.02", "1692080078806"]]]`) - err = p.wsHandleData(pressXToJSON) + err = e.wsHandleData(pressXToJSON) if err != nil { t.Error(err) } @@ -636,14 +636,14 @@ func TestWsPriceAggregateOrderbook(t *testing.T) { func TestGetHistoricCandles(t *testing.T) { t.Parallel() - _, err := p.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.FiveMin, time.Unix(1588741402, 0), time.Unix(1588745003, 0)) + _, err := e.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.FiveMin, time.Unix(1588741402, 0), time.Unix(1588745003, 0)) assert.NoError(t, err) } func TestGetHistoricCandlesExtended(t *testing.T) { t.Parallel() - _, err := p.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.FiveMin, time.Unix(1588741402, 0), time.Unix(1588745003, 0)) + _, err := e.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.FiveMin, time.Unix(1588741402, 0), time.Unix(1588745003, 0)) assert.NoError(t, err) } @@ -652,7 +652,7 @@ func TestGetRecentTrades(t *testing.T) { if mockTests { t.Skip("relies on time.Now()") } - _, err := p.GetRecentTrades(t.Context(), currency.NewPair(currency.BTC, currency.XMR), asset.Spot) + _, err := e.GetRecentTrades(t.Context(), currency.NewPair(currency.BTC, currency.XMR), asset.Spot) assert.NoError(t, err) } @@ -666,78 +666,78 @@ func TestGetHistoricTrades(t *testing.T) { tStart = time.Date(tmNow.Year(), tmNow.Month()-3, 6, 0, 0, 0, 0, time.UTC) tEnd = time.Date(tmNow.Year(), tmNow.Month()-3, 7, 0, 0, 0, 0, time.UTC) } - _, err := p.GetHistoricTrades(t.Context(), currency.NewPair(currency.BTC, currency.XMR), asset.Spot, tStart, tEnd) + _, err := e.GetHistoricTrades(t.Context(), currency.NewPair(currency.BTC, currency.XMR), asset.Spot, tStart, tEnd) assert.NoError(t, err) } func TestProcessAccountMarginPosition(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } margin := []byte(`[1000,"",[["m", 23432933, 28, "-0.06000000"]]]`) - err = p.wsHandleData(margin) + err = e.wsHandleData(margin) require.ErrorIs(t, err, errNotEnoughData) margin = []byte(`[1000,"",[["m", "23432933", 28, "-0.06000000", null]]]`) - err = p.wsHandleData(margin) + err = e.wsHandleData(margin) require.ErrorIs(t, err, errTypeAssertionFailure) margin = []byte(`[1000,"",[["m", 23432933, "28", "-0.06000000", null]]]`) - err = p.wsHandleData(margin) + err = e.wsHandleData(margin) require.ErrorIs(t, err, errTypeAssertionFailure) margin = []byte(`[1000,"",[["m", 23432933, 28, -0.06000000, null]]]`) - err = p.wsHandleData(margin) + err = e.wsHandleData(margin) require.ErrorIs(t, err, errTypeAssertionFailure) margin = []byte(`[1000,"",[["m", 23432933, 28, "-0.06000000", null]]]`) - err = p.wsHandleData(margin) + err = e.wsHandleData(margin) if err != nil { t.Fatal(err) } } func TestProcessAccountPendingOrder(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } pending := []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000","0"]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errNotEnoughData) pending = []byte(`[1000,"",[["p","431682155857",127,"1000.00000000","1.00000000","0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errTypeAssertionFailure) pending = []byte(`[1000,"",[["p",431682155857,"127","1000.00000000","1.00000000","0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errTypeAssertionFailure) pending = []byte(`[1000,"",[["p",431682155857,127,1000.00000000,"1.00000000","0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errTypeAssertionFailure) pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000",1.00000000,"0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errTypeAssertionFailure) pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000",0,null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) require.ErrorIs(t, err, errTypeAssertionFailure) pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000","0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) if err != nil { t.Fatal(err) } // Unmatched pair in system pending = []byte(`[1000,"",[["p",431682155857,666,"1000.00000000","1.00000000","0",null]]]`) - err = p.wsHandleData(pending) + err = e.wsHandleData(pending) if err != nil { t.Fatal(err) } @@ -745,119 +745,119 @@ func TestProcessAccountPendingOrder(t *testing.T) { func TestProcessAccountOrderUpdate(t *testing.T) { orderUpdate := []byte(`[1000,"",[["o",431682155857,"0.00000000","f"]]]`) - err := p.wsHandleData(orderUpdate) + err := e.wsHandleData(orderUpdate) require.ErrorIs(t, err, errNotEnoughData) orderUpdate = []byte(`[1000,"",[["o","431682155857","0.00000000","f",null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) require.ErrorIs(t, err, errTypeAssertionFailure) orderUpdate = []byte(`[1000,"",[["o",431682155857,0.00000000,"f",null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) require.ErrorIs(t, err, errTypeAssertionFailure) orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000",123,null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) require.ErrorIs(t, err, errTypeAssertionFailure) orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","c",null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) require.ErrorIs(t, err, errNotEnoughData) orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.50000000","c",null,"0.50000000"]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) if err != nil { t.Fatal(err) } orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","c",null,"1.00000000"]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) if err != nil { t.Fatal(err) } orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.50000000","f",null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) if err != nil { t.Fatal(err) } orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","s",null]]]`) - err = p.wsHandleData(orderUpdate) + err = e.wsHandleData(orderUpdate) if err != nil { t.Fatal(err) } } func TestProcessAccountOrderLimit(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } accountTrade := []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000"]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errNotEnoughData) accountTrade = []byte(`[1000,"",[["n","127",431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,"431682155857","0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,0,"1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0",1000.00000000,"1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000",1.00000000,"2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000",1234,"1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56",1.00000000,null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`) - err = p.wsHandleData(accountTrade) + err = e.wsHandleData(accountTrade) if err != nil { t.Fatal(err) } } func TestProcessAccountBalanceUpdate(t *testing.T) { - err := p.loadCurrencyDetails(t.Context()) + err := e.loadCurrencyDetails(t.Context()) if err != nil { t.Error(err) } balance := []byte(`[1000,"",[["b",243,"e"]]]`) - err = p.wsHandleData(balance) + err = e.wsHandleData(balance) require.ErrorIs(t, err, errNotEnoughData) balance = []byte(`[1000,"",[["b","243","e","-1.00000000"]]]`) - err = p.wsHandleData(balance) + err = e.wsHandleData(balance) require.ErrorIs(t, err, errTypeAssertionFailure) balance = []byte(`[1000,"",[["b",243,1234,"-1.00000000"]]]`) - err = p.wsHandleData(balance) + err = e.wsHandleData(balance) require.ErrorIs(t, err, errTypeAssertionFailure) balance = []byte(`[1000,"",[["b",243,"e",-1.00000000]]]`) - err = p.wsHandleData(balance) + err = e.wsHandleData(balance) require.ErrorIs(t, err, errTypeAssertionFailure) balance = []byte(`[1000,"",[["b",243,"e","-1.00000000"]]]`) - err = p.wsHandleData(balance) + err = e.wsHandleData(balance) if err != nil { t.Fatal(err) } @@ -865,35 +865,35 @@ func TestProcessAccountBalanceUpdate(t *testing.T) { func TestProcessAccountTrades(t *testing.T) { accountTrades := []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345"]]]`) - err := p.wsHandleData(accountTrades) + err := e.wsHandleData(accountTrades) require.ErrorIs(t, err, errNotEnoughData) accountTrades = []byte(`[1000,"",[["t", "12345", "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, 0.03000000, "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", 0.50000000, "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, 0.00000375, "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, 0.0000037, "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", 12345, "12345", 0.015]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) require.ErrorIs(t, err, errTypeAssertionFailure) accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`) - err = p.wsHandleData(accountTrades) + err = e.wsHandleData(accountTrades) if err != nil { t.Fatal(err) } @@ -901,15 +901,15 @@ func TestProcessAccountTrades(t *testing.T) { func TestProcessAccountKilledOrder(t *testing.T) { kill := []byte(`[1000,"",[["k", 1337]]]`) - err := p.wsHandleData(kill) + err := e.wsHandleData(kill) require.ErrorIs(t, err, errNotEnoughData) kill = []byte(`[1000,"",[["k", "1337", null]]]`) - err = p.wsHandleData(kill) + err = e.wsHandleData(kill) require.ErrorIs(t, err, errTypeAssertionFailure) kill = []byte(`[1000,"",[["k", 1337, null]]]`) - err = p.wsHandleData(kill) + err = e.wsHandleData(kill) if err != nil { t.Fatal(err) } @@ -918,9 +918,9 @@ func TestProcessAccountKilledOrder(t *testing.T) { func TestGetCompleteBalances(t *testing.T) { t.Parallel() if !mockTests { - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) } - _, err := p.GetCompleteBalances(t.Context()) + _, err := e.GetCompleteBalances(t.Context()) if err != nil { t.Fatal(err) } @@ -928,13 +928,13 @@ func TestGetCompleteBalances(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := p.UpdateTicker(t.Context(), testPair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), testPair, asset.Spot) assert.NoError(t, err) } func TestUpdateTickers(t *testing.T) { t.Parallel() - err := p.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) if err != nil { t.Error(err) } @@ -942,7 +942,7 @@ func TestUpdateTickers(t *testing.T) { func TestGetAvailableTransferChains(t *testing.T) { t.Parallel() - _, err := p.GetAvailableTransferChains(t.Context(), currency.USDT) + _, err := e.GetAvailableTransferChains(t.Context(), currency.USDT) if err != nil { t.Fatal(err) } @@ -950,9 +950,9 @@ func TestGetAvailableTransferChains(t *testing.T) { func TestWalletActivity(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := p.WalletActivity(t.Context(), time.Now().Add(-time.Minute), time.Now(), "") + _, err := e.WalletActivity(t.Context(), time.Now().Add(-time.Minute), time.Now(), "") if err != nil { t.Error(err) } @@ -960,8 +960,8 @@ func TestWalletActivity(t *testing.T) { func TestCancelMultipleOrdersByIDs(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) - _, err := p.CancelMultipleOrdersByIDs(t.Context(), []string{"1234"}, []string{"5678"}) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.CancelMultipleOrdersByIDs(t.Context(), []string{"1234"}, []string{"5678"}) if err != nil { t.Error(err) } @@ -969,8 +969,8 @@ func TestCancelMultipleOrdersByIDs(t *testing.T) { func TestGetAccountFundingHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) - _, err := p.GetAccountFundingHistory(t.Context()) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetAccountFundingHistory(t.Context()) if err != nil { t.Error(err) } @@ -978,9 +978,9 @@ func TestGetAccountFundingHistory(t *testing.T) { func TestGetWithdrawalsHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := p.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) + _, err := e.GetWithdrawalsHistory(t.Context(), currency.BTC, asset.Spot) if err != nil { t.Error(err) } @@ -988,8 +988,8 @@ func TestGetWithdrawalsHistory(t *testing.T) { func TestCancelBatchOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, p, canManipulateRealOrders) - _, err := p.CancelBatchOrders(t.Context(), []order.Cancel{ + sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) + _, err := e.CancelBatchOrders(t.Context(), []order.Cancel{ { OrderID: "1234", AssetType: asset.Spot, @@ -1003,7 +1003,7 @@ func TestCancelBatchOrders(t *testing.T) { func TestGetTimestamp(t *testing.T) { t.Parallel() - st, err := p.GetTimestamp(t.Context()) + st, err := e.GetTimestamp(t.Context()) require.NoError(t, err) if st.IsZero() { @@ -1013,7 +1013,7 @@ func TestGetTimestamp(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() - st, err := p.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) if st.IsZero() { @@ -1023,7 +1023,7 @@ func TestGetServerTime(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := p.FetchTradablePairs(t.Context(), asset.Spot) + _, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Error(err) } @@ -1031,12 +1031,12 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, p) - for _, a := range p.GetAssetTypes(false) { - pairs, err := p.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := p.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/poloniex/poloniex_websocket.go b/exchanges/poloniex/poloniex_websocket.go index 5ebe1652003..cef38caa8ea 100644 --- a/exchanges/poloniex/poloniex_websocket.go +++ b/exchanges/poloniex/poloniex_websocket.go @@ -55,46 +55,46 @@ var ( ) // WsConnect initiates a websocket connection -func (p *Poloniex) WsConnect() error { +func (e *Exchange) WsConnect() error { ctx := context.TODO() - if !p.Websocket.IsEnabled() || !p.IsEnabled() { + if !e.Websocket.IsEnabled() || !e.IsEnabled() { return websocket.ErrWebsocketNotEnabled } var dialer gws.Dialer - err := p.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) + err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{}) if err != nil { return err } - err = p.loadCurrencyDetails(ctx) + err = e.loadCurrencyDetails(ctx) if err != nil { return err } - p.Websocket.Wg.Add(1) - go p.wsReadData() + e.Websocket.Wg.Add(1) + go e.wsReadData() return nil } // TODO: Create routine to refresh list every day/week(?) for production -func (p *Poloniex) loadCurrencyDetails(ctx context.Context) error { - if p.details.isInitial() { - ticks, err := p.GetTicker(ctx) +func (e *Exchange) loadCurrencyDetails(ctx context.Context) error { + if e.details.isInitial() { + ticks, err := e.GetTicker(ctx) if err != nil { return err } - err = p.details.loadPairs(ticks) + err = e.details.loadPairs(ticks) if err != nil { return err } - currs, err := p.GetCurrencies(ctx) + currs, err := e.GetCurrencies(ctx) if err != nil { return err } - err = p.details.loadCodes(currs) + err = e.details.loadCodes(currs) if err != nil { return err } @@ -103,21 +103,21 @@ func (p *Poloniex) loadCurrencyDetails(ctx context.Context) error { } // wsReadData handles data from the websocket connection -func (p *Poloniex) wsReadData() { - defer p.Websocket.Wg.Done() +func (e *Exchange) wsReadData() { + defer e.Websocket.Wg.Done() for { - resp := p.Websocket.Conn.ReadMessage() + resp := e.Websocket.Conn.ReadMessage() if resp.Raw == nil { return } - err := p.wsHandleData(resp.Raw) + err := e.wsHandleData(resp.Raw) if err != nil { - p.Websocket.DataHandler <- fmt.Errorf("%s: %w", p.Name, err) + e.Websocket.DataHandler <- fmt.Errorf("%s: %w", e.Name, err) } } } -func (p *Poloniex) wsHandleData(respRaw []byte) error { +func (e *Exchange) wsHandleData(respRaw []byte) error { var result any err := json.Unmarshal(respRaw, &result) if err != nil { @@ -170,37 +170,37 @@ func (p *Poloniex) wsHandleData(respRaw []byte) error { switch updateType { case accountNotificationPendingOrder: - err = p.processAccountPendingOrder(notification) + err = e.processAccountPendingOrder(notification) if err != nil { return fmt.Errorf("account notification pending order: %w", err) } case accountNotificationOrderUpdate: - err = p.processAccountOrderUpdate(notification) + err = e.processAccountOrderUpdate(notification) if err != nil { return fmt.Errorf("account notification order update: %w", err) } case accountNotificationOrderLimitCreated: - err = p.processAccountOrderLimit(notification) + err = e.processAccountOrderLimit(notification) if err != nil { return fmt.Errorf("account notification limit order creation: %w", err) } case accountNotificationBalanceUpdate: - err = p.processAccountBalanceUpdate(notification) + err = e.processAccountBalanceUpdate(notification) if err != nil { return fmt.Errorf("account notification balance update: %w", err) } case accountNotificationTrades: - err = p.processAccountTrades(notification) + err = e.processAccountTrades(notification) if err != nil { return fmt.Errorf("account notification trades: %w", err) } case accountNotificationKilledOrder: - err = p.processAccountKilledOrder(notification) + err = e.processAccountKilledOrder(notification) if err != nil { return fmt.Errorf("account notification killed order: %w", err) } case accountNotificationMarginPosition: - err = p.processAccountMarginPosition(notification) + err = e.processAccountMarginPosition(notification) if err != nil { return fmt.Errorf("account notification margin position: %w", err) } @@ -210,7 +210,7 @@ func (p *Poloniex) wsHandleData(respRaw []byte) error { } return nil case wsTickerDataID: - err = p.wsHandleTickerData(data) + err = e.wsHandleTickerData(data) if err != nil { return fmt.Errorf("websocket ticker process: %w", err) } @@ -238,13 +238,13 @@ func (p *Poloniex) wsHandleData(respRaw []byte) error { switch updateIdent { case orderbookInitial: - err = p.WsProcessOrderbookSnapshot(subData) + err = e.WsProcessOrderbookSnapshot(subData) if err != nil { return fmt.Errorf("websocket process orderbook snapshot: %w", err) } case orderbookUpdate: var pair currency.Pair - pair, err = p.details.GetPair(channelID) + pair, err = e.details.GetPair(channelID) if err != nil { return err } @@ -254,25 +254,25 @@ func (p *Poloniex) wsHandleData(respRaw []byte) error { return fmt.Errorf("%w sequence number is not a float64", errTypeAssertionFailure) } - err = p.WsProcessOrderbookUpdate(seqNo, subData, pair) + err = e.WsProcessOrderbookUpdate(seqNo, subData, pair) if err != nil { return fmt.Errorf("websocket process orderbook update: %w", err) } case tradeUpdate: - err = p.processTrades(channelID, subData) + err = e.processTrades(channelID, subData) if err != nil { return fmt.Errorf("websocket process trades update: %w", err) } default: - p.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ - Message: p.Name + websocket.UnhandledMessage + string(respRaw), + e.Websocket.DataHandler <- websocket.UnhandledMessageWarning{ + Message: e.Name + websocket.UnhandledMessage + string(respRaw), } } } return nil } -func (p *Poloniex) wsHandleTickerData(data []any) error { +func (e *Exchange) wsHandleTickerData(data []any) error { tickerData, ok := data[2].([]any) if !ok { return fmt.Errorf("%w ticker data is not []any", @@ -284,12 +284,12 @@ func (p *Poloniex) wsHandleTickerData(data []any) error { return fmt.Errorf("%w currency ID not float64", errTypeAssertionFailure) } - pair, err := p.details.GetPair(currencyID) + pair, err := e.details.GetPair(currencyID) if err != nil { return err } - enabled, err := p.GetEnabledPairs(asset.Spot) + enabled, err := e.GetEnabledPairs(asset.Spot) if err != nil { return err } @@ -360,8 +360,8 @@ func (p *Poloniex) wsHandleTickerData(data []any) error { // highestTradeIn24Hm, ok := tickerData[8].(string) // lowestTradePrice24H, ok := tickerData[9].(string) - p.Websocket.DataHandler <- &ticker.Price{ - ExchangeName: p.Name, + e.Websocket.DataHandler <- &ticker.Price{ + ExchangeName: e.Name, Volume: baseCurrencyVolume24H, QuoteVolume: quoteCurrencyVolume24H, High: highestBid, @@ -377,7 +377,7 @@ func (p *Poloniex) wsHandleTickerData(data []any) error { // WsProcessOrderbookSnapshot processes a new orderbook snapshot into a local // of orderbooks -func (p *Poloniex) WsProcessOrderbookSnapshot(data []any) error { +func (e *Exchange) WsProcessOrderbookSnapshot(data []any) error { subDataMap, ok := data[1].(map[string]any) if !ok { return fmt.Errorf("%w subData element is not map[string]any", @@ -481,19 +481,19 @@ func (p *Poloniex) WsProcessOrderbookSnapshot(data []any) error { book.Asks.SortAsks() book.Bids.SortBids() book.Asset = asset.Spot - book.ValidateOrderbook = p.ValidateOrderbook + book.ValidateOrderbook = e.ValidateOrderbook book.LastUpdated = time.UnixMilli(tsMilli) book.Pair, err = currency.NewPairFromString(pair) if err != nil { return err } - book.Exchange = p.Name + book.Exchange = e.Name - return p.Websocket.Orderbook.LoadSnapshot(&book) + return e.Websocket.Orderbook.LoadSnapshot(&book) } // WsProcessOrderbookUpdate processes new orderbook updates -func (p *Poloniex) WsProcessOrderbookUpdate(sequenceNumber float64, data []any, pair currency.Pair) error { +func (e *Exchange) WsProcessOrderbookUpdate(sequenceNumber float64, data []any, pair currency.Pair) error { if len(data) < 5 { return errNotEnoughData } @@ -540,12 +540,12 @@ func (p *Poloniex) WsProcessOrderbookUpdate(sequenceNumber float64, data []any, } else { update.Asks = []orderbook.Level{{Price: price, Amount: volume}} } - return p.Websocket.Orderbook.Update(update) + return e.Websocket.Orderbook.Update(update) } // GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions() -func (p *Poloniex) GenerateDefaultSubscriptions() (subscription.List, error) { - enabledPairs, err := p.GetEnabledPairs(asset.Spot) +func (e *Exchange) GenerateDefaultSubscriptions() (subscription.List, error) { + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return nil, err } @@ -555,7 +555,7 @@ func (p *Poloniex) GenerateDefaultSubscriptions() (subscription.List, error) { Channel: strconv.FormatInt(wsTickerDataID, 10), }) - if p.IsWebsocketAuthenticationSupported() { + if e.IsWebsocketAuthenticationSupported() { subscriptions = append(subscriptions, &subscription.Subscription{ Channel: strconv.FormatInt(wsAccountNotificationID, 10), }) @@ -573,22 +573,22 @@ func (p *Poloniex) GenerateDefaultSubscriptions() (subscription.List, error) { } // Subscribe sends a websocket message to receive data from the channel -func (p *Poloniex) Subscribe(subs subscription.List) error { +func (e *Exchange) Subscribe(subs subscription.List) error { ctx := context.TODO() - return p.manageSubs(ctx, subs, wsSubscribeOp) + return e.manageSubs(ctx, subs, wsSubscribeOp) } // Unsubscribe sends a websocket message to stop receiving data from the channel -func (p *Poloniex) Unsubscribe(subs subscription.List) error { +func (e *Exchange) Unsubscribe(subs subscription.List) error { ctx := context.TODO() - return p.manageSubs(ctx, subs, wsUnsubscribeOp) + return e.manageSubs(ctx, subs, wsUnsubscribeOp) } -func (p *Poloniex) manageSubs(ctx context.Context, subs subscription.List, op wsOp) error { +func (e *Exchange) manageSubs(ctx context.Context, subs subscription.List, op wsOp) error { var creds *account.Credentials - if p.IsWebsocketAuthenticationSupported() { + if e.IsWebsocketAuthenticationSupported() { var err error - creds, err = p.GetCredentials(ctx) + creds, err = e.GetCredentials(ctx) if err != nil { return err } @@ -598,7 +598,7 @@ func (p *Poloniex) manageSubs(ctx context.Context, subs subscription.List, op ws for _, s := range subs { var err error if creds != nil && strings.EqualFold(strconv.FormatInt(wsAccountNotificationID, 10), s.Channel) { - err = p.wsSendAuthorisedCommand(ctx, creds.Secret, creds.Key, op) + err = e.wsSendAuthorisedCommand(ctx, creds.Secret, creds.Key, op) } else { req := wsCommand{Command: op} if strings.EqualFold(strconv.FormatInt(wsTickerDataID, 10), s.Channel) { @@ -609,13 +609,13 @@ func (p *Poloniex) manageSubs(ctx context.Context, subs subscription.List, op ws } req.Channel = s.Pairs[0].String() } - err = p.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + err = e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) } if err == nil { if op == wsSubscribeOp { - err = p.Websocket.AddSuccessfulSubscriptions(p.Websocket.Conn, s) + err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s) } else { - err = p.Websocket.RemoveSubscriptions(p.Websocket.Conn, s) + err = e.Websocket.RemoveSubscriptions(e.Websocket.Conn, s) } } if err != nil { @@ -625,7 +625,7 @@ func (p *Poloniex) manageSubs(ctx context.Context, subs subscription.List, op ws return errs } -func (p *Poloniex) wsSendAuthorisedCommand(ctx context.Context, secret, key string, op wsOp) error { +func (e *Exchange) wsSendAuthorisedCommand(ctx context.Context, secret, key string, op wsOp) error { nonce := fmt.Sprintf("nonce=%v", time.Now().UnixNano()) hmac, err := crypto.GetHMAC(crypto.HashSHA512, []byte(nonce), []byte(secret)) if err != nil { @@ -638,10 +638,10 @@ func (p *Poloniex) wsSendAuthorisedCommand(ctx context.Context, secret, key stri Key: key, Payload: nonce, } - return p.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) + return e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, req) } -func (p *Poloniex) processAccountMarginPosition(notification []any) error { +func (e *Exchange) processAccountMarginPosition(notification []any) error { if len(notification) < 5 { return errNotEnoughData } @@ -655,7 +655,7 @@ func (p *Poloniex) processAccountMarginPosition(notification []any) error { if !ok { return fmt.Errorf("%w currency id not float64", errTypeAssertionFailure) } - code, err := p.details.GetCode(currencyID) + code, err := e.details.GetCode(currencyID) if err != nil { return err } @@ -674,7 +674,7 @@ func (p *Poloniex) processAccountMarginPosition(notification []any) error { clientOrderID, _ := notification[4].(string) // Temp struct for margin position changes - p.Websocket.DataHandler <- struct { + e.Websocket.DataHandler <- struct { OrderID string Code currency.Code Amount float64 @@ -689,7 +689,7 @@ func (p *Poloniex) processAccountMarginPosition(notification []any) error { return nil } -func (p *Poloniex) processAccountPendingOrder(notification []any) error { +func (e *Exchange) processAccountPendingOrder(notification []any) error { if len(notification) < 7 { return errNotEnoughData } @@ -703,14 +703,14 @@ func (p *Poloniex) processAccountPendingOrder(notification []any) error { if !ok { return fmt.Errorf("%w currency id not float64", errTypeAssertionFailure) } - pair, err := p.details.GetPair(currencyID) + pair, err := e.details.GetPair(currencyID) if err != nil { if !errors.Is(err, errIDNotFoundInPairMap) { return err } log.Errorf(log.WebsocketMgr, "%s - Unknown currency pair ID. Currency will appear as the pair ID: '%v'", - p.Name, + e.Name, currencyID) } @@ -742,8 +742,8 @@ func (p *Poloniex) processAccountPendingOrder(notification []any) error { // null returned so ok check is not needed clientOrderID, _ := notification[6].(string) - p.Websocket.DataHandler <- &order.Detail{ - Exchange: p.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: strconv.FormatFloat(orderID, 'f', -1, 64), Pair: pair, AssetType: asset.Spot, @@ -757,7 +757,7 @@ func (p *Poloniex) processAccountPendingOrder(notification []any) error { return nil } -func (p *Poloniex) processAccountOrderUpdate(notification []any) error { +func (e *Exchange) processAccountOrderUpdate(notification []any) error { if len(notification) < 5 { return errNotEnoughData } @@ -813,8 +813,8 @@ func (p *Poloniex) processAccountOrderUpdate(notification []any) error { // null returned so ok check is not needed clientOrderID, _ := notification[4].(string) - p.Websocket.DataHandler <- &order.Detail{ - Exchange: p.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, RemainingAmount: cancelledAmount, Amount: amount + cancelledAmount, ExecutedAmount: amount, @@ -827,7 +827,7 @@ func (p *Poloniex) processAccountOrderUpdate(notification []any) error { return nil } -func (p *Poloniex) processAccountOrderLimit(notification []any) error { +func (e *Exchange) processAccountOrderLimit(notification []any) error { if len(notification) != 9 { return errNotEnoughData } @@ -836,14 +836,14 @@ func (p *Poloniex) processAccountOrderLimit(notification []any) error { if !ok { return fmt.Errorf("%w currency ID not string", errTypeAssertionFailure) } - pair, err := p.details.GetPair(currencyID) + pair, err := e.details.GetPair(currencyID) if err != nil { if !errors.Is(err, errIDNotFoundInPairMap) { return err } log.Errorf(log.WebsocketMgr, "%s - Unknown currency pair ID. Currency will appear as the pair ID: '%v'", - p.Name, + e.Name, currencyID) } @@ -900,8 +900,8 @@ func (p *Poloniex) processAccountOrderLimit(notification []any) error { // null returned so ok check is not needed clientOrderID, _ := notification[8].(string) - p.Websocket.DataHandler <- &order.Detail{ - Exchange: p.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, Price: orderPrice, RemainingAmount: orderAmount, ExecutedAmount: origOrderAmount - orderAmount, @@ -918,7 +918,7 @@ func (p *Poloniex) processAccountOrderLimit(notification []any) error { return nil } -func (p *Poloniex) processAccountBalanceUpdate(notification []any) error { +func (e *Exchange) processAccountBalanceUpdate(notification []any) error { if len(notification) < 4 { return errNotEnoughData } @@ -927,7 +927,7 @@ func (p *Poloniex) processAccountBalanceUpdate(notification []any) error { if !ok { return fmt.Errorf("%w currency ID not float64", errTypeAssertionFailure) } - code, err := p.details.GetCode(currencyID) + code, err := e.details.GetCode(currencyID) if err != nil { return err } @@ -949,7 +949,7 @@ func (p *Poloniex) processAccountBalanceUpdate(notification []any) error { // TODO: Integrate with exchange account system // NOTES: This will affect free amount, a rest call might be needed to get // locked and total amounts periodically. - p.Websocket.DataHandler <- account.Change{ + e.Websocket.DataHandler <- account.Change{ Account: deriveWalletType(walletType), AssetType: asset.Spot, Balance: &account.Balance{ @@ -974,7 +974,7 @@ func deriveWalletType(s string) string { } } -func (p *Poloniex) processAccountTrades(notification []any) error { +func (e *Exchange) processAccountTrades(notification []any) error { if len(notification) < 11 { return errNotEnoughData } @@ -1041,15 +1041,15 @@ func (p *Poloniex) processAccountTrades(notification []any) error { return err } - p.Websocket.DataHandler <- &order.Detail{ - Exchange: p.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: strconv.FormatFloat(orderID, 'f', -1, 64), Fee: totalFee, Trades: []order.TradeHistory{{ Price: rate, Amount: amount, Fee: totalFee, - Exchange: p.Name, + Exchange: e.Name, TID: strconv.FormatFloat(tradeID, 'f', -1, 64), Timestamp: timeParse, Total: tradeTotal, @@ -1060,7 +1060,7 @@ func (p *Poloniex) processAccountTrades(notification []any) error { return nil } -func (p *Poloniex) processAccountKilledOrder(notification []any) error { +func (e *Exchange) processAccountKilledOrder(notification []any) error { if len(notification) < 3 { return errNotEnoughData } @@ -1073,8 +1073,8 @@ func (p *Poloniex) processAccountKilledOrder(notification []any) error { // null returned so ok check is not needed clientOrderID, _ := notification[2].(string) - p.Websocket.DataHandler <- &order.Detail{ - Exchange: p.Name, + e.Websocket.DataHandler <- &order.Detail{ + Exchange: e.Name, OrderID: strconv.FormatFloat(orderID, 'f', -1, 64), Status: order.Cancelled, AssetType: asset.Spot, @@ -1083,11 +1083,11 @@ func (p *Poloniex) processAccountKilledOrder(notification []any) error { return nil } -func (p *Poloniex) processTrades(currencyID float64, subData []any) error { - if !p.IsSaveTradeDataEnabled() { +func (e *Exchange) processTrades(currencyID float64, subData []any) error { + if !e.IsSaveTradeDataEnabled() { return nil } - pair, err := p.details.GetPair(currencyID) + pair, err := e.details.GetPair(currencyID) if err != nil { return err } @@ -1140,9 +1140,9 @@ func (p *Poloniex) processTrades(currencyID float64, subData []any) error { return fmt.Errorf("%w time not float64", errTypeAssertionFailure) } - return p.AddTradesToBuffer(trade.Data{ + return e.AddTradesToBuffer(trade.Data{ TID: tradeID, - Exchange: p.Name, + Exchange: e.Name, CurrencyPair: pair, AssetType: asset.Spot, Side: side, diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index e706b5b61e1..7772c2929fc 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -33,12 +33,12 @@ import ( ) // SetDefaults sets default settings for poloniex -func (p *Poloniex) SetDefaults() { - p.Name = "Poloniex" - p.Enabled = true - p.Verbose = true - p.API.CredentialsValidator.RequiresKey = true - p.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Poloniex" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{ Delimiter: currency.UnderscoreDelimiter, @@ -50,12 +50,12 @@ func (p *Poloniex) SetDefaults() { Uppercase: true, } - err := p.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - p.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: true, @@ -122,14 +122,14 @@ func (p *Poloniex) SetDefaults() { }, } - p.Requester, err = request.New(p.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), request.WithLimiter(GetRateLimit())) if err != nil { log.Errorln(log.ExchangeSys, err) } - p.API.Endpoints = p.NewEndpoints() - err = p.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: poloniexAPIURL, exchange.RestSpotSupplementary: poloniexAltAPIUrl, exchange.WebsocketSpot: poloniexWebsocketAddress, @@ -137,41 +137,41 @@ func (p *Poloniex) SetDefaults() { if err != nil { log.Errorln(log.ExchangeSys, err) } - p.Websocket = websocket.NewManager() - p.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit - p.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout - p.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit + e.Websocket = websocket.NewManager() + e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit + e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout + e.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit } // Setup sets user exchange configuration settings -func (p *Poloniex) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { err := exch.Validate() if err != nil { return err } if !exch.Enabled { - p.SetEnabled(false) + e.SetEnabled(false) return nil } - err = p.SetupDefaults(exch) + err = e.SetupDefaults(exch) if err != nil { return err } - wsRunningURL, err := p.API.Endpoints.GetURL(exchange.WebsocketSpot) + wsRunningURL, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { return err } - err = p.Websocket.Setup(&websocket.ManagerSetup{ + err = e.Websocket.Setup(&websocket.ManagerSetup{ ExchangeConfig: exch, DefaultURL: poloniexWebsocketAddress, RunningURL: wsRunningURL, - Connector: p.WsConnect, - Subscriber: p.Subscribe, - Unsubscriber: p.Unsubscribe, - GenerateSubscriptions: p.GenerateDefaultSubscriptions, - Features: &p.Features.Supports.WebsocketCapabilities, + Connector: e.WsConnect, + Subscriber: e.Subscribe, + Unsubscriber: e.Unsubscribe, + GenerateSubscriptions: e.GenerateDefaultSubscriptions, + Features: &e.Features.Supports.WebsocketCapabilities, OrderbookBufferConfig: buffer.Config{ SortBuffer: true, SortBufferByUpdateIDs: true, @@ -181,16 +181,16 @@ func (p *Poloniex) Setup(exch *config.Exchange) error { return err } - return p.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ + return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{ ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout, ResponseMaxLimit: exch.WebsocketResponseMaxLimit, }) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (p *Poloniex) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { // TODO: Upgrade to new API version for fetching operational pairs. - resp, err := p.GetTicker(ctx) + resp, err := e.GetTicker(ctx) if err != nil { return nil, err } @@ -214,31 +214,31 @@ func (p *Poloniex) FetchTradablePairs(ctx context.Context, _ asset.Item) (curren // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (p *Poloniex) UpdateTradablePairs(ctx context.Context, forceUpgrade bool) error { - pairs, err := p.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpgrade bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = p.UpdatePairs(pairs, asset.Spot, false, forceUpgrade) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpgrade) if err != nil { return err } - return p.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (p *Poloniex) UpdateTickers(ctx context.Context, a asset.Item) error { - tick, err := p.GetTicker(ctx) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := e.GetTicker(ctx) if err != nil { return err } - enabledPairs, err := p.GetEnabledPairs(a) + enabledPairs, err := e.GetEnabledPairs(a) if err != nil { return err } for i := range enabledPairs { - fPair, err := p.FormatExchangeCurrency(enabledPairs[i], a) + fPair, err := e.FormatExchangeCurrency(enabledPairs[i], a) if err != nil { return err } @@ -256,7 +256,7 @@ func (p *Poloniex) UpdateTickers(ctx context.Context, a asset.Item) error { Low: tick[curr].Low24Hr, Volume: tick[curr].BaseVolume, QuoteVolume: tick[curr].QuoteVolume, - ExchangeName: p.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -267,38 +267,38 @@ func (p *Poloniex) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (p *Poloniex) UpdateTicker(ctx context.Context, currencyPair currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := p.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, currencyPair currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(p.Name, currencyPair, a) + return ticker.GetTicker(e.Name, currencyPair, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, pair currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := p.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } callingBook := &orderbook.Book{ - Exchange: p.Name, + Exchange: e.Name, Pair: pair, Asset: assetType, - ValidateOrderbook: p.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - orderbookNew, err := p.GetOrderbook(ctx, "", poloniexMaxOrderbookDepth) + orderbookNew, err := e.GetOrderbook(ctx, "", poloniexMaxOrderbookDepth) if err != nil { return callingBook, err } - enabledPairs, err := p.GetEnabledPairs(assetType) + enabledPairs, err := e.GetEnabledPairs(assetType) if err != nil { return callingBook, err } for i := range enabledPairs { - pFmt, err := p.GetPairFormat(assetType, true) + pFmt, err := e.GetPairFormat(assetType, true) if err != nil { return nil, err } @@ -311,10 +311,10 @@ func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, asse } } book := &orderbook.Book{ - Exchange: p.Name, + Exchange: e.Name, Pair: enabledPairs[i], Asset: assetType, - ValidateOrderbook: p.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } book.Bids = make(orderbook.Levels, len(data.Bids)) @@ -337,15 +337,15 @@ func (p *Poloniex) UpdateOrderbook(ctx context.Context, pair currency.Pair, asse return book, err } } - return orderbook.Get(p.Name, pair, assetType) + return orderbook.Get(e.Name, pair, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Poloniex exchange -func (p *Poloniex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = p.Name - accountBalance, err := p.GetBalances(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetBalances(ctx) if err != nil { return response, err } @@ -363,7 +363,7 @@ func (p *Poloniex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) Currencies: currencies, }) - creds, err := p.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -377,16 +377,16 @@ func (p *Poloniex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (p *Poloniex) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) { end := time.Now() - walletActivity, err := p.WalletActivity(ctx, end.Add(-time.Hour*24*365), end, "") + walletActivity, err := e.WalletActivity(ctx, end.Add(-time.Hour*24*365), end, "") if err != nil { return nil, err } resp := make([]exchange.FundingHistory, len(walletActivity.Deposits)) for i := range walletActivity.Deposits { resp[i] = exchange.FundingHistory{ - ExchangeName: p.Name, + ExchangeName: e.Name, Status: walletActivity.Deposits[i].Status, Timestamp: walletActivity.Deposits[i].Timestamp.Time(), Currency: walletActivity.Deposits[i].Currency.String(), @@ -397,7 +397,7 @@ func (p *Poloniex) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fun } for i := range walletActivity.Withdrawals { resp[i] = exchange.FundingHistory{ - ExchangeName: p.Name, + ExchangeName: e.Name, Status: walletActivity.Withdrawals[i].Status, Timestamp: walletActivity.Withdrawals[i].Timestamp.Time(), Currency: walletActivity.Withdrawals[i].Currency.String(), @@ -411,9 +411,9 @@ func (p *Poloniex) GetAccountFundingHistory(ctx context.Context) ([]exchange.Fun } // GetWithdrawalsHistory returns previous withdrawals data -func (p *Poloniex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { end := time.Now() - withdrawals, err := p.WalletActivity(ctx, end.Add(-time.Hour*24*365), end, "withdrawals") + withdrawals, err := e.WalletActivity(ctx, end.Add(-time.Hour*24*365), end, "withdrawals") if err != nil { return nil, err } @@ -436,17 +436,17 @@ func (p *Poloniex) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ } // GetRecentTrades returns the most recent trades for a currency and asset -func (p *Poloniex) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return p.GetHistoricTrades(ctx, pair, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (e *Exchange) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return e.GetHistoricTrades(ctx, pair, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (p *Poloniex) GetHistoricTrades(ctx context.Context, pair currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(ctx context.Context, pair currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - pair, err = p.FormatExchangeCurrency(pair, assetType) + pair, err = e.FormatExchangeCurrency(pair, assetType) if err != nil { return nil, err } @@ -456,7 +456,7 @@ func (p *Poloniex) GetHistoricTrades(ctx context.Context, pair currency.Pair, as allTrades: for { var tradeData []TradeHistory - tradeData, err = p.GetTradeHistory(ctx, + tradeData, err = e.GetTradeHistory(ctx, pair.String(), ts.Unix(), timestampEnd.Unix()) @@ -478,7 +478,7 @@ allTrades: return nil, err } resp = append(resp, trade.Data{ - Exchange: p.Name, + Exchange: e.Name, TID: tradeData[i].TradeID, CurrencyPair: pair, AssetType: assetType, @@ -500,7 +500,7 @@ allTrades: } } - err = p.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -511,16 +511,16 @@ allTrades: } // SubmitOrder submits a new order -func (p *Poloniex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(p.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } - fPair, err := p.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } - response, err := p.PlaceOrder(ctx, + response, err := e.PlaceOrder(ctx, fPair.String(), s.Price, s.Amount, @@ -535,7 +535,7 @@ func (p *Poloniex) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Sub // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (p *Poloniex) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(ctx context.Context, action *order.Modify) (*order.ModifyResponse, error) { if err := action.Validate(); err != nil { return nil, err } @@ -545,7 +545,7 @@ func (p *Poloniex) ModifyOrder(ctx context.Context, action *order.Modify) (*orde return nil, err } - resp, err := p.MoveOrder(ctx, + resp, err := e.MoveOrder(ctx, oID, action.Price, action.Amount, @@ -564,7 +564,7 @@ func (p *Poloniex) ModifyOrder(ctx context.Context, action *order.Modify) (*orde } // CancelOrder cancels an order by its corresponding ID number -func (p *Poloniex) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -574,11 +574,11 @@ func (p *Poloniex) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } - return p.CancelExistingOrder(ctx, orderIDInt) + return e.CancelExistingOrder(ctx, orderIDInt) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (p *Poloniex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.CancelBatchResponse, error) { if len(o) == 0 { return nil, order.ErrCancelOrderIsNil } @@ -594,7 +594,7 @@ func (p *Poloniex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*or return nil, order.ErrOrderIDNotSet } } - cancelledOrders, err := p.CancelMultipleOrdersByIDs(ctx, orderIDs, clientOrderIDs) + cancelledOrders, err := e.CancelMultipleOrdersByIDs(ctx, orderIDs, clientOrderIDs) if err != nil { return nil, err } @@ -612,18 +612,18 @@ func (p *Poloniex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*or } // CancelAllOrders cancels all orders associated with a currency pair -func (p *Poloniex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - openOrders, err := p.GetOpenOrdersForAllCurrencies(ctx) + openOrders, err := e.GetOpenOrdersForAllCurrencies(ctx) if err != nil { return cancelAllOrdersResponse, err } for key := range openOrders.Data { for i := range openOrders.Data[key] { - err = p.CancelExistingOrder(ctx, openOrders.Data[key][i].OrderNumber) + err = e.CancelExistingOrder(ctx, openOrders.Data[key][i].OrderNumber) if err != nil { id := strconv.FormatInt(openOrders.Data[key][i].OrderNumber, 10) cancelAllOrdersResponse.Status[id] = err.Error() @@ -635,24 +635,24 @@ func (p *Poloniex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order. } // GetOrderInfo returns order information based on order ID -func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) { if pair.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } orderInfo := order.Detail{ - Exchange: p.Name, + Exchange: e.Name, Pair: pair, } - trades, err := p.GetAuthenticatedOrderTrades(ctx, orderID) + trades, err := e.GetAuthenticatedOrderTrades(ctx, orderID) if err != nil && !strings.Contains(err.Error(), "Order not found") { return nil, err } for i := range trades { var tradeHistory order.TradeHistory - tradeHistory.Exchange = p.Name + tradeHistory.Exchange = e.Name tradeHistory.Side, err = order.StringToOrderSide(trades[i].Type) if err != nil { return nil, err @@ -669,7 +669,7 @@ func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair curren orderInfo.Trades = append(orderInfo.Trades, tradeHistory) } - resp, err := p.GetAuthenticatedOrderStatus(ctx, orderID) + resp, err := e.GetAuthenticatedOrderStatus(ctx, orderID) if err != nil { if len(orderInfo.Trades) > 0 { // on closed orders return trades only if strings.Contains(err.Error(), "Order not found") { @@ -681,7 +681,7 @@ func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair curren } if orderInfo.Status, err = order.StringToOrderStatus(resp.Status); err != nil { - log.Errorf(log.ExchangeSys, "%s %v", p.Name, err) + log.Errorf(log.ExchangeSys, "%s %v", e.Name, err) } orderInfo.Price = resp.Rate orderInfo.Amount = resp.Amount @@ -703,15 +703,15 @@ func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair curren } // GetDepositAddress returns a deposit address for a specified currency -func (p *Poloniex) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { - depositAddrs, err := p.GetDepositAddresses(ctx) +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) { + depositAddrs, err := e.GetDepositAddresses(ctx) if err != nil { return nil, err } // Some coins use a main address, so we must use this in conjunction with the returned // deposit address to produce the full deposit address and tag - currencies, err := p.GetCurrencies(ctx) + currencies, err := e.GetCurrencies(ctx) if err != nil { return nil, err } @@ -727,7 +727,7 @@ func (p *Poloniex) GetDepositAddress(ctx context.Context, cryptocurrency currenc address = coinParams.DepositAddress tag, ok = depositAddrs.Addresses[cryptocurrency.Upper().String()] if !ok { - newAddr, err := p.GenerateNewAddress(ctx, cryptocurrency.Upper().String()) + newAddr, err := e.GenerateNewAddress(ctx, cryptocurrency.Upper().String()) if err != nil { return nil, err } @@ -762,7 +762,7 @@ func (p *Poloniex) GetDepositAddress(ctx context.Context, cryptocurrency currenc return nil, fmt.Errorf("deposits and withdrawals for %v are currently disabled", targetCurrency) } - newAddr, err := p.GenerateNewAddress(ctx, targetCurrency) + newAddr, err := e.GenerateNewAddress(ctx, targetCurrency) if err != nil { return nil, err } @@ -773,7 +773,7 @@ func (p *Poloniex) GetDepositAddress(ctx context.Context, cryptocurrency currenc // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (p *Poloniex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -782,7 +782,7 @@ func (p *Poloniex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ if withdrawRequest.Crypto.Chain != "" { targetCurrency = withdrawRequest.Crypto.Chain } - v, err := p.Withdraw(ctx, targetCurrency, withdrawRequest.Crypto.Address, withdrawRequest.Amount) + v, err := e.Withdraw(ctx, targetCurrency, withdrawRequest.Crypto.Address, withdrawRequest.Amount) if err != nil { return nil, err } @@ -793,41 +793,41 @@ func (p *Poloniex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (p *Poloniex) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (p *Poloniex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (p *Poloniex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if (!p.AreCredentialsValid(ctx) || p.SkipAuthCheck) && // Todo check connection status + if (!e.AreCredentialsValid(ctx) || e.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return p.GetFee(ctx, feeBuilder) + return e.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := p.GetOpenOrdersForAllCurrencies(ctx) + resp, err := e.GetOpenOrdersForAllCurrencies(ctx) if err != nil { return nil, err } - format, err := p.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -850,7 +850,7 @@ func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReq if err != nil { log.Errorf(log.ExchangeSys, "Exchange %v Func %v Order %v Could not parse date to unix with value of %v", - p.Name, + e.Name, "GetActiveOrders", resp.Data[key][i].OrderNumber, resp.Data[key][i].Date) @@ -863,22 +863,22 @@ func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.MultiOrderReq Date: orderDate, Price: resp.Data[key][i].Rate, Pair: symbol, - Exchange: p.Name, + Exchange: e.Name, }) } } - return req.Filter(p.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - resp, err := p.GetAuthenticatedTradeHistory(ctx, + resp, err := e.GetAuthenticatedTradeHistory(ctx, req.StartTime.Unix(), req.EndTime.Unix(), 10000) @@ -886,7 +886,7 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq return nil, err } - format, err := p.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -909,7 +909,7 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq if err != nil { log.Errorf(log.ExchangeSys, "Exchange %v Func %v Order %v Could not parse date to unix with value of %v", - p.Name, + e.Name, "GetActiveOrders", resp.Data[key][i].OrderNumber, resp.Data[key][i].Date) @@ -925,34 +925,34 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.MultiOrderReq AverageExecutedPrice: resp.Data[key][i].Rate, Pair: pair, Status: order.Filled, - Exchange: p.Name, + Exchange: e.Name, } detail.InferCostsAndTimes() orders = append(orders, detail) } } - return req.Filter(p.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (p *Poloniex) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := p.UpdateAccountInfo(ctx, assetType) - return p.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (p *Poloniex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := p.GetKlineRequest(pair, a, interval, start, end, false) +func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineRequest(pair, a, interval, start, end, false) if err != nil { return nil, err } - resp, err := p.GetChartData(ctx, + resp, err := e.GetChartData(ctx, req.RequestFormatted.String(), req.Start, req.End, - p.FormatExchangeKlineInterval(req.ExchangeInterval)) + e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } @@ -972,19 +972,19 @@ func (p *Poloniex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (p *Poloniex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { - req, err := p.GetKlineExtendedRequest(pair, a, interval, start, end) +func (e *Exchange) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) { + req, err := e.GetKlineExtendedRequest(pair, a, interval, start, end) if err != nil { return nil, err } timeSeries := make([]kline.Candle, 0, req.Size()) for i := range req.RangeHolder.Ranges { - resp, err := p.GetChartData(ctx, + resp, err := e.GetChartData(ctx, req.RequestFormatted.String(), req.RangeHolder.Ranges[i].Start.Time, req.RangeHolder.Ranges[i].End.Time, - p.FormatExchangeKlineInterval(req.ExchangeInterval)) + e.FormatExchangeKlineInterval(req.ExchangeInterval)) if err != nil { return nil, err } @@ -1003,10 +1003,9 @@ func (p *Poloniex) GetHistoricCandlesExtended(ctx context.Context, pair currency return req.ProcessResponse(timeSeries) } -// GetAvailableTransferChains returns the available transfer blockchains for the specific -// cryptocurrency -func (p *Poloniex) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { - currencies, err := p.GetCurrencies(ctx) +// GetAvailableTransferChains returns the available transfer blockchains for the specific cryptocurrency +func (e *Exchange) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) { + currencies, err := e.GetCurrencies(ctx) if err != nil { return nil, err } @@ -1020,30 +1019,30 @@ func (p *Poloniex) GetAvailableTransferChains(ctx context.Context, cryptocurrenc } // GetServerTime returns the current exchange server time. -func (p *Poloniex) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - return p.GetTimestamp(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + return e.GetTimestamp(ctx) } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (p *Poloniex) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { // TODO: implement with API upgrade return nil, common.ErrNotYetImplemented } // GetLatestFundingRates returns the latest funding rates data -func (p *Poloniex) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { // TODO: implement with API upgrade return nil, common.ErrNotYetImplemented } // UpdateOrderExecutionLimits updates order execution limits -func (p *Poloniex) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (p *Poloniex) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := p.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index 86b293d0000..cf72c23a635 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -38,21 +38,21 @@ const ( privateRedeemCoupon = "RedeemYobicode" ) -// Yobit is the overarching type across the Yobit package -type Yobit struct { +// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Yobit +type Exchange struct { exchange.Base } // GetInfo returns the Yobit info -func (y *Yobit) GetInfo(ctx context.Context) (Info, error) { +func (e *Exchange) GetInfo(ctx context.Context) (Info, error) { resp := Info{} path := fmt.Sprintf("/%s/%s/", apiPublicVersion, publicInfo) - return resp, y.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTicker returns a ticker for a specific currency -func (y *Yobit) GetTicker(ctx context.Context, symbol string) (map[string]Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string) (map[string]Ticker, error) { type Response struct { Data map[string]Ticker } @@ -60,11 +60,11 @@ func (y *Yobit) GetTicker(ctx context.Context, symbol string) (map[string]Ticker response := Response{} path := fmt.Sprintf("/%s/%s/%s", apiPublicVersion, publicTicker, symbol) - return response.Data, y.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) + return response.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) } // GetDepth returns the depth for a specific currency -func (y *Yobit) GetDepth(ctx context.Context, symbol string) (Orderbook, error) { +func (e *Exchange) GetDepth(ctx context.Context, symbol string) (Orderbook, error) { type Response struct { Data map[string]Orderbook } @@ -73,18 +73,18 @@ func (y *Yobit) GetDepth(ctx context.Context, symbol string) (Orderbook, error) path := fmt.Sprintf("/%s/%s/%s", apiPublicVersion, publicDepth, symbol) return response.Data[symbol], - y.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) + e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) } // GetTrades returns the trades for a specific currency -func (y *Yobit) GetTrades(ctx context.Context, symbol string) ([]Trade, error) { +func (e *Exchange) GetTrades(ctx context.Context, symbol string) ([]Trade, error) { type respDataHolder struct { Data map[string][]Trade } var dataHolder respDataHolder path := "/" + apiPublicVersion + "/" + publicTrades + "/" + symbol - err := y.SendHTTPRequest(ctx, exchange.RestSpot, path, &dataHolder.Data) + err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &dataHolder.Data) if err != nil { return nil, err } @@ -96,10 +96,10 @@ func (y *Yobit) GetTrades(ctx context.Context, symbol string) ([]Trade, error) { } // GetAccountInformation returns a users account info -func (y *Yobit) GetAccountInformation(ctx context.Context) (AccountInfo, error) { +func (e *Exchange) GetAccountInformation(ctx context.Context) (AccountInfo, error) { result := AccountInfo{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateAccountInfo, url.Values{}, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateAccountInfo, url.Values{}, &result) if err != nil { return result, err } @@ -110,7 +110,7 @@ func (y *Yobit) GetAccountInformation(ctx context.Context) (AccountInfo, error) } // Trade places an order and returns the order ID if successful or an error -func (y *Yobit) Trade(ctx context.Context, pair, orderType string, amount, price float64) (int64, error) { +func (e *Exchange) Trade(ctx context.Context, pair, orderType string, amount, price float64) (int64, error) { req := url.Values{} req.Add("pair", pair) req.Add("type", strings.ToLower(orderType)) @@ -119,7 +119,7 @@ func (y *Yobit) Trade(ctx context.Context, pair, orderType string, amount, price result := TradeOrderResponse{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTrade, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTrade, req, &result) if err != nil { return int64(result.OrderID), err } @@ -130,33 +130,33 @@ func (y *Yobit) Trade(ctx context.Context, pair, orderType string, amount, price } // GetOpenOrders returns the active orders for a specific currency -func (y *Yobit) GetOpenOrders(ctx context.Context, pair string) (map[string]ActiveOrders, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, pair string) (map[string]ActiveOrders, error) { req := url.Values{} req.Add("pair", pair) result := map[string]ActiveOrders{} - return result, y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateActiveOrders, req, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateActiveOrders, req, &result) } // GetOrderInformation returns the order info for a specific order ID -func (y *Yobit) GetOrderInformation(ctx context.Context, orderID int64) (map[string]OrderInfo, error) { +func (e *Exchange) GetOrderInformation(ctx context.Context, orderID int64) (map[string]OrderInfo, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(orderID, 10)) result := map[string]OrderInfo{} - return result, y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateOrderInfo, req, &result) + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateOrderInfo, req, &result) } // CancelExistingOrder cancels an order for a specific order ID -func (y *Yobit) CancelExistingOrder(ctx context.Context, orderID int64) error { +func (e *Exchange) CancelExistingOrder(ctx context.Context, orderID int64) error { req := url.Values{} req.Add("order_id", strconv.FormatInt(orderID, 10)) result := CancelOrder{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCancelOrder, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCancelOrder, req, &result) if err != nil { return err } @@ -167,7 +167,7 @@ func (y *Yobit) CancelExistingOrder(ctx context.Context, orderID int64) error { } // GetTradeHistory returns the trade history -func (y *Yobit) GetTradeHistory(ctx context.Context, tidFrom, count, tidEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { +func (e *Exchange) GetTradeHistory(ctx context.Context, tidFrom, count, tidEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { req := url.Values{} req.Add("from", strconv.FormatInt(tidFrom, 10)) req.Add("count", strconv.FormatInt(count, 10)) @@ -180,7 +180,7 @@ func (y *Yobit) GetTradeHistory(ctx context.Context, tidFrom, count, tidEnd, sin result := TradeHistoryResponse{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTradeHistory, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTradeHistory, req, &result) if err != nil { return nil, err } @@ -192,7 +192,7 @@ func (y *Yobit) GetTradeHistory(ctx context.Context, tidFrom, count, tidEnd, sin } // GetCryptoDepositAddress returns the deposit address for a specific currency -func (y *Yobit) GetCryptoDepositAddress(ctx context.Context, coin string, createNew bool) (*DepositAddress, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, coin string, createNew bool) (*DepositAddress, error) { req := url.Values{} req.Add("coinName", coin) if createNew { @@ -200,7 +200,7 @@ func (y *Yobit) GetCryptoDepositAddress(ctx context.Context, coin string, create } var result DepositAddress - err := y.SendAuthenticatedHTTPRequest(ctx, + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateGetDepositAddress, req, @@ -216,7 +216,7 @@ func (y *Yobit) GetCryptoDepositAddress(ctx context.Context, coin string, create } // WithdrawCoinsToAddress initiates a withdrawal to a specified address -func (y *Yobit) WithdrawCoinsToAddress(ctx context.Context, coin string, amount float64, address string) (WithdrawCoinsToAddress, error) { +func (e *Exchange) WithdrawCoinsToAddress(ctx context.Context, coin string, amount float64, address string) (WithdrawCoinsToAddress, error) { req := url.Values{} req.Add("coinName", coin) req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -224,7 +224,7 @@ func (y *Yobit) WithdrawCoinsToAddress(ctx context.Context, coin string, amount result := WithdrawCoinsToAddress{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateWithdrawCoinsToAddress, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateWithdrawCoinsToAddress, req, &result) if err != nil { return result, err } @@ -235,14 +235,14 @@ func (y *Yobit) WithdrawCoinsToAddress(ctx context.Context, coin string, amount } // CreateCoupon creates an exchange coupon for a specific currency -func (y *Yobit) CreateCoupon(ctx context.Context, currency string, amount float64) (CreateCoupon, error) { +func (e *Exchange) CreateCoupon(ctx context.Context, currency string, amount float64) (CreateCoupon, error) { req := url.Values{} req.Add("currency", currency) req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result CreateCoupon - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCreateCoupon, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCreateCoupon, req, &result) if err != nil { return result, err } @@ -253,13 +253,13 @@ func (y *Yobit) CreateCoupon(ctx context.Context, currency string, amount float6 } // RedeemCoupon redeems an exchange coupon -func (y *Yobit) RedeemCoupon(ctx context.Context, coupon string) (RedeemCoupon, error) { +func (e *Exchange) RedeemCoupon(ctx context.Context, coupon string) (RedeemCoupon, error) { req := url.Values{} req.Add("coupon", coupon) result := RedeemCoupon{} - err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateRedeemCoupon, req, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateRedeemCoupon, req, &result) if err != nil { return result, err } @@ -270,8 +270,8 @@ func (y *Yobit) RedeemCoupon(ctx context.Context, coupon string) (RedeemCoupon, } // SendHTTPRequest sends an unauthenticated HTTP request -func (y *Yobit) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { - endpoint, err := y.API.Endpoints.GetURL(ep) +func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error { + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -280,23 +280,23 @@ func (y *Yobit) SendHTTPRequest(ctx context.Context, ep exchange.URL, path strin Method: http.MethodGet, Path: endpoint + path, Result: result, - Verbose: y.Verbose, - HTTPDebugging: y.HTTPDebugging, - HTTPRecording: y.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, } - return y.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to Yobit -func (y *Yobit) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) (err error) { - creds, err := y.GetCredentials(ctx) +func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) (err error) { + creds, err := e.GetCredentials(ctx) if err != nil { return err } - endpoint, err := y.API.Endpoints.GetURL(ep) + endpoint, err := e.API.Endpoints.GetURL(ep) if err != nil { return err } @@ -304,8 +304,8 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.UR params = url.Values{} } - return y.SendPayload(ctx, request.Unset, func() (*request.Item, error) { - n := y.Requester.GetNonce(nonce.Unix).String() + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { + n := e.Requester.GetNonce(nonce.Unix).String() params.Set("nonce", n) params.Set("method", path) @@ -328,15 +328,15 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.UR Body: strings.NewReader(encoded), Result: result, NonceEnabled: true, - Verbose: y.Verbose, - HTTPDebugging: y.HTTPDebugging, - HTTPRecording: y.HTTPRecording, + Verbose: e.Verbose, + HTTPDebugging: e.HTTPDebugging, + HTTPRecording: e.HTTPRecording, }, nil }, request.AuthenticatedRequest) } // GetFee returns an estimate of fee based on type of transaction -func (y *Yobit) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index 4a69bb066aa..8b064ff5214 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -20,7 +20,7 @@ import ( "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" ) -var y *Yobit +var e *Exchange // Please supply your own keys for better unit testing const ( @@ -32,14 +32,14 @@ const ( var testPair = currency.NewBTCUSD().Format(currency.PairFormat{Delimiter: "_"}) func TestMain(m *testing.M) { - y = new(Yobit) - if err := testexch.Setup(y); err != nil { + e = new(Exchange) + if err := testexch.Setup(e); err != nil { log.Fatalf("Yobit Setup error: %s", err) } if apiKey != "" && apiSecret != "" { - y.API.AuthenticatedSupport = true - y.SetCredentials(apiKey, apiSecret, "", "", "", "") + e.API.AuthenticatedSupport = true + e.SetCredentials(apiKey, apiSecret, "", "", "", "") } os.Exit(m.Run()) @@ -47,7 +47,7 @@ func TestMain(m *testing.M) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := y.FetchTradablePairs(t.Context(), asset.Spot) + _, err := e.FetchTradablePairs(t.Context(), asset.Spot) if err != nil { t.Errorf("FetchTradablePairs err: %s", err) } @@ -55,7 +55,7 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetInfo(t *testing.T) { t.Parallel() - _, err := y.GetInfo(t.Context()) + _, err := e.GetInfo(t.Context()) if err != nil { t.Error("GetInfo() error") } @@ -63,25 +63,25 @@ func TestGetInfo(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := y.GetTicker(t.Context(), testPair.String()) + _, err := e.GetTicker(t.Context(), testPair.String()) assert.NoError(t, err, "GetTicker should not error") } func TestGetDepth(t *testing.T) { t.Parallel() - _, err := y.GetDepth(t.Context(), testPair.String()) + _, err := e.GetDepth(t.Context(), testPair.String()) assert.NoError(t, err, "GetDepth should not error") } func TestGetTrades(t *testing.T) { t.Parallel() - _, err := y.GetTrades(t.Context(), testPair.String()) + _, err := e.GetTrades(t.Context(), testPair.String()) assert.NoError(t, err, "GetTrades should not error") } func TestGetAccountInfo(t *testing.T) { t.Parallel() - _, err := y.UpdateAccountInfo(t.Context(), asset.Spot) + _, err := e.UpdateAccountInfo(t.Context(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -89,7 +89,7 @@ func TestGetAccountInfo(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() - _, err := y.GetOpenOrders(t.Context(), "") + _, err := e.GetOpenOrders(t.Context(), "") if err == nil { t.Error("GetOpenOrders() Expected error") } @@ -97,8 +97,8 @@ func TestGetOpenOrders(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, y) - _, err := y.GetOrderInfo(t.Context(), "1337", currency.NewBTCUSD(), asset.Spot) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) + _, err := e.GetOrderInfo(t.Context(), "1337", currency.NewBTCUSD(), asset.Spot) if err != nil { t.Error(err) } @@ -106,9 +106,9 @@ func TestGetOrderInfo(t *testing.T) { func TestGetCryptoDepositAddress(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, y) + sharedtestvalues.SkipTestIfCredentialsUnset(t, e) - _, err := y.GetCryptoDepositAddress(t.Context(), "bTc", false) + _, err := e.GetCryptoDepositAddress(t.Context(), "bTc", false) if err != nil { t.Error(err) } @@ -116,7 +116,7 @@ func TestGetCryptoDepositAddress(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - err := y.CancelExistingOrder(t.Context(), 1337) + err := e.CancelExistingOrder(t.Context(), 1337) if err == nil { t.Error("CancelOrder() Expected error") } @@ -124,7 +124,7 @@ func TestCancelOrder(t *testing.T) { func TestTrade(t *testing.T) { t.Parallel() - _, err := y.Trade(t.Context(), "", order.Buy.String(), 0, 0) + _, err := e.Trade(t.Context(), "", order.Buy.String(), 0, 0) if err == nil { t.Error("Trade() Expected error") } @@ -132,7 +132,7 @@ func TestTrade(t *testing.T) { func TestWithdrawCoinsToAddress(t *testing.T) { t.Parallel() - _, err := y.WithdrawCoinsToAddress(t.Context(), "", 0, "") + _, err := e.WithdrawCoinsToAddress(t.Context(), "", 0, "") if err == nil { t.Error("WithdrawCoinsToAddress() Expected error") } @@ -140,7 +140,7 @@ func TestWithdrawCoinsToAddress(t *testing.T) { func TestCreateYobicode(t *testing.T) { t.Parallel() - _, err := y.CreateCoupon(t.Context(), "bla", 0) + _, err := e.CreateCoupon(t.Context(), "bla", 0) if err == nil { t.Error("CreateYobicode() Expected error") } @@ -148,7 +148,7 @@ func TestCreateYobicode(t *testing.T) { func TestRedeemYobicode(t *testing.T) { t.Parallel() - _, err := y.RedeemCoupon(t.Context(), "bla2") + _, err := e.RedeemCoupon(t.Context(), "bla2") if err == nil { t.Error("RedeemYobicode() Expected error") } @@ -170,11 +170,11 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { feeBuilder := setFeeBuilder() - _, err := y.GetFeeByType(t.Context(), feeBuilder) + _, err := e.GetFeeByType(t.Context(), feeBuilder) if err != nil { t.Fatal(err) } - if !sharedtestvalues.AreAPICredentialsSet(y) { + if !sharedtestvalues.AreAPICredentialsSet(e) { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) } @@ -189,7 +189,7 @@ func TestGetFee(t *testing.T) { feeBuilder := setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } @@ -197,53 +197,53 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Invalid currency feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee QIWI @@ -251,7 +251,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD feeBuilder.BankTransactionType = exchange.Qiwi - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Wire @@ -259,7 +259,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD feeBuilder.BankTransactionType = exchange.WireTransfer - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Payeer @@ -267,7 +267,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD feeBuilder.BankTransactionType = exchange.Payeer - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Capitalist @@ -275,7 +275,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.RUR feeBuilder.BankTransactionType = exchange.Capitalist - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee AdvCash @@ -283,7 +283,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD feeBuilder.BankTransactionType = exchange.AdvCash - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee PerfectMoney @@ -291,7 +291,7 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.RUR feeBuilder.BankTransactionType = exchange.PerfectMoney - if _, err := y.GetFee(feeBuilder); err != nil { + if _, err := e.GetFee(feeBuilder); err != nil { t.Error(err) } } @@ -299,7 +299,7 @@ func TestGetFee(t *testing.T) { func TestFormatWithdrawPermissions(t *testing.T) { t.Parallel() expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText - withdrawPermissions := y.FormatWithdrawPermissions() + withdrawPermissions := e.FormatWithdrawPermissions() if withdrawPermissions != expectedResult { t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions) } @@ -314,10 +314,10 @@ func TestGetActiveOrders(t *testing.T) { Side: order.AnySide, } - _, err := y.GetActiveOrders(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(y) && err != nil { + _, err := e.GetActiveOrders(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get open orders: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -333,10 +333,10 @@ func TestGetOrderHistory(t *testing.T) { Side: order.AnySide, } - _, err := y.GetOrderHistory(t.Context(), &getOrdersRequest) - if sharedtestvalues.AreAPICredentialsSet(y) && err != nil { + _, err := e.GetOrderHistory(t.Context(), &getOrdersRequest) + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not get order history: %s", err) - } else if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } @@ -345,10 +345,10 @@ func TestGetOrderHistory(t *testing.T) { // ---------------------------------------------------------------------------------------------------------------------------- func TestSubmitOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) orderSubmission := &order.Submit{ - Exchange: y.Name, + Exchange: e.Name, Pair: currency.Pair{ Delimiter: "_", Base: currency.BTC, @@ -361,17 +361,17 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := y.SubmitOrder(t.Context(), orderSubmission) - if sharedtestvalues.AreAPICredentialsSet(y) && (err != nil || response.Status != order.New) { + response, err := e.SubmitOrder(t.Context(), orderSubmission) + if sharedtestvalues.AreAPICredentialsSet(e) && (err != nil || response.Status != order.New) { t.Errorf("Order failed to be placed: %v", err) - } else if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + } else if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } } func TestCancelExchangeOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -381,18 +381,18 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := y.CancelOrder(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + err := e.CancelOrder(t.Context(), orderCancellation) + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(y) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } } func TestCancelAllExchangeOrders(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) currencyPair := currency.NewPair(currency.LTC, currency.BTC) orderCancellation := &order.Cancel{ @@ -402,12 +402,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := y.CancelAllOrders(t.Context(), orderCancellation) + resp, err := e.CancelAllOrders(t.Context(), orderCancellation) - if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(y) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Could not cancel orders: %v", err) } @@ -418,9 +418,9 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) - _, err := y.ModifyOrder(t.Context(), + _, err := e.ModifyOrder(t.Context(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") @@ -429,10 +429,10 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawCryptoRequest := withdraw.Request{ - Exchange: y.Name, + Exchange: e.Name, Amount: -1, Currency: currency.BTC, Description: "WITHDRAW IT ALL", @@ -441,22 +441,22 @@ func TestWithdraw(t *testing.T) { }, } - _, err := y.WithdrawCryptocurrencyFunds(t.Context(), + _, err := e.WithdrawCryptocurrencyFunds(t.Context(), &withdrawCryptoRequest) - if !sharedtestvalues.AreAPICredentialsSet(y) && err == nil { + if !sharedtestvalues.AreAPICredentialsSet(e) && err == nil { t.Error("Expecting an error when no keys are set") } - if sharedtestvalues.AreAPICredentialsSet(y) && err != nil { + if sharedtestvalues.AreAPICredentialsSet(e) && err != nil { t.Errorf("Withdraw failed to be placed: %v", err) } } func TestWithdrawFiat(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := y.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -466,10 +466,10 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCannotManipulateOrders(t, y, canManipulateRealOrders) + sharedtestvalues.SkipTestIfCannotManipulateOrders(t, e, canManipulateRealOrders) withdrawFiatRequest := withdraw.Request{} - _, err := y.WithdrawFiatFundsToInternationalBank(t.Context(), + _, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", @@ -479,13 +479,13 @@ func TestWithdrawInternationalBank(t *testing.T) { } func TestGetDepositAddress(t *testing.T) { - if sharedtestvalues.AreAPICredentialsSet(y) { - _, err := y.GetDepositAddress(t.Context(), currency.BTC, "", "") + if sharedtestvalues.AreAPICredentialsSet(e) { + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err != nil { t.Error(err) } } else { - _, err := y.GetDepositAddress(t.Context(), currency.BTC, "", "") + _, err := e.GetDepositAddress(t.Context(), currency.BTC, "", "") if err == nil { t.Error("GetDepositAddress() error") } @@ -493,24 +493,24 @@ func TestGetDepositAddress(t *testing.T) { } func TestGetRecentTrades(t *testing.T) { - _, err := y.GetRecentTrades(t.Context(), testPair, asset.Spot) + _, err := e.GetRecentTrades(t.Context(), testPair, asset.Spot) assert.NoError(t, err, "GetRecentTrades should not error") } func TestGetHistoricTrades(t *testing.T) { - _, err := y.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) assert.ErrorIs(t, err, common.ErrFunctionNotSupported) } func TestUpdateTicker(t *testing.T) { t.Parallel() - _, err := y.UpdateTicker(t.Context(), testPair, asset.Spot) + _, err := e.UpdateTicker(t.Context(), testPair, asset.Spot) assert.NoError(t, err, "UpdateTicker should not error") } func TestUpdateTickers(t *testing.T) { t.Parallel() - err := y.UpdateTickers(t.Context(), asset.Spot) + err := e.UpdateTickers(t.Context(), asset.Spot) if err != nil { t.Error(err) } @@ -518,7 +518,7 @@ func TestUpdateTickers(t *testing.T) { func TestWrapperGetServerTime(t *testing.T) { t.Parallel() - st, err := y.GetServerTime(t.Context(), asset.Spot) + st, err := e.GetServerTime(t.Context(), asset.Spot) require.NoError(t, err) if st.IsZero() { @@ -528,12 +528,12 @@ func TestWrapperGetServerTime(t *testing.T) { func TestGetCurrencyTradeURL(t *testing.T) { t.Parallel() - testexch.UpdatePairsOnce(t, y) - for _, a := range y.GetAssetTypes(false) { - pairs, err := y.CurrencyPairs.GetPairs(a, false) + testexch.UpdatePairsOnce(t, e) + for _, a := range e.GetAssetTypes(false) { + pairs, err := e.CurrencyPairs.GetPairs(a, false) require.NoErrorf(t, err, "cannot get pairs for %s", a) require.NotEmptyf(t, pairs, "no pairs for %s", a) - resp, err := y.GetCurrencyTradeURL(t.Context(), a, pairs[0]) + resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0]) require.NoError(t, err) assert.NotEmpty(t, resp) } diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index 43107419870..327243de61c 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -30,21 +30,21 @@ import ( ) // SetDefaults sets current default value for Yobit -func (y *Yobit) SetDefaults() { - y.Name = "Yobit" - y.Enabled = true - y.Verbose = true - y.API.CredentialsValidator.RequiresKey = true - y.API.CredentialsValidator.RequiresSecret = true +func (e *Exchange) SetDefaults() { + e.Name = "Yobit" + e.Enabled = true + e.Verbose = true + e.API.CredentialsValidator.RequiresKey = true + e.API.CredentialsValidator.RequiresSecret = true requestFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter, Separator: currency.DashDelimiter} configFmt := ¤cy.PairFormat{Delimiter: currency.UnderscoreDelimiter, Uppercase: true} - err := y.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) + err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot) if err != nil { log.Errorln(log.ExchangeSys, err) } - y.Features = exchange.Features{ + e.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ REST: true, Websocket: false, @@ -74,15 +74,15 @@ func (y *Yobit) SetDefaults() { }, } - y.Requester, err = request.New(y.Name, + e.Requester, err = request.New(e.Name, common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout), // Server responses are cached every 2 seconds. request.WithLimiter(request.NewBasicRateLimit(time.Second, 1, 1))) if err != nil { log.Errorln(log.ExchangeSys, err) } - y.API.Endpoints = y.NewEndpoints() - err = y.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + e.API.Endpoints = e.NewEndpoints() + err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: apiPublicURL, exchange.RestSpotSupplementary: apiPrivateURL, }) @@ -92,20 +92,20 @@ func (y *Yobit) SetDefaults() { } // Setup sets exchange configuration parameters for Yobit -func (y *Yobit) Setup(exch *config.Exchange) error { +func (e *Exchange) Setup(exch *config.Exchange) error { if err := exch.Validate(); err != nil { return err } if !exch.Enabled { - y.SetEnabled(false) + e.SetEnabled(false) return nil } - return y.SetupDefaults(exch) + return e.SetupDefaults(exch) } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (y *Yobit) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { - info, err := y.GetInfo(ctx) +func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) { + info, err := e.GetInfo(ctx) if err != nil { return nil, err } @@ -126,36 +126,36 @@ func (y *Yobit) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency. // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (y *Yobit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { - pairs, err := y.FetchTradablePairs(ctx, asset.Spot) +func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } - err = y.UpdatePairs(pairs, asset.Spot, false, forceUpdate) + err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate) if err != nil { return err } - return y.EnsureOnePairEnabled() + return e.EnsureOnePairEnabled() } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (y *Yobit) UpdateTickers(ctx context.Context, a asset.Item) error { - enabledPairs, err := y.GetEnabledPairs(a) +func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error { + enabledPairs, err := e.GetEnabledPairs(a) if err != nil { return err } - pairsCollated, err := y.FormatExchangeCurrencies(enabledPairs, a) + pairsCollated, err := e.FormatExchangeCurrencies(enabledPairs, a) if err != nil { return err } - result, err := y.GetTicker(ctx, pairsCollated) + result, err := e.GetTicker(ctx, pairsCollated) if err != nil { return err } for i := range enabledPairs { - fPair, err := y.FormatExchangeCurrency(enabledPairs[i], a) + fPair, err := e.FormatExchangeCurrency(enabledPairs[i], a) if err != nil { return err } @@ -173,7 +173,7 @@ func (y *Yobit) UpdateTickers(ctx context.Context, a asset.Item) error { Low: resultCurr.Low, QuoteVolume: resultCurr.VolumeCurrent, Volume: resultCurr.Vol, - ExchangeName: y.Name, + ExchangeName: e.Name, AssetType: a, }) if err != nil { @@ -184,32 +184,32 @@ func (y *Yobit) UpdateTickers(ctx context.Context, a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (y *Yobit) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { - if err := y.UpdateTickers(ctx, a); err != nil { +func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + if err := e.UpdateTickers(ctx, a); err != nil { return nil, err } - return ticker.GetTicker(y.Name, p, a) + return ticker.GetTicker(e.Name, p, a) } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { +func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) { if p.IsEmpty() { return nil, currency.ErrCurrencyPairEmpty } - if err := y.CurrencyPairs.IsAssetEnabled(assetType); err != nil { + if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil { return nil, err } book := &orderbook.Book{ - Exchange: y.Name, + Exchange: e.Name, Pair: p, Asset: assetType, - ValidateOrderbook: y.ValidateOrderbook, + ValidateOrderbook: e.ValidateOrderbook, } - fPair, err := y.FormatExchangeCurrency(p, assetType) + fPair, err := e.FormatExchangeCurrency(p, assetType) if err != nil { return book, err } - orderbookNew, err := y.GetDepth(ctx, fPair.String()) + orderbookNew, err := e.GetDepth(ctx, fPair.String()) if err != nil { return book, err } @@ -233,15 +233,15 @@ func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType if err != nil { return book, err } - return orderbook.Get(y.Name, p, assetType) + return orderbook.Get(e.Name, p, assetType) } // UpdateAccountInfo retrieves balances for all enabled currencies for the // Yobit exchange -func (y *Yobit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { +func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings - response.Exchange = y.Name - accountBalance, err := y.GetAccountInformation(ctx) + response.Exchange = e.Name + accountBalance, err := e.GetAccountInformation(ctx) if err != nil { return response, err } @@ -266,7 +266,7 @@ func (y *Yobit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac Currencies: currencies, }) - creds, err := y.GetCredentials(ctx) + creds, err := e.GetCredentials(ctx) if err != nil { return account.Holdings{}, err } @@ -280,25 +280,25 @@ func (y *Yobit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (ac // GetAccountFundingHistory returns funding history, deposits and // withdrawals -func (y *Yobit) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { +func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (y *Yobit) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { +func (e *Exchange) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) { return nil, common.ErrFunctionNotSupported } // GetRecentTrades returns the most recent trades for a currency and asset -func (y *Yobit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error - p, err = y.FormatExchangeCurrency(p, assetType) + p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData []Trade - tradeData, err = y.GetTrades(ctx, p.String()) + tradeData, err = e.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -310,7 +310,7 @@ func (y *Yobit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType side = order.Sell } resp[i] = trade.Data{ - Exchange: y.Name, + Exchange: e.Name, TID: strconv.FormatInt(tradeData[i].TID, 10), CurrencyPair: p, AssetType: assetType, @@ -321,7 +321,7 @@ func (y *Yobit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } } - err = y.AddTradesToBuffer(resp...) + err = e.AddTradesToBuffer(resp...) if err != nil { return nil, err } @@ -331,14 +331,14 @@ func (y *Yobit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType } // GetHistoricTrades returns historic trade data within the timeframe provided -func (y *Yobit) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // Yobit only supports limit orders -func (y *Yobit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { - if err := s.Validate(y.GetTradingRequirements()); err != nil { +func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) { + if err := s.Validate(e.GetTradingRequirements()); err != nil { return nil, err } @@ -346,12 +346,12 @@ func (y *Yobit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit return nil, errors.New("only limit orders are allowed") } - fPair, err := y.FormatExchangeCurrency(s.Pair, s.AssetType) + fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType) if err != nil { return nil, err } - response, err := y.Trade(ctx, + response, err := e.Trade(ctx, fPair.String(), s.Side.String(), s.Amount, @@ -364,12 +364,12 @@ func (y *Yobit) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Submit // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (y *Yobit) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { +func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (y *Yobit) CancelOrder(ctx context.Context, o *order.Cancel) error { +func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -379,32 +379,32 @@ func (y *Yobit) CancelOrder(ctx context.Context, o *order.Cancel) error { return err } - return y.CancelExistingOrder(ctx, orderIDInt) + return e.CancelExistingOrder(ctx, orderIDInt) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (y *Yobit) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { +func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) { return nil, common.ErrFunctionNotSupported } // CancelAllOrders cancels all orders associated with a currency pair -func (y *Yobit) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { +func (e *Exchange) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - enabledPairs, err := y.GetEnabledPairs(asset.Spot) + enabledPairs, err := e.GetEnabledPairs(asset.Spot) if err != nil { return cancelAllOrdersResponse, err } allActiveOrders := make([]map[string]ActiveOrders, len(enabledPairs)) for i := range enabledPairs { - fCurr, err := y.FormatExchangeCurrency(enabledPairs[i], asset.Spot) + fCurr, err := e.FormatExchangeCurrency(enabledPairs[i], asset.Spot) if err != nil { return cancelAllOrdersResponse, err } - activeOrdersForPair, err := y.GetOpenOrders(ctx, fCurr.String()) + activeOrdersForPair, err := e.GetOpenOrders(ctx, fCurr.String()) if err != nil { return cancelAllOrdersResponse, err } @@ -420,7 +420,7 @@ func (y *Yobit) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Can continue } - err = y.CancelExistingOrder(ctx, orderIDInt) + err = e.CancelExistingOrder(ctx, orderIDInt) if err != nil { cancelAllOrdersResponse.Status[key] = err.Error() } @@ -431,16 +431,16 @@ func (y *Yobit) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.Can } // GetOrderInfo returns order information based on order ID -func (y *Yobit) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { iOID, err := strconv.ParseInt(orderID, 10, 64) if err != nil { return nil, err } - format, err := y.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } - resp, err := y.GetOrderInformation(ctx, iOID) + resp, err := e.GetOrderInformation(ctx, iOID) if err != nil { return nil, err } @@ -466,20 +466,20 @@ func (y *Yobit) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pai Side: side, Date: orderInfo.TimestampCreated.Time(), Pair: symbol, - Exchange: y.Name, + Exchange: e.Name, }, nil } return nil, fmt.Errorf("%w %v", order.ErrOrderNotFound, orderID) } // GetDepositAddress returns a deposit address for a specified currency -func (y *Yobit) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { +func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) { if cryptocurrency.Equal(currency.XRP) { // {"success":1,"return":{"status":"online","blocks":65778672,"address":996707783,"processed_amount":0.00000000,"server_time":1629425030}} return nil, errors.New("XRP isn't supported as the API does not return a valid address") } - addr, err := y.GetCryptoDepositAddress(ctx, cryptocurrency.String(), false) + addr, err := e.GetCryptoDepositAddress(ctx, cryptocurrency.String(), false) if err != nil { return nil, err } @@ -489,11 +489,11 @@ func (y *Yobit) GetDepositAddress(ctx context.Context, cryptocurrency currency.C // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (y *Yobit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := y.WithdrawCoinsToAddress(ctx, + resp, err := e.WithdrawCoinsToAddress(ctx, withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Crypto.Address) @@ -508,36 +508,36 @@ func (y *Yobit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (y *Yobit) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (y *Yobit) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (y *Yobit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if feeBuilder == nil { return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer) } - if !y.AreCredentialsValid(ctx) && // Todo check connection status + if !e.AreCredentialsValid(ctx) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return y.GetFee(feeBuilder) + return e.GetFee(feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err } - format, err := y.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -545,12 +545,12 @@ func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques var orders []order.Detail for x := range req.Pairs { var fCurr currency.Pair - fCurr, err = y.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + fCurr, err = e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } var resp map[string]ActiveOrders - resp, err = y.GetOpenOrders(ctx, fCurr.String()) + resp, err = e.GetOpenOrders(ctx, fCurr.String()) if err != nil { return nil, err } @@ -573,16 +573,16 @@ func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.MultiOrderReques Side: side, Date: resp[id].TimestampCreated.Time(), Pair: symbol, - Exchange: y.Name, + Exchange: e.Name, }) } } - return req.Filter(y.Name, orders), nil + return req.Filter(e.Name, orders), nil } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { +func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) { err := req.Validate() if err != nil { return nil, err @@ -591,12 +591,12 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques var allOrders []TradeHistory for x := range req.Pairs { var fPair currency.Pair - fPair, err = y.FormatExchangeCurrency(req.Pairs[x], asset.Spot) + fPair, err = e.FormatExchangeCurrency(req.Pairs[x], asset.Spot) if err != nil { return nil, err } var resp map[string]TradeHistory - resp, err = y.GetTradeHistory(ctx, + resp, err = e.GetTradeHistory(ctx, 0, 10000, math.MaxInt64, @@ -613,7 +613,7 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques } } - format, err := y.GetPairFormat(asset.Spot, false) + format, err := e.GetPairFormat(asset.Spot, false) if err != nil { return nil, err } @@ -640,34 +640,34 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.MultiOrderReques Status: order.Filled, Date: allOrders[i].Timestamp.Time(), Pair: pair, - Exchange: y.Name, + Exchange: e.Name, } detail.InferCostsAndTimes() orders[i] = detail } - return req.Filter(y.Name, orders), nil + return req.Filter(e.Name, orders), nil } // ValidateAPICredentials validates current credentials used for wrapper // functionality -func (y *Yobit) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { - _, err := y.UpdateAccountInfo(ctx, assetType) - return y.CheckTransientError(err) +func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) + return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (y *Yobit) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (y *Yobit) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { +func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) { return nil, common.ErrFunctionNotSupported } // GetServerTime returns the current exchange server time. -func (y *Yobit) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { - info, err := y.GetInfo(ctx) +func (e *Exchange) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) { + info, err := e.GetInfo(ctx) if err != nil { return time.Time{}, err } @@ -675,23 +675,23 @@ func (y *Yobit) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, err } // GetFuturesContractDetails returns all contracts from the exchange by asset type -func (y *Yobit) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { +func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) { return nil, common.ErrFunctionNotSupported } // GetLatestFundingRates returns the latest funding rates data -func (y *Yobit) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { +func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) { return nil, common.ErrFunctionNotSupported } // UpdateOrderExecutionLimits updates order execution limits -func (y *Yobit) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { +func (e *Exchange) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } // GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair -func (y *Yobit) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { - _, err := y.CurrencyPairs.IsPairEnabled(cp, a) +func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) { + _, err := e.CurrencyPairs.IsPairEnabled(cp, a) if err != nil { return "", err } diff --git a/internal/testing/exchange/exchange_test.go b/internal/testing/exchange/exchange_test.go index 63e6b958386..ee9b6661448 100644 --- a/internal/testing/exchange/exchange_test.go +++ b/internal/testing/exchange/exchange_test.go @@ -14,7 +14,7 @@ import ( // TestSetup exercises Setup func TestSetup(t *testing.T) { - b := new(binance.Binance) + b := new(binance.Exchange) require.NoError(t, Setup(b), "Setup must not error") assert.NotNil(t, b.Websocket, "Websocket should not be nil after Setup") @@ -24,7 +24,7 @@ func TestSetup(t *testing.T) { // TestMockHTTPInstance exercises MockHTTPInstance func TestMockHTTPInstance(t *testing.T) { - b := new(binance.Binance) + b := new(binance.Exchange) require.NoError(t, Setup(b), "Test exchange Setup must not error") require.NoError(t, MockHTTPInstance(b), "MockHTTPInstance with no optional path must not error") require.NoError(t, MockHTTPInstance(b, "api"), "MockHTTPInstance with optional path must not error") @@ -32,6 +32,6 @@ func TestMockHTTPInstance(t *testing.T) { // TestMockWsInstance exercises MockWsInstance func TestMockWsInstance(t *testing.T) { - b := MockWsInstance[binance.Binance](t, mockws.CurryWsMockUpgrader(t, func(_ testing.TB, _ []byte, _ *gws.Conn) error { return nil })) + b := MockWsInstance[binance.Exchange](t, mockws.CurryWsMockUpgrader(t, func(_ testing.TB, _ []byte, _ *gws.Conn) error { return nil })) require.NotNil(t, b, "MockWsInstance must not be nil") }