diff --git a/.github/workflows/amd64.Dockerfile b/.github/workflows/amd64.Dockerfile index 773e8e77..8d89b932 100644 --- a/.github/workflows/amd64.Dockerfile +++ b/.github/workflows/amd64.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24-alpine +FROM golang:1.25-alpine # Install GCC and musl-dev (needed for SQLite library) RUN apk add --no-cache gcc musl-dev diff --git a/.github/workflows/config-versions-lint.yml b/.github/workflows/config-versions-lint.yml index 0aeed42e..5059dd67 100644 --- a/.github/workflows/config-versions-lint.yml +++ b/.github/workflows/config-versions-lint.yml @@ -1,7 +1,7 @@ name: configs-versions-lint on: [push, pull_request] env: - GO_VERSION: 1.24.x + GO_VERSION: 1.25.x jobs: lint: name: config versions lint diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index ac6eb78d..58e7fd56 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -8,8 +8,8 @@ jobs: - uses: actions/checkout@v5 - uses: actions/setup-go@v5 with: - go-version: '1.24.x' + go-version: '1.25.x' - name: golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: v2.1.6 \ No newline at end of file + version: v2.4.0 \ No newline at end of file diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 8d32208b..404e55b3 100644 --- a/.github/workflows/proto-lint.yml +++ b/.github/workflows/proto-lint.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: 1.24.x + go-version: 1.25.x - name: Setup build depends run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a258e22f..7a90b8f3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,7 +1,7 @@ on: [push, pull_request] name: CI env: - GO_VERSION: 1.24.x + GO_VERSION: 1.25.x GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: backend: diff --git a/.golangci.yml b/.golangci.yml index 0fd70a1c..73933f5b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -14,6 +14,7 @@ linters: - unused # disabled by default linters +# - arangolint # - asasalint - asciicheck - bidichk @@ -29,6 +30,7 @@ linters: # - dupl - dupword - durationcheck +# - embeddedstructfieldcheck # - err113 - errchkjson - errname @@ -39,6 +41,7 @@ linters: - fatcontext # - forbidigo - forcetypeassert +# - funcorder # - funlen # - ginkgolinter - gocheckcompilerdirectives @@ -79,6 +82,7 @@ linters: # - nilnil # - nlreturn - noctx +# - noinlineerr - nolintlint # - nonamedreturns - nosprintfhostport @@ -110,8 +114,9 @@ linters: - wastedassign - whitespace # - wrapcheck -# - wsl +# - wsl_v5 # - zerologlint +# - wsl // Deprecated settings: depguard: @@ -130,7 +135,6 @@ linters: gocritic: disabled-checks: - wrapperFunc - - importShadow - methodExprCall - evalOrder enabled-tags: @@ -171,6 +175,9 @@ linters: - linters: - revive text: 'should have a package comment' + - linters: + - revive + text: "var-naming: avoid meaningless package names" paths: - vendor - web/ diff --git a/Dockerfile b/Dockerfile index 6e450612..1d0ab5b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24 as build +FROM golang:1.25 as build WORKDIR /go/src/github.com/thrasher-corp/gocryptotrader COPY . . RUN GO111MODULE=on go mod vendor diff --git a/Makefile b/Makefile index 2969555f..95bddbff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LDFLAGS = -ldflags "-w -s" GCTPKG = github.com/thrasher-corp/gocryptotrader -LINTPKG = github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 +LINTPKG = github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0 GOPATH ?= $(shell go env GOPATH) LINTBIN = $(GOPATH)/bin/golangci-lint GOFUMPTBIN = $(GOPATH)/bin/gofumpt @@ -21,7 +21,7 @@ lint: lint_docker: @command -v docker >/dev/null 2>&1 || (echo "Docker not found. Please install Docker to run this target." && exit 1) - docker run --rm -t -v $(CURDIR):/app -w /app golangci/golangci-lint:v2.1.6 golangci-lint run --verbose + docker run --rm -t -v $(CURDIR):/app -w /app golangci/golangci-lint:v2.4.0 golangci-lint run --verbose check: lint test diff --git a/backtester/engine/grpcserver.go b/backtester/engine/grpcserver.go index 5692ccb2..2d3fb36e 100644 --- a/backtester/engine/grpcserver.go +++ b/backtester/engine/grpcserver.go @@ -67,7 +67,7 @@ func StartRPCServer(server *GRPCServer) error { return err } log.Debugf(log.GRPCSys, "Backtester GRPC server enabled. Starting GRPC server on https://%v.\n", server.config.GRPC.ListenAddress) - lis, err := net.Listen("tcp", server.config.GRPC.ListenAddress) + lis, err := net.Listen("tcp", server.config.GRPC.ListenAddress) //nolint:noctx // TODO: #2006 Replace net.Listen with (*net.ListenConfig).Listen if err != nil { return err } diff --git a/backtester/engine/setup.go b/backtester/engine/setup.go index 8f2ad685..9dbfb9b0 100644 --- a/backtester/engine/setup.go +++ b/backtester/engine/setup.go @@ -636,21 +636,21 @@ func (bt *BackTest) setupExchangeSettings(cfg *config.Config) (*exchange.Exchang return resp, nil } -func (bt *BackTest) loadExchangePairAssetBase(exch string, base, quote currency.Code, ai asset.Item) (gctexchange.IBotExchange, currency.Pair, asset.Item, error) { - e, err := bt.exchangeManager.GetExchangeByName(exch) +func (bt *BackTest) loadExchangePairAssetBase(exchName string, baseCode, quoteCode currency.Code, a asset.Item) (gctexchange.IBotExchange, currency.Pair, asset.Item, error) { + e, err := bt.exchangeManager.GetExchangeByName(exchName) if err != nil { return nil, currency.EMPTYPAIR, asset.Empty, err } var cp, fPair currency.Pair - cp = currency.NewPair(base, quote) + cp = currency.NewPair(baseCode, quoteCode) exchangeBase := e.GetBase() - fPair, err = exchangeBase.FormatExchangeCurrency(cp, ai) + fPair, err = exchangeBase.FormatExchangeCurrency(cp, a) if err != nil { return nil, currency.EMPTYPAIR, asset.Empty, err } - return e, fPair, ai, nil + return e, fPair, a, nil } // getFees will return an exchange's fee rate from GCT's wrapper function @@ -929,8 +929,8 @@ func loadAPIData(cfg *config.Config, exch gctexchange.IBotExchange, fPair curren }, nil } -func setExchangeCredentials(cfg *config.Config, base *gctexchange.Base) error { - if cfg == nil || base == nil || cfg.DataSettings.LiveData == nil { +func setExchangeCredentials(cfg *config.Config, exch *gctexchange.Base) error { + if cfg == nil || exch == nil || cfg.DataSettings.LiveData == nil { return gctcommon.ErrNilPointer } if !cfg.DataSettings.LiveData.RealOrders { @@ -942,15 +942,15 @@ func setExchangeCredentials(cfg *config.Config, base *gctexchange.Base) error { if len(cfg.DataSettings.LiveData.ExchangeCredentials) == 0 { return errNoCredsNoLive } - name := strings.ToLower(base.Name) + name := strings.ToLower(exch.Name) for i := range cfg.DataSettings.LiveData.ExchangeCredentials { if !strings.EqualFold(cfg.DataSettings.LiveData.ExchangeCredentials[i].Exchange, name) || cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.IsEmpty() { - return fmt.Errorf("%v %w, please review your live, real order config", base.GetName(), gctexchange.ErrCredentialsAreEmpty) + return fmt.Errorf("%v %w, please review your live, real order config", exch.GetName(), gctexchange.ErrCredentialsAreEmpty) } - base.API.AuthenticatedSupport = true - base.API.AuthenticatedWebsocketSupport = true - base.SetCredentials( + exch.API.AuthenticatedSupport = true + exch.API.AuthenticatedWebsocketSupport = true + exch.SetCredentials( cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.Key, cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.Secret, cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.ClientID, @@ -958,7 +958,7 @@ func setExchangeCredentials(cfg *config.Config, base *gctexchange.Base) error { cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.PEMKey, cfg.DataSettings.LiveData.ExchangeCredentials[i].Keys.OneTimePassword, ) - _, err := base.GetCredentials(context.TODO()) + _, err := exch.GetCredentials(context.TODO()) if err != nil { return err } diff --git a/backtester/eventhandlers/strategies/binancecashandcarry/binancecashandcarry.go b/backtester/eventhandlers/strategies/binancecashandcarry/binancecashandcarry.go index abf2f969..5efcd99e 100644 --- a/backtester/eventhandlers/strategies/binancecashandcarry/binancecashandcarry.go +++ b/backtester/eventhandlers/strategies/binancecashandcarry/binancecashandcarry.go @@ -125,25 +125,25 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, f funding.IFundingTra // CloseAllPositions is this strategy's implementation on how to // unwind all positions in the event of a closure -func (s *Strategy) CloseAllPositions(holdings []holdings.Holding, prices []data.Event) ([]signal.Event, error) { +func (s *Strategy) CloseAllPositions(h []holdings.Holding, prices []data.Event) ([]signal.Event, error) { var spotSignals, futureSignals []signal.Event signalTime := time.Now().UTC() - for i := range holdings { + for i := range h { for j := range prices { - if prices[j].GetExchange() != holdings[i].Exchange || - prices[j].GetAssetType() != holdings[i].Asset || - !prices[j].Pair().Equal(holdings[i].Pair) { + if prices[j].GetExchange() != h[i].Exchange || + prices[j].GetAssetType() != h[i].Asset || + !prices[j].Pair().Equal(h[i].Pair) { continue } sig := &signal.Signal{ Base: &event.Base{ - Offset: holdings[i].Offset + 1, - Exchange: holdings[i].Exchange, + Offset: h[i].Offset + 1, + Exchange: h[i].Exchange, Time: signalTime, Interval: prices[j].GetInterval(), - CurrencyPair: holdings[i].Pair, + CurrencyPair: h[i].Pair, UnderlyingPair: prices[j].GetUnderlyingPair(), - AssetType: holdings[i].Asset, + AssetType: h[i].Asset, Reasons: []string{"closing position on close"}, }, OpenPrice: prices[j].GetOpenPrice(), @@ -151,9 +151,9 @@ func (s *Strategy) CloseAllPositions(holdings []holdings.Holding, prices []data. LowPrice: prices[j].GetLowPrice(), ClosePrice: prices[j].GetClosePrice(), Volume: prices[j].GetVolume(), - Amount: holdings[i].BaseSize, + Amount: h[i].BaseSize, Direction: order.ClosePosition, - CollateralCurrency: holdings[i].Pair.Base, + CollateralCurrency: h[i].Pair.Base, } if prices[j].GetAssetType().IsFutures() { futureSignals = append(futureSignals, sig) diff --git a/backtester/eventhandlers/strategies/rsi/rsi.go b/backtester/eventhandlers/strategies/rsi/rsi.go index 8b6faa27..d3ed75a7 100644 --- a/backtester/eventhandlers/strategies/rsi/rsi.go +++ b/backtester/eventhandlers/strategies/rsi/rsi.go @@ -73,12 +73,11 @@ func (s *Strategy) OnSignal(d data.Handler, _ funding.IFundingTransferer, _ port if err != nil { return nil, err } - var massagedData []float64 - massagedData, err = s.massageMissingData(dataRange, es.GetTime()) + backfilledData, err := s.backfillMissingData(dataRange, es.GetTime()) if err != nil { return nil, err } - rsi := indicators.RSI(massagedData, int(s.rsiPeriod.IntPart())) + rsi := indicators.RSI(backfilledData, int(s.rsiPeriod.IntPart())) latestRSIValue := decimal.NewFromFloat(rsi[len(rsi)-1]) hasDataAtTime, err := d.HasDataAtTime(latest.GetTime()) if err != nil { @@ -171,16 +170,16 @@ func (s *Strategy) SetDefaults() { s.rsiPeriod = decimal.NewFromInt(14) } -// massageMissingData will replace missing data with the previous candle's data +// backfillMissingData will replace missing data with the previous candle's data // this will ensure that RSI can be calculated correctly // the decision to handle missing data occurs at the strategy level, not all strategies // may wish to modify data -func (s *Strategy) massageMissingData(data []decimal.Decimal, t time.Time) ([]float64, error) { - resp := make([]float64, len(data)) +func (s *Strategy) backfillMissingData(d []decimal.Decimal, t time.Time) ([]float64, error) { + resp := make([]float64, len(d)) var missingDataStreak int64 - for i := range data { - if data[i].IsZero() && i > int(s.rsiPeriod.IntPart()) { - data[i] = data[i-1] + for i := range d { + if d[i].IsZero() && i > int(s.rsiPeriod.IntPart()) { + d[i] = d[i-1] missingDataStreak++ } else { missingDataStreak = 0 @@ -191,7 +190,7 @@ func (s *Strategy) massageMissingData(data []decimal.Decimal, t time.Time) ([]fl t.Format(time.DateTime), base.ErrTooMuchBadData) } - resp[i] = data[i].InexactFloat64() + resp[i] = d[i].InexactFloat64() } return resp, nil } diff --git a/backtester/eventhandlers/strategies/top2bottom2/top2bottom2.go b/backtester/eventhandlers/strategies/top2bottom2/top2bottom2.go index 79ce147a..f69e0bcc 100644 --- a/backtester/eventhandlers/strategies/top2bottom2/top2bottom2.go +++ b/backtester/eventhandlers/strategies/top2bottom2/top2bottom2.go @@ -131,24 +131,23 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, f funding.IFundingTra highData[i] = history[i].GetHighPrice() lowData[i] = history[i].GetLowPrice() } - var massagedCloseData, massagedVolumeData, massagedHighData, massagedLowData []float64 - massagedCloseData, err = s.massageMissingData(closeData, es.GetTime()) + backfilledCloseData, err := s.backfillMissingData(closeData, es.GetTime()) if err != nil { return nil, err } - massagedVolumeData, err = s.massageMissingData(volumeData, es.GetTime()) + backfilledVolumeData, err := s.backfillMissingData(volumeData, es.GetTime()) if err != nil { return nil, err } - massagedHighData, err = s.massageMissingData(highData, es.GetTime()) + backfilledHighData, err := s.backfillMissingData(highData, es.GetTime()) if err != nil { return nil, err } - massagedLowData, err = s.massageMissingData(lowData, es.GetTime()) + backfilledLowData, err := s.backfillMissingData(lowData, es.GetTime()) if err != nil { return nil, err } - mfi := indicators.MFI(massagedHighData, massagedLowData, massagedCloseData, massagedVolumeData, int(s.mfiPeriod.IntPart())) + mfi := indicators.MFI(backfilledHighData, backfilledLowData, backfilledCloseData, backfilledVolumeData, int(s.mfiPeriod.IntPart())) latestMFI := decimal.NewFromFloat(mfi[len(mfi)-1]) hasDataAtTime, err := d[i].HasDataAtTime(latest.GetTime()) if err != nil { @@ -247,16 +246,16 @@ func (s *Strategy) SetDefaults() { s.mfiPeriod = decimal.NewFromInt(14) } -// massageMissingData will replace missing data with the previous candle's data +// backfillMissingData will replace missing data with the previous candle's data // this will ensure that mfi can be calculated correctly // the decision to handle missing data occurs at the strategy level, not all strategies // may wish to modify data -func (s *Strategy) massageMissingData(data []decimal.Decimal, t time.Time) ([]float64, error) { - resp := make([]float64, len(data)) +func (s *Strategy) backfillMissingData(d []decimal.Decimal, t time.Time) ([]float64, error) { + resp := make([]float64, len(d)) var missingDataStreak int64 - for i := range data { - if data[i].IsZero() && i > int(s.mfiPeriod.IntPart()) { - data[i] = data[i-1] + for i := range d { + if d[i].IsZero() && i > int(s.mfiPeriod.IntPart()) { + d[i] = d[i-1] missingDataStreak++ } else { missingDataStreak = 0 @@ -267,7 +266,7 @@ func (s *Strategy) massageMissingData(data []decimal.Decimal, t time.Time) ([]fl t.Format(time.DateTime), base.ErrTooMuchBadData) } - resp[i] = data[i].InexactFloat64() + resp[i] = d[i].InexactFloat64() } return resp, nil } diff --git a/backtester/funding/item.go b/backtester/funding/item.go index 7da21c86..035ec031 100644 --- a/backtester/funding/item.go +++ b/backtester/funding/item.go @@ -92,11 +92,11 @@ func (i *Item) Equal(item *Item) bool { } // BasicEqual checks for equality via passed in values -func (i *Item) BasicEqual(exch string, a asset.Item, currency, pairedCurrency currency.Code) bool { +func (i *Item) BasicEqual(exch string, a asset.Item, ccy, pairedCurrency currency.Code) bool { return i != nil && i.exchange == exch && i.asset == a && - i.currency.Equal(currency) && + i.currency.Equal(ccy) && (i.pairedWith == nil || (i.pairedWith != nil && i.pairedWith.currency.Equal(pairedCurrency))) } diff --git a/cmd/exchange_template/exchange_template.go b/cmd/exchange_template/exchange_template.go index c4d5de5c..3758f4e4 100644 --- a/cmd/exchange_template/exchange_template.go +++ b/cmd/exchange_template/exchange_template.go @@ -1,6 +1,7 @@ package main import ( + "context" "errors" "flag" "fmt" @@ -241,7 +242,7 @@ func saveConfig(exchangeDirectory string, configTestFile *config.Config, newExch } func runCommand(dir, param string) error { - cmd := exec.Command("go", param) + cmd := exec.CommandContext(context.TODO(), "go", param) cmd.Dir = dir out, err := cmd.CombinedOutput() if err != nil { @@ -253,11 +254,12 @@ func runCommand(dir, param string) error { func newFile(path string) { _, err := os.Stat(path) - if os.IsNotExist(err) { - file, err := os.Create(path) - if err != nil { - log.Fatal(err) - } - file.Close() + if !os.IsNotExist(err) { + return } + f, err := os.Create(path) + if err != nil { + log.Fatal(err) + } + f.Close() } diff --git a/cmd/exchange_wrapper_issues/main.go b/cmd/exchange_wrapper_issues/main.go index 3c799c59..7395b10d 100644 --- a/cmd/exchange_wrapper_issues/main.go +++ b/cmd/exchange_wrapper_issues/main.go @@ -285,10 +285,10 @@ func parseOrderType(orderType string) order.Type { } } -func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) []ExchangeAssetPairResponses { +func testWrappers(e exchange.IBotExchange, base *exchange.Base, cfg *Config) []ExchangeAssetPairResponses { response := make([]ExchangeAssetPairResponses, 0) - testOrderSide := parseOrderSide(config.OrderSubmission.OrderSide) - testOrderType := parseOrderType(config.OrderSubmission.OrderType) + testOrderSide := parseOrderSide(cfg.OrderSubmission.OrderSide) + testOrderType := parseOrderType(cfg.OrderSubmission.OrderType) assetTypes := base.GetAssetTypes(false) if assetTypeOverride != "" { a, err := asset.New(assetTypeOverride) @@ -577,8 +577,8 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) feeType := exchange.FeeBuilder{ FeeType: exchange.CryptocurrencyTradeFee, Pair: p, - PurchasePrice: config.OrderSubmission.Price, - Amount: config.OrderSubmission.Amount, + PurchasePrice: cfg.OrderSubmission.Price, + Amount: cfg.OrderSubmission.Amount, } var getFeeByTypeResponse float64 getFeeByTypeResponse, err = e.GetFeeByType(context.TODO(), &feeType) @@ -599,9 +599,9 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Pair: p, Side: testOrderSide, Type: testOrderType, - Amount: config.OrderSubmission.Amount, - Price: config.OrderSubmission.Price, - ClientID: config.OrderSubmission.OrderID, + Amount: cfg.OrderSubmission.Amount, + Price: cfg.OrderSubmission.Price, + ClientID: cfg.OrderSubmission.OrderID, AssetType: assetTypes[i], } var submitOrderResponse *order.SubmitResponse @@ -619,12 +619,12 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) modifyRequest := order.Modify{ - OrderID: config.OrderSubmission.OrderID, + OrderID: cfg.OrderSubmission.OrderID, Type: testOrderType, Side: testOrderSide, Pair: p, - Price: config.OrderSubmission.Price, - Amount: config.OrderSubmission.Amount, + Price: cfg.OrderSubmission.Price, + Amount: cfg.OrderSubmission.Amount, AssetType: assetTypes[i], } modifyOrderResponse, err := e.ModifyOrder(context.TODO(), &modifyRequest) @@ -643,7 +643,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) cancelRequest := order.Cancel{ Side: testOrderSide, Pair: p, - OrderID: config.OrderSubmission.OrderID, + OrderID: cfg.OrderSubmission.OrderID, AssetType: assetTypes[i], } err = e.CancelOrder(context.TODO(), &cancelRequest) @@ -663,7 +663,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) request = append(request, order.Cancel{ Side: testOrderSide, Pair: p, - OrderID: config.OrderSubmission.OrderID, + OrderID: cfg.OrderSubmission.OrderID, AssetType: assetTypes[i], }) @@ -696,14 +696,14 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var r15 *order.Detail - r15, err = e.GetOrderInfo(context.TODO(), config.OrderSubmission.OrderID, p, assetTypes[i]) + r15, err = e.GetOrderInfo(context.TODO(), cfg.OrderSubmission.OrderID, p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() responseContainer.ErrorCount++ } responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{ - SentParams: jsonifyInterface([]any{config.OrderSubmission.OrderID, p, assetTypes[i]}), + SentParams: jsonifyInterface([]any{cfg.OrderSubmission.OrderID, p, assetTypes[i]}), Function: "GetOrderInfo", Error: msg, Response: jsonifyInterface([]any{r15}), @@ -770,8 +770,8 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) feeType = exchange.FeeBuilder{ FeeType: exchange.CryptocurrencyWithdrawalFee, Pair: p, - PurchasePrice: config.OrderSubmission.Price, - Amount: config.OrderSubmission.Amount, + PurchasePrice: cfg.OrderSubmission.Price, + Amount: cfg.OrderSubmission.Amount, } var GetFeeByTypeResponse float64 GetFeeByTypeResponse, err = e.GetFeeByType(context.TODO(), &feeType) @@ -792,7 +792,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Crypto: withdraw.CryptoRequest{ Address: withdrawAddressOverride, }, - Amount: config.OrderSubmission.Amount, + Amount: cfg.OrderSubmission.Amount, } msg = "" err = withdrawRequest.Validate() @@ -815,8 +815,8 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) feeType = exchange.FeeBuilder{ FeeType: exchange.InternationalBankWithdrawalFee, Pair: p, - PurchasePrice: config.OrderSubmission.Price, - Amount: config.OrderSubmission.Amount, + PurchasePrice: cfg.OrderSubmission.Price, + Amount: cfg.OrderSubmission.Amount, FiatCurrency: currency.AUD, BankTransactionType: exchange.WireTransfer, } @@ -836,32 +836,32 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) withdrawRequestFiat := withdraw.Request{ Currency: p.Quote, - Amount: config.OrderSubmission.Amount, + Amount: cfg.OrderSubmission.Amount, Fiat: withdraw.FiatRequest{ Bank: banking.Account{ - AccountName: config.BankDetails.BankAccountName, - AccountNumber: config.BankDetails.BankAccountNumber, - SWIFTCode: config.BankDetails.SwiftCode, - IBAN: config.BankDetails.Iban, - BankPostalCity: config.BankDetails.BankCity, - BankName: config.BankDetails.BankName, - BankAddress: config.BankDetails.BankAddress, - BankCountry: config.BankDetails.BankCountry, - BankPostalCode: config.BankDetails.BankPostalCode, - BankCode: config.BankDetails.BankCode, + AccountName: cfg.BankDetails.BankAccountName, + AccountNumber: cfg.BankDetails.BankAccountNumber, + SWIFTCode: cfg.BankDetails.SwiftCode, + IBAN: cfg.BankDetails.Iban, + BankPostalCity: cfg.BankDetails.BankCity, + BankName: cfg.BankDetails.BankName, + BankAddress: cfg.BankDetails.BankAddress, + BankCountry: cfg.BankDetails.BankCountry, + BankPostalCode: cfg.BankDetails.BankPostalCode, + BankCode: cfg.BankDetails.BankCode, }, - IsExpressWire: config.BankDetails.IsExpressWire, - RequiresIntermediaryBank: config.BankDetails.RequiresIntermediaryBank, - IntermediaryBankName: config.BankDetails.IntermediaryBankName, - IntermediaryBankAccountNumber: config.BankDetails.IntermediaryBankAccountNumber, - IntermediarySwiftCode: config.BankDetails.IntermediarySwiftCode, - IntermediaryIBAN: config.BankDetails.IntermediaryIban, - IntermediaryBankCity: config.BankDetails.IntermediaryBankCity, - IntermediaryBankAddress: config.BankDetails.IntermediaryBankAddress, - IntermediaryBankCountry: config.BankDetails.IntermediaryBankCountry, - IntermediaryBankPostalCode: config.BankDetails.IntermediaryBankPostalCode, - IntermediaryBankCode: config.BankDetails.IntermediaryBankCode, + IsExpressWire: cfg.BankDetails.IsExpressWire, + RequiresIntermediaryBank: cfg.BankDetails.RequiresIntermediaryBank, + IntermediaryBankName: cfg.BankDetails.IntermediaryBankName, + IntermediaryBankAccountNumber: cfg.BankDetails.IntermediaryBankAccountNumber, + IntermediarySwiftCode: cfg.BankDetails.IntermediarySwiftCode, + IntermediaryIBAN: cfg.BankDetails.IntermediaryIban, + IntermediaryBankCity: cfg.BankDetails.IntermediaryBankCity, + IntermediaryBankAddress: cfg.BankDetails.IntermediaryBankAddress, + IntermediaryBankCountry: cfg.BankDetails.IntermediaryBankCountry, + IntermediaryBankPostalCode: cfg.BankDetails.IntermediaryBankPostalCode, + IntermediaryBankCode: cfg.BankDetails.IntermediaryBankCode, }, } withdrawFiatFundsResponse, err := e.WithdrawFiatFunds(context.TODO(), &withdrawRequestFiat) @@ -1038,9 +1038,9 @@ func loadConfig() (Config, error) { return cfg, err } -func saveConfig(config *Config) { +func saveConfig(cfg *Config) { log.Println("JSONifying config...") - jsonOutput, err := json.MarshalIndent(config, "", " ") + jsonOutput, err := json.MarshalIndent(cfg, "", " ") if err != nil { log.Fatalf("Encountered error encoding JSON: %v", err) } diff --git a/cmd/gctcli/commands.go b/cmd/gctcli/commands.go index 001fd107..f6b073df 100644 --- a/cmd/gctcli/commands.go +++ b/cmd/gctcli/commands.go @@ -2861,7 +2861,7 @@ func withdrawlRequestByExchangeID(c *cli.Context) error { return cli.ShowSubcommandHelp(c) } - var exchange, currency, assetType string + var exchange, ccy, assetType string if c.IsSet("exchange") { exchange = c.String("exchange") } else { @@ -2896,7 +2896,7 @@ func withdrawlRequestByExchangeID(c *cli.Context) error { } if c.IsSet("currency") { - currency = c.String("currency") + ccy = c.String("currency") } if c.IsSet("asset") { @@ -2922,7 +2922,7 @@ func withdrawlRequestByExchangeID(c *cli.Context) error { Exchange: exchange, Id: ID, Limit: int32(limit), //nolint:gosec // TODO: SQL boiler's QueryMode limit only accepts the int type - Currency: currency, + Currency: ccy, AssetType: assetType, }, ) diff --git a/cmd/gctcli/helpers.go b/cmd/gctcli/helpers.go index 1be1e4eb..b4908ebb 100644 --- a/cmd/gctcli/helpers.go +++ b/cmd/gctcli/helpers.go @@ -22,11 +22,11 @@ var ( func clearScreen() error { switch runtime.GOOS { case "windows": - cmd := exec.Command("cmd", "/c", "cls") + cmd := exec.CommandContext(context.TODO(), "cmd", "/c", "cls") cmd.Stdout = os.Stdout return cmd.Run() default: - cmd := exec.Command("clear") + cmd := exec.CommandContext(context.TODO(), "clear") cmd.Stdout = os.Stdout return cmd.Run() } diff --git a/communications/telegram/telegram.go b/communications/telegram/telegram.go index 141feb5e..4564a647 100644 --- a/communications/telegram/telegram.go +++ b/communications/telegram/telegram.go @@ -91,17 +91,17 @@ func (t *Telegram) PushEvent(event base.Event) error { msg := fmt.Sprintf("Type: %s Message: %s", event.Type, event.Message) - var errors error + var errs error for user, ID := range t.AuthorisedClients { if ID == 0 { log.Warnf(log.CommunicationMgr, "Telegram: Unable to send message to %s as their ID isn't set. A user must issue any supported command to begin a session.\n", user) continue } if err := t.SendMessage(msg, ID); err != nil { - errors = common.AppendError(errors, err) + errs = common.AppendError(errs, err) } } - return errors + return errs } // PollerStart starts the long polling sequence @@ -252,13 +252,13 @@ func (t *Telegram) SendMessage(text string, chatID int64) error { text, } - json, err := json.Marshal(&messageToSend) + jsonData, err := json.Marshal(&messageToSend) if err != nil { return err } resp := Message{} - err = t.SendHTTPRequest(path, json, &resp) + err = t.SendHTTPRequest(path, jsonData, &resp) if err != nil { return err } diff --git a/database/database.go b/database/database.go index d5770fe1..050ee06c 100644 --- a/database/database.go +++ b/database/database.go @@ -1,6 +1,7 @@ package database import ( + "context" "database/sql" "fmt" "time" @@ -46,7 +47,7 @@ func (i *Instance) SetPostgresConnection(con *sql.DB) error { if con == nil { return errNilSQL } - if err := con.Ping(); err != nil { + if err := con.PingContext(context.TODO()); err != nil { return fmt.Errorf("%w %s", errFailedPing, err) } i.m.Lock() @@ -117,7 +118,7 @@ func (i *Instance) Ping() error { if i.SQL == nil { return errNilSQL } - return i.SQL.Ping() + return i.SQL.PingContext(context.TODO()) } // GetSQL returns the sql connection diff --git a/database/repository/script/script.go b/database/repository/script/script.go index 9721c8b9..d9a7c358 100644 --- a/database/repository/script/script.go +++ b/database/repository/script/script.go @@ -15,7 +15,7 @@ import ( ) // Event inserts a new script event into database with execution details (script name time status hash of script) -func Event(id, name, path string, data null.Bytes, executionType, status string, time time.Time) { +func Event(id, name, path string, data null.Bytes, executionType, status string, tm time.Time) { if database.DB.SQL == nil { return } @@ -68,7 +68,7 @@ func Event(id, name, path string, data null.Bytes, executionType, status string, tempScriptExecution := &modelSQLite.ScriptExecution{ ScriptID: id, - ExecutionTime: time.UTC().String(), + ExecutionTime: tm.UTC().String(), ExecutionStatus: status, ExecutionType: executionType, } @@ -99,7 +99,7 @@ func Event(id, name, path string, data null.Bytes, executionType, status string, } tempScriptExecution := &modelPSQL.ScriptExecution{ - ExecutionTime: time.UTC(), + ExecutionTime: tm.UTC(), ExecutionStatus: status, ExecutionType: executionType, } diff --git a/database/repository/trade/trade.go b/database/repository/trade/trade.go index cf0118d4..9b0f4981 100644 --- a/database/repository/trade/trade.go +++ b/database/repository/trade/trade.go @@ -217,14 +217,14 @@ func insertPostgres(ctx context.Context, tx *sql.Tx, trades ...Data) error { } // GetByUUID returns a trade by its unique ID -func GetByUUID(uuid string) (td Data, err error) { +func GetByUUID(u string) (td Data, err error) { if repository.GetSQLDialect() == database.DBSQLite3 || repository.GetSQLDialect() == database.DBSQLite { - td, err = getByUUIDSQLite(uuid) + td, err = getByUUIDSQLite(u) if err != nil { return td, fmt.Errorf("trade.Get getByUUIDSQLite %w", err) } } else { - td, err = getByUUIDPostgres(uuid) + td, err = getByUUIDPostgres(u) if err != nil { return td, fmt.Errorf("trade.Get getByUUIDPostgres %w", err) } @@ -233,10 +233,10 @@ func GetByUUID(uuid string) (td Data, err error) { return td, nil } -func getByUUIDSQLite(uuid string) (Data, error) { +func getByUUIDSQLite(u string) (Data, error) { var td Data var ts time.Time - query := sqlite3.Trades(qm.Where("id = ?", uuid)) + query := sqlite3.Trades(qm.Where("id = ?", u)) result, err := query.One(context.TODO(), database.DB.SQL) if err != nil { return td, err @@ -262,8 +262,8 @@ func getByUUIDSQLite(uuid string) (Data, error) { return td, nil } -func getByUUIDPostgres(uuid string) (td Data, err error) { - query := postgres.Trades(qm.Where("id = ?", uuid)) +func getByUUIDPostgres(u string) (td Data, err error) { + query := postgres.Trades(qm.Where("id = ?", u)) var result *postgres.Trade result, err = query.One(context.TODO(), database.DB.SQL) if err != nil { diff --git a/engine/ntp_manager.go b/engine/ntp_manager.go index 79a1afe4..66c54e40 100644 --- a/engine/ntp_manager.go +++ b/engine/ntp_manager.go @@ -156,7 +156,7 @@ func (m *ntpManager) processTime() error { // if no server can be reached will return local time in UTC() func (m *ntpManager) checkTimeInPools() time.Time { for i := range m.pools { - con, err := net.DialTimeout("udp", m.pools[i], 5*time.Second) + con, err := net.DialTimeout("udp", m.pools[i], 5*time.Second) //nolint:noctx // TODO: #2006 Use (*net.Dialer).DialContext with (*net.Dialer).Timeout if err != nil { log.Warnf(log.TimeMgr, "Unable to connect to hosts %v attempting next", m.pools[i]) continue diff --git a/engine/order_manager.go b/engine/order_manager.go index 1479f821..d7673592 100644 --- a/engine/order_manager.go +++ b/engine/order_manager.go @@ -943,10 +943,10 @@ func (s *store) get() map[string][]*order.Detail { } // getByExchangeAndID returns a specific order by exchange and id -func (s *store) getByExchangeAndID(exchange, id string) (*order.Detail, error) { +func (s *store) getByExchangeAndID(exch, id string) (*order.Detail, error) { s.m.Lock() defer s.m.Unlock() - r, ok := s.Orders[strings.ToLower(exchange)] + r, ok := s.Orders[strings.ToLower(exch)] if !ok { return nil, ErrExchangeNotFound } diff --git a/engine/portfolio_manager.go b/engine/portfolio_manager.go index 0927bc37..b19244c9 100644 --- a/engine/portfolio_manager.go +++ b/engine/portfolio_manager.go @@ -333,9 +333,9 @@ func (m *portfolioManager) IsWhiteListed(address string) bool { } // IsExchangeSupported checks if an exchange is supported -func (m *portfolioManager) IsExchangeSupported(exchange, address string) bool { +func (m *portfolioManager) IsExchangeSupported(exch, address string) bool { if m == nil || !m.IsRunning() { return false } - return m.base.IsExchangeSupported(exchange, address) + return m.base.IsExchangeSupported(exch, address) } diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 031302be..50e5cbe2 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -134,7 +134,7 @@ func StartRPCServer(engine *Engine) { return } log.Debugf(log.GRPCSys, "gRPC server support enabled. Starting gRPC server on https://%v.\n", engine.Config.RemoteControl.GRPC.ListenAddress) - lis, err := net.Listen("tcp", engine.Config.RemoteControl.GRPC.ListenAddress) + lis, err := net.Listen("tcp", engine.Config.RemoteControl.GRPC.ListenAddress) //nolint:noctx // TODO: #2006 Replace net.Listen with (*net.ListenConfig).Listen if err != nil { log.Errorf(log.GRPCSys, "gRPC server failed to bind to port: %s", err) return diff --git a/exchange/websocket/connection.go b/exchange/websocket/connection.go index 117567c4..ab70bae5 100644 --- a/exchange/websocket/connection.go +++ b/exchange/websocket/connection.go @@ -374,8 +374,8 @@ func (c *connection) Shutdown() error { } // SetURL sets connection URL -func (c *connection) SetURL(url string) { - c.URL = url +func (c *connection) SetURL(u string) { + c.URL = u } // SetProxy sets connection proxy @@ -469,11 +469,11 @@ inspection: return resps, nil } -func removeURLQueryString(url string) string { - if index := strings.Index(url, "?"); index != -1 { - return url[:index] +func removeURLQueryString(u string) string { + if index := strings.Index(u, "?"); index != -1 { + return u[:index] } - return url + return u } // RequireMatchWithData routes incoming data using the connection specific match system to the correct handler diff --git a/exchange/websocket/manager.go b/exchange/websocket/manager.go index 8633f234..69bc6a7f 100644 --- a/exchange/websocket/manager.go +++ b/exchange/websocket/manager.go @@ -739,51 +739,51 @@ func (m *Manager) CanUseAuthenticatedWebsocketForWrapper() bool { } // SetWebsocketURL sets websocket URL and can refresh underlying connections -func (m *Manager) SetWebsocketURL(url string, auth, reconnect bool) error { +func (m *Manager) SetWebsocketURL(u string, auth, reconnect bool) error { if m.useMultiConnectionManagement { // TODO: Add functionality for multi-connection management to change URL return fmt.Errorf("%s: %w", m.exchangeName, errCannotChangeConnectionURL) } - defaultVals := url == "" || url == config.WebsocketURLNonDefaultMessage + defaultVals := u == "" || u == config.WebsocketURLNonDefaultMessage if auth { if defaultVals { - url = m.defaultURLAuth + u = m.defaultURLAuth } - err := checkWebsocketURL(url) + err := checkWebsocketURL(u) if err != nil { return err } - m.runningURLAuth = url + m.runningURLAuth = u if m.verbose { - log.Debugf(log.WebsocketMgr, "%s websocket: setting authenticated websocket URL: %s\n", m.exchangeName, url) + log.Debugf(log.WebsocketMgr, "%s websocket: setting authenticated websocket URL: %s\n", m.exchangeName, u) } if m.AuthConn != nil { - m.AuthConn.SetURL(url) + m.AuthConn.SetURL(u) } } else { if defaultVals { - url = m.defaultURL + u = m.defaultURL } - err := checkWebsocketURL(url) + err := checkWebsocketURL(u) if err != nil { return err } - m.runningURL = url + m.runningURL = u if m.verbose { - log.Debugf(log.WebsocketMgr, "%s websocket: setting unauthenticated websocket URL: %s\n", m.exchangeName, url) + log.Debugf(log.WebsocketMgr, "%s websocket: setting unauthenticated websocket URL: %s\n", m.exchangeName, u) } if m.Conn != nil { - m.Conn.SetURL(url) + m.Conn.SetURL(u) } } if m.IsConnected() && reconnect { - log.Debugf(log.WebsocketMgr, "%s websocket: flushing websocket connection to %s\n", m.exchangeName, url) + log.Debugf(log.WebsocketMgr, "%s websocket: flushing websocket connection to %s\n", m.exchangeName, u) return m.Shutdown() } return nil diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index f02426a1..995bb175 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -1033,9 +1033,9 @@ func (e *Exchange) WithdrawHistory(ctx context.Context, c currency.Code, status } // GetDepositAddressForCurrency retrieves the wallet address for a given currency -func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { +func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, coin, chain string) (*DepositAddress, error) { params := url.Values{} - params.Set("coin", currency) + params.Set("coin", coin) if chain != "" { params.Set("network", chain) } diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index 901fb987..84bee002 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -2256,7 +2256,7 @@ func TestWsOCO(t *testing.T) { } func TestGetWsAuthStreamKey(t *testing.T) { - key, err := e.GetWsAuthStreamKey(t.Context()) + authKey, err := e.GetWsAuthStreamKey(t.Context()) switch { case mockTests && err != nil, !mockTests && sharedtestvalues.AreAPICredentialsSet(e) && err != nil: @@ -2265,7 +2265,7 @@ func TestGetWsAuthStreamKey(t *testing.T) { t.Fatal("Expected error") } - if key == "" && (sharedtestvalues.AreAPICredentialsSet(e) || mockTests) { + if authKey == "" && (sharedtestvalues.AreAPICredentialsSet(e) || mockTests) { t.Error("Expected key") } } diff --git a/exchanges/binanceus/binanceus.go b/exchanges/binanceus/binanceus.go index 140b0885..aff4f3aa 100644 --- a/exchanges/binanceus/binanceus.go +++ b/exchanges/binanceus/binanceus.go @@ -663,7 +663,7 @@ func (e *Exchange) GetTradeFee(ctx context.Context, recvWindow uint64, symbol st // // INPUTS: // asset: string , startTime & endTime unix time in Milli seconds, recvWindow(duration in milli seconds > 2000 to < 6000) -func (e *Exchange) GetAssetDistributionHistory(ctx context.Context, asset string, startTime, endTime int64, recvWindow uint64) (*AssetDistributionHistories, error) { +func (e *Exchange) GetAssetDistributionHistory(ctx context.Context, a string, startTime, endTime int64, recvWindow uint64) (*AssetDistributionHistories, error) { params := url.Values{} timestamp := time.Now().UnixMilli() var resp AssetDistributionHistories @@ -683,8 +683,8 @@ func (e *Exchange) GetAssetDistributionHistory(ctx context.Context, asset string params.Set("recvWindow", strconv.FormatUint(recvWindow, 10)) } - if asset != "" { - params.Set("asset", asset) + if a != "" { + params.Set("asset", a) } return &resp, e.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, @@ -1498,12 +1498,12 @@ func (e *Exchange) WithdrawFiat(ctx context.Context, arg *WithdrawFiatRequestPar */ // GetDepositAddressForCurrency retrieves the wallet address for a given currency -func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, currency, chain string) (*DepositAddress, error) { +func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, coin, chain string) (*DepositAddress, error) { params := url.Values{} - if currency == "" { + if coin == "" { return nil, errMissingRequiredArgumentCoin } - params.Set("coin", currency) + params.Set("coin", coin) if chain != "" { params.Set("network", chain) } @@ -1515,11 +1515,11 @@ func (e *Exchange) GetDepositAddressForCurrency(ctx context.Context, currency, c // 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 (e *Exchange) 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, coin currency.Code, status uint8, startTime, endTime time.Time, offset, limit int) ([]DepositHistory, error) { var response []DepositHistory params := url.Values{} - if !c.IsEmpty() { - params.Set("coin", c.String()) + if !coin.IsEmpty() { + params.Set("coin", coin.String()) } if status > 0 { diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index d47a1b04..6ceb71e7 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -402,7 +402,7 @@ func (e *Exchange) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { if !ok { return resp, common.GetTypeAssertError("string", data[x][0], "Wallets.WalletType") } - currency, ok := data[x][1].(string) + ccy, ok := data[x][1].(string) if !ok { return resp, common.GetTypeAssertError("string", data[x][1], "Wallets.Currency") } @@ -416,7 +416,7 @@ func (e *Exchange) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { } resp[x] = WalletDataV2{ WalletType: walletType, - Currency: currency, + Currency: ccy, Balance: balance, UnsettledInterest: unsettledInterest, } @@ -500,10 +500,9 @@ func (e *Exchange) GetSiteInfoConfigData(ctx context.Context, assetType asset.It default: return nil, fmt.Errorf("invalid asset type for GetSiteInfoConfigData: %s", assetType) } - url := bitfinexAPIVersion2 + path - var resp [][][]any - err := e.SendHTTPRequest(ctx, exchange.RestSpot, url, &resp, status) + var resp [][][]any + err := e.SendHTTPRequest(ctx, exchange.RestSpot, bitfinexAPIVersion2+path, &resp, status) if err != nil { return nil, err } @@ -1231,11 +1230,11 @@ func (e *Exchange) GetAccountBalance(ctx context.Context) ([]Balance, error) { // Currency - example "BTC" // WalletFrom - example "exchange" // WalletTo - example "deposit" -func (e *Exchange) WalletTransfer(ctx context.Context, amount float64, currency, walletFrom, walletTo string) (WalletTransfer, error) { +func (e *Exchange) WalletTransfer(ctx context.Context, amount float64, ccy, walletFrom, walletTo string) (WalletTransfer, error) { var response []WalletTransfer req := make(map[string]any) req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - req["currency"] = currency + req["currency"] = ccy req["walletfrom"] = walletFrom req["walletto"] = walletTo diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index 49ebcfbe..5ae5e08f 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -412,15 +412,15 @@ func (e *Exchange) PlaceTrade(ctx context.Context, orderCurrency, transactionTyp // // orderID: Order number registered for purchase/sales // transactionType: Transaction type(bid : purchase, ask : sales) -// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS +// ccy: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (e *Exchange) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) { +func (e *Exchange) GetOrderDetails(ctx context.Context, orderID, transactionType, ccy string) (OrderDetails, error) { response := OrderDetails{} params := url.Values{} params.Set("order_id", strings.ToUpper(orderID)) params.Set("type", transactionType) - params.Set("currency", strings.ToUpper(currency)) + params.Set("currency", strings.ToUpper(ccy)) return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response) @@ -429,15 +429,15 @@ func (e *Exchange) GetOrderDetails(ctx context.Context, orderID, transactionType // CancelTrade cancels a customer purchase/sales transaction // transactionType: Transaction type(bid : purchase, ask : sales) // orderID: Order number registered for purchase/sales -// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS +// ccy: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (e *Exchange) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) { +func (e *Exchange) CancelTrade(ctx context.Context, transactionType, orderID, ccy string) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} params.Set("order_id", strings.ToUpper(orderID)) params.Set("type", strings.ToUpper(transactionType)) - params.Set("currency", strings.ToUpper(currency)) + params.Set("currency", strings.ToUpper(ccy)) return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response) @@ -451,7 +451,7 @@ func (e *Exchange) CancelTrade(ctx context.Context, transactionType, orderID, cu // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM // (default value: BTC) // units: Quantity to withdraw currency -func (e *Exchange) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, address, destination, ccy string, units float64) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -459,7 +459,7 @@ func (e *Exchange) WithdrawCrypto(ctx context.Context, address, destination, cur if destination != "" { params.Set("destination", destination) } - params.Set("currency", strings.ToUpper(currency)) + params.Set("currency", strings.ToUpper(ccy)) params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 7d7bdba0..5a37c670 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -735,13 +735,10 @@ func (e *Exchange) UserLogOutAll(ctx context.Context) (int64, error) { } // GetUserMargin returns user margin information -func (e *Exchange) GetUserMargin(ctx context.Context, currency string) (UserMargin, error) { +func (e *Exchange) GetUserMargin(ctx context.Context, ccy string) (UserMargin, error) { var info UserMargin - - return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - bitmexEndpointUserMargin, - UserCurrencyParams{Currency: currency}, - &info) + params := UserCurrencyParams{Currency: ccy} + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMargin, params, &info) } // GetAllUserMargin returns user margin information @@ -755,13 +752,10 @@ func (e *Exchange) GetAllUserMargin(ctx context.Context) ([]UserMargin, error) { } // GetMinimumWithdrawalFee returns minimum withdrawal fee information -func (e *Exchange) GetMinimumWithdrawalFee(ctx context.Context, currency string) (MinWithdrawalFee, error) { +func (e *Exchange) GetMinimumWithdrawalFee(ctx context.Context, ccy string) (MinWithdrawalFee, error) { var fee MinWithdrawalFee - - return fee, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - bitmexEndpointUserMinWithdrawalFee, - UserCurrencyParams{Currency: currency}, - &fee) + params := UserCurrencyParams{Currency: ccy} + return fee, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMinWithdrawalFee, params, &fee) } // GetUserPreferences returns user preferences @@ -797,13 +791,10 @@ func (e *Exchange) UserRequestWithdrawal(ctx context.Context, params UserRequest } // GetWalletInfo returns user wallet information -func (e *Exchange) GetWalletInfo(ctx context.Context, currency string) (WalletInfo, error) { +func (e *Exchange) GetWalletInfo(ctx context.Context, ccy string) (WalletInfo, error) { var info WalletInfo - - if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - bitmexEndpointUserWallet, - UserCurrencyParams{Currency: currency}, - &info); err != nil { + params := UserCurrencyParams{Currency: ccy} + if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWallet, params, &info); err != nil { return info, err } @@ -818,23 +809,17 @@ func (e *Exchange) GetWalletInfo(ctx context.Context, currency string) (WalletIn } // GetWalletHistory returns user wallet history transaction data -func (e *Exchange) GetWalletHistory(ctx context.Context, currency string) ([]TransactionInfo, error) { +func (e *Exchange) GetWalletHistory(ctx context.Context, ccy string) ([]TransactionInfo, error) { var info []TransactionInfo - - return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - bitmexEndpointUserWalletHistory, - UserCurrencyParams{Currency: currency}, - &info) + params := UserCurrencyParams{Currency: ccy} + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletHistory, params, &info) } // GetWalletSummary returns user wallet summary -func (e *Exchange) GetWalletSummary(ctx context.Context, currency string) ([]TransactionInfo, error) { +func (e *Exchange) GetWalletSummary(ctx context.Context, ccy string) ([]TransactionInfo, error) { var info []TransactionInfo - - return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - bitmexEndpointUserWalletSummary, - UserCurrencyParams{Currency: currency}, - &info) + params := UserCurrencyParams{Currency: ccy} + return info, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletSummary, params, &info) } // SendHTTPRequest sends an unauthenticated HTTP request diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 36b95414..8794b3f5 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -155,28 +155,27 @@ func getInternationalBankDepositFee(amount float64) float64 { } // GetTicker returns ticker information -func (e *Exchange) GetTicker(ctx context.Context, currency string, hourly bool) (*Ticker, error) { +func (e *Exchange) GetTicker(ctx context.Context, symbol string, hourly bool) (*Ticker, error) { response := Ticker{} tickerEndpoint := bitstampAPITicker - if hourly { tickerEndpoint = bitstampAPITickerHourly } - path := "/v" + bitstampAPIVersion + "/" + tickerEndpoint + "/" + strings.ToLower(currency) + "/" + path := "/v" + bitstampAPIVersion + "/" + tickerEndpoint + "/" + strings.ToLower(symbol) + "/" 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 (e *Exchange) GetOrderbook(ctx context.Context, currency string) (*Orderbook, error) { +func (e *Exchange) GetOrderbook(ctx context.Context, symbol string) (*Orderbook, error) { type response struct { Timestamp types.Time `json:"timestamp"` Bids [][2]types.Number `json:"bids"` Asks [][2]types.Number `json:"asks"` } - path := "/v" + bitstampAPIVersion + "/" + bitstampAPIOrderbook + "/" + strings.ToLower(currency) + "/" + path := "/v" + bitstampAPIVersion + "/" + bitstampAPIOrderbook + "/" + strings.ToLower(symbol) + "/" var resp response err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { @@ -379,60 +378,51 @@ func (e *Exchange) CryptoWithdrawal(ctx context.Context, amount float64, address } // OpenBankWithdrawal Opens a bank withdrawal request (SEPA or international) -func (e *Exchange) OpenBankWithdrawal(ctx context.Context, amount float64, currency, - name, iban, bic, address, postalCode, city, country, - comment, withdrawalType string, -) (FIATWithdrawalResponse, error) { - req := url.Values{} - req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - req.Add("account_currency", currency) - req.Add("name", name) - req.Add("iban", iban) - req.Add("bic", bic) - req.Add("address", address) - req.Add("postal_code", postalCode) - req.Add("city", city) - req.Add("country", country) - req.Add("type", withdrawalType) - req.Add("comment", comment) - +func (e *Exchange) OpenBankWithdrawal(ctx context.Context, req *OpenBankWithdrawalRequest) (FIATWithdrawalResponse, error) { + v := url.Values{} + v.Add("amount", strconv.FormatFloat(req.Amount, 'f', -1, 64)) + v.Add("account_currency", req.Currency.String()) + v.Add("name", req.Name) + v.Add("iban", req.IBAN) + v.Add("bic", req.BIC) + v.Add("address", req.Address) + v.Add("postal_code", req.PostalCode) + v.Add("city", req.City) + v.Add("country", req.Country) + v.Add("type", req.WithdrawalType) + v.Add("comment", req.Comment) resp := FIATWithdrawalResponse{} - return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, v, &resp) } // OpenInternationalBankWithdrawal Opens a bank withdrawal request (international) -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, -) (FIATWithdrawalResponse, error) { - req := url.Values{} - req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - req.Add("account_currency", currency) - req.Add("name", name) - req.Add("iban", iban) - req.Add("bic", bic) - req.Add("address", address) - req.Add("postal_code", postalCode) - req.Add("city", city) - req.Add("country", country) - req.Add("type", withdrawalType) - req.Add("comment", comment) - req.Add("currency", internationalCurrency) - req.Add("bank_name", bankName) - req.Add("bank_address", bankAddress) - req.Add("bank_postal_code", bankPostCode) - req.Add("bank_city", bankCity) - req.Add("bank_country", bankCountry) - +func (e *Exchange) OpenInternationalBankWithdrawal(ctx context.Context, req *OpenBankWithdrawalRequest) (FIATWithdrawalResponse, error) { + v := url.Values{} + v.Add("amount", strconv.FormatFloat(req.Amount, 'f', -1, 64)) + v.Add("account_currency", req.Currency.String()) + v.Add("name", req.Name) + v.Add("iban", req.IBAN) + v.Add("bic", req.BIC) + v.Add("address", req.Address) + v.Add("postal_code", req.PostalCode) + v.Add("city", req.City) + v.Add("country", req.Country) + v.Add("type", req.WithdrawalType) + v.Add("comment", req.Comment) + v.Add("currency", req.InternationalCurrency) + v.Add("bank_name", req.BankName) + v.Add("bank_address", req.BankAddress) + v.Add("bank_postal_code", req.BankPostalCode) + v.Add("bank_city", req.BankCity) + v.Add("bank_country", req.BankCountry) resp := FIATWithdrawalResponse{} - return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, v, &resp) } // GetCryptoDepositAddress returns a depositing address by crypto. -// crypto - example "btc", "ltc", "eth", "xrp" or "bch" -func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, crypto currency.Code) (*DepositAddress, error) { - path := crypto.Lower().String() + "_address" +// c - example "btc", "ltc", "eth", "xrp" or "bch" +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, c currency.Code) (*DepositAddress, error) { + path := c.Lower().String() + "_address" var resp DepositAddress return &resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) } @@ -446,7 +436,7 @@ func (e *Exchange) GetUnconfirmedBitcoinDeposits(ctx context.Context) ([]Unconfi } // OHLC returns OHLCV data for step (interval) -func (e *Exchange) OHLC(ctx context.Context, currency string, start, end time.Time, step, limit string) (resp OHLCResponse, err error) { +func (e *Exchange) OHLC(ctx context.Context, symbol 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 +450,7 @@ func (e *Exchange) OHLC(ctx context.Context, currency string, start, end time.Ti if !end.IsZero() { v.Add("end", strconv.FormatInt(end.Unix(), 10)) } - return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampAPIOHLC+"/"+currency, v), &resp) + return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampAPIOHLC+"/"+symbol, v), &resp) } // TransferAccountBalance transfers funds from either a main or sub account @@ -468,10 +458,10 @@ func (e *Exchange) 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 (e *Exchange) TransferAccountBalance(ctx context.Context, amount float64, currency, subAccount string, toMain bool) error { +func (e *Exchange) TransferAccountBalance(ctx context.Context, amount float64, ccy, subAccount string, toMain bool) error { req := url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - req.Add("currency", currency) + req.Add("currency", ccy) if subAccount == "" { return errors.New("missing subAccount parameter") diff --git a/exchanges/bitstamp/bitstamp_types.go b/exchanges/bitstamp/bitstamp_types.go index 6e18b3dc..e0634d89 100644 --- a/exchanges/bitstamp/bitstamp_types.go +++ b/exchanges/bitstamp/bitstamp_types.go @@ -180,6 +180,29 @@ type CryptoWithdrawalResponse struct { ID int64 `json:"withdrawal_id"` } +// OpenBankWithdrawalRequest holds the request information for sending a bank withdrawal request +type OpenBankWithdrawalRequest struct { + Amount float64 + Currency currency.Code + Name string + IBAN string + BIC string + Address string + PostalCode string + City string + Country string + WithdrawalType string + Comment string + + // International bank account details + InternationalCurrency string + BankName string + BankAddress string + BankPostalCode string + BankCity string + BankCountry string +} + // FIATWithdrawalResponse response from a fiat withdrawal request type FIATWithdrawalResponse struct { ID int64 `json:"withdrawal_id"` diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 2ccb7cc8..562597b2 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -583,18 +583,20 @@ func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withd if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := e.OpenBankWithdrawal(ctx, - withdrawRequest.Amount, - withdrawRequest.Currency.String(), - withdrawRequest.Fiat.Bank.AccountName, - withdrawRequest.Fiat.Bank.IBAN, - withdrawRequest.Fiat.Bank.SWIFTCode, - withdrawRequest.Fiat.Bank.BankAddress, - withdrawRequest.Fiat.Bank.BankPostalCode, - withdrawRequest.Fiat.Bank.BankPostalCity, - withdrawRequest.Fiat.Bank.BankCountry, - withdrawRequest.Description, - sepaWithdrawal) + + resp, err := e.OpenBankWithdrawal(ctx, &OpenBankWithdrawalRequest{ + Amount: withdrawRequest.Amount, + Currency: withdrawRequest.Currency, + Name: withdrawRequest.Fiat.Bank.AccountName, + IBAN: withdrawRequest.Fiat.Bank.IBAN, + BIC: withdrawRequest.Fiat.Bank.SWIFTCode, + Address: withdrawRequest.Fiat.Bank.BankAddress, + PostalCode: withdrawRequest.Fiat.Bank.BankPostalCode, + City: withdrawRequest.Fiat.Bank.BankPostalCity, + Country: withdrawRequest.Fiat.Bank.BankCountry, + Comment: withdrawRequest.Description, + WithdrawalType: sepaWithdrawal, + }) if err != nil { return nil, err } @@ -610,24 +612,25 @@ func (e *Exchange) WithdrawFiatFundsToInternationalBank(ctx context.Context, wit if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := e.OpenInternationalBankWithdrawal(ctx, - withdrawRequest.Amount, - withdrawRequest.Currency.String(), - withdrawRequest.Fiat.Bank.AccountName, - withdrawRequest.Fiat.Bank.IBAN, - withdrawRequest.Fiat.Bank.SWIFTCode, - withdrawRequest.Fiat.Bank.BankAddress, - withdrawRequest.Fiat.Bank.BankPostalCode, - withdrawRequest.Fiat.Bank.BankPostalCity, - withdrawRequest.Fiat.Bank.BankCountry, - withdrawRequest.Fiat.IntermediaryBankName, - withdrawRequest.Fiat.IntermediaryBankAddress, - withdrawRequest.Fiat.IntermediaryBankPostalCode, - withdrawRequest.Fiat.IntermediaryBankCity, - withdrawRequest.Fiat.IntermediaryBankCountry, - withdrawRequest.Fiat.WireCurrency, - withdrawRequest.Description, - internationalWithdrawal) + resp, err := e.OpenInternationalBankWithdrawal(ctx, &OpenBankWithdrawalRequest{ + Amount: withdrawRequest.Amount, + Currency: withdrawRequest.Currency, + Name: withdrawRequest.Fiat.Bank.AccountName, + IBAN: withdrawRequest.Fiat.Bank.IBAN, + BIC: withdrawRequest.Fiat.Bank.SWIFTCode, + Address: withdrawRequest.Fiat.Bank.BankAddress, + PostalCode: withdrawRequest.Fiat.Bank.BankPostalCode, + City: withdrawRequest.Fiat.Bank.BankPostalCity, + Country: withdrawRequest.Fiat.Bank.BankCountry, + BankName: withdrawRequest.Fiat.IntermediaryBankName, + BankAddress: withdrawRequest.Fiat.IntermediaryBankAddress, + BankPostalCode: withdrawRequest.Fiat.IntermediaryBankPostalCode, + BankCity: withdrawRequest.Fiat.IntermediaryBankCity, + BankCountry: withdrawRequest.Fiat.IntermediaryBankCountry, + InternationalCurrency: withdrawRequest.Fiat.WireCurrency, + Comment: withdrawRequest.Description, + WithdrawalType: internationalWithdrawal, + }) if err != nil { return nil, err } diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index f5e46a65..44f548ae 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -212,22 +212,20 @@ func (e *Exchange) GetWalletHistory(ctx context.Context, symbol string, start, e } // GetWalletAddress returns the users account balance -func (e *Exchange) GetWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { +func (e *Exchange) GetWalletAddress(ctx context.Context, ccy string) (WalletAddress, error) { var resp WalletAddress - urlValues := url.Values{} - if currency != "" { - urlValues.Add("currency", currency) + if ccy != "" { + urlValues.Add("currency", ccy) } - return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletAddress, true, urlValues, nil, &resp, queryFunc) } // CreateWalletAddress create new deposit address for requested currency -func (e *Exchange) CreateWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { +func (e *Exchange) CreateWalletAddress(ctx context.Context, ccy string) (WalletAddress, error) { var resp WalletAddress req := make(map[string]any, 1) - req["currency"] = currency + req["currency"] = ccy err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletAddress, true, nil, req, &resp, queryFunc) if err != nil { errResp := ErrorResponse{} @@ -251,10 +249,10 @@ func (e *Exchange) CreateWalletAddress(ctx context.Context, currency string) (Wa } // WalletWithdrawal submit request to withdraw crypto currency -func (e *Exchange) WalletWithdrawal(ctx context.Context, currency, address, tag, amount string) (WithdrawalResponse, error) { +func (e *Exchange) WalletWithdrawal(ctx context.Context, ccy, address, tag, amount string) (WithdrawalResponse, error) { var resp WithdrawalResponse req := make(map[string]any, 4) - req["currency"] = currency + req["currency"] = ccy req["address"] = address req["tag"] = tag req["amount"] = amount diff --git a/exchanges/bybit/bybit.go b/exchanges/bybit/bybit.go index 096f2974..81fb4a38 100644 --- a/exchanges/bybit/bybit.go +++ b/exchanges/bybit/bybit.go @@ -1245,10 +1245,10 @@ func (e *Exchange) UpgradeToUnifiedAccount(ctx context.Context) (*UnifiedAccount } // GetBorrowHistory retrieves interest records, sorted in reverse order of creation time. -func (e *Exchange) GetBorrowHistory(ctx context.Context, currency, cursor string, startTime, endTime time.Time, limit int64) (*BorrowHistory, error) { +func (e *Exchange) GetBorrowHistory(ctx context.Context, ccy, cursor string, startTime, endTime time.Time, limit int64) (*BorrowHistory, error) { params := url.Values{} - if currency != "" { - params.Set("currency", currency) + if ccy != "" { + params.Set("currency", ccy) } if cursor != "" { params.Set("cursor", cursor) @@ -1286,10 +1286,10 @@ func (e *Exchange) SetCollateralCoin(ctx context.Context, coin currency.Code, co // 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 (e *Exchange) GetCollateralInfo(ctx context.Context, currency string) (*CollateralInfo, error) { +func (e *Exchange) GetCollateralInfo(ctx context.Context, ccy string) (*CollateralInfo, error) { params := url.Values{} - if currency != "" { - params.Set("currency", currency) + if ccy != "" { + params.Set("currency", ccy) } var resp *CollateralInfo return resp, e.SendAuthHTTPRequestV5(ctx, exchange.RestSpot, http.MethodGet, "/v5/account/collateral-info", params, nil, &resp, defaultEPL) @@ -2157,13 +2157,13 @@ func (e *Exchange) SetSpotMarginTradeLeverage(ctx context.Context, leverage floa } // GetVIPMarginData retrieves public VIP Margin data -func (e *Exchange) GetVIPMarginData(ctx context.Context, vipLevel, currency string) (*VIPMarginData, error) { +func (e *Exchange) GetVIPMarginData(ctx context.Context, vipLevel, ccy string) (*VIPMarginData, error) { params := url.Values{} if vipLevel != "" { params.Set("vipLevel", vipLevel) } - if currency != "" { - params.Set("currency", currency) + if ccy != "" { + params.Set("currency", ccy) } var resp *VIPMarginData return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, "spot-cross-margin-trade/data", defaultEPL, &resp) diff --git a/exchanges/coinbasepro/coinbasepro.go b/exchanges/coinbasepro/coinbasepro.go index c34252fd..e46665d8 100644 --- a/exchanges/coinbasepro/coinbasepro.go +++ b/exchanges/coinbasepro/coinbasepro.go @@ -442,12 +442,12 @@ func (e *Exchange) 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 (e *Exchange) MarginTransfer(ctx context.Context, amount float64, transferType, profileID, currency string) (MarginTransfer, error) { +func (e *Exchange) MarginTransfer(ctx context.Context, amount float64, transferType, profileID, ccy string) (MarginTransfer, error) { resp := MarginTransfer{} req := make(map[string]any) req["type"] = transferType req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - req["currency"] = currency + req["currency"] = ccy req["margin_profile_id"] = profileID return resp, @@ -487,11 +487,11 @@ func (e *Exchange) GetPayMethods(ctx context.Context) ([]PaymentMethod, error) { // amount - The amount to deposit // currency - The type of currency // paymentID - ID of the payment method -func (e *Exchange) DepositViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) DepositViaPaymentMethod(ctx context.Context, amount float64, ccy, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount - req["currency"] = currency + req["currency"] = ccy req["payment_method_id"] = paymentID return resp, @@ -506,11 +506,11 @@ func (e *Exchange) DepositViaPaymentMethod(ctx context.Context, amount float64, // amount - The amount to deposit // currency - The type of currency // accountID - ID of the coinbase account -func (e *Exchange) DepositViaCoinbase(ctx context.Context, amount float64, currency, accountID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) DepositViaCoinbase(ctx context.Context, amount float64, ccy, accountID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount - req["currency"] = currency + req["currency"] = ccy req["coinbase_account_id"] = accountID return resp, @@ -522,11 +522,11 @@ func (e *Exchange) DepositViaCoinbase(ctx context.Context, amount float64, curre // amount - The amount to withdraw // currency - The type of currency // paymentID - ID of the payment method -func (e *Exchange) WithdrawViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (e *Exchange) WithdrawViaPaymentMethod(ctx context.Context, amount float64, ccy, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount - req["currency"] = currency + req["currency"] = ccy req["payment_method_id"] = paymentID return resp, @@ -555,11 +555,11 @@ func (e *Exchange) WithdrawViaPaymentMethod(ctx context.Context, amount float64, // amount - The amount to withdraw // currency - The type of currency // cryptoAddress - A crypto address of the recipient -func (e *Exchange) WithdrawCrypto(ctx context.Context, amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, amount float64, ccy, cryptoAddress string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]any) req["amount"] = amount - req["currency"] = currency + req["currency"] = ccy req["crypto_address"] = cryptoAddress return resp, diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index c6addec5..2cfc6bc9 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -196,11 +196,10 @@ func (e *Exchange) GetTradeHistory(ctx context.Context, instrumentID, start, lim } // GetIndexTicker returns the index ticker for an asset -func (e *Exchange) GetIndexTicker(ctx context.Context, asset string) (IndexTicker, error) { +func (e *Exchange) GetIndexTicker(ctx context.Context, a string) (IndexTicker, error) { var result IndexTicker params := make(map[string]any) - params["asset"] = asset - + params["asset"] = a return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutIndexTicker, params, false, &result) } @@ -214,12 +213,11 @@ func (e *Exchange) GetDerivativeInstruments(ctx context.Context, secType string) } // GetOptionChain returns option chain -func (e *Exchange) GetOptionChain(ctx context.Context, asset, secType string) (OptionChainResponse, error) { +func (e *Exchange) GetOptionChain(ctx context.Context, a, secType string) (OptionChainResponse, error) { var result OptionChainResponse params := make(map[string]any) - params["asset"] = asset + params["asset"] = a params["sec_type"] = secType - return result, e.SendHTTPRequest(ctx, exchange.RestSpot, coinutOptionChain, params, false, &result) } diff --git a/exchanges/deribit/deribit.go b/exchanges/deribit/deribit.go index c8d113cf..22684b8c 100644 --- a/exchanges/deribit/deribit.go +++ b/exchanges/deribit/deribit.go @@ -2326,8 +2326,8 @@ func (e *Exchange) CreateCombo(ctx context.Context, args []ComboParam) (*ComboDe // 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 (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { - if nonce == "" { +func (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, tradeNonce, role string, ccy currency.Code, trades []BlockTradeParam) ([]BlockTradeResponse, error) { + if tradeNonce == "" { return nil, errMissingNonce } if role != roleMaker && role != roleTaker { @@ -2351,7 +2351,7 @@ func (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, return nil, fmt.Errorf("%w, trade price can't be negative", errInvalidPrice) } } - signature, err := e.VerifyBlockTrade(ctx, timestampMS, nonce, role, ccy, trades) + signature, err := e.VerifyBlockTrade(ctx, timestampMS, tradeNonce, role, ccy, trades) if err != nil { return nil, err } @@ -2364,7 +2364,7 @@ func (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, params.Set("currency", ccy.String()) } params.Set("trades", string(values)) - params.Set("nonce", nonce) + params.Set("nonce", tradeNonce) params.Set("role", role) params.Set("counterparty_signature", signature) params.Set("timestamp", strconv.FormatInt(timestampMS.UnixMilli(), 10)) @@ -2373,8 +2373,8 @@ func (e *Exchange) ExecuteBlockTrade(ctx context.Context, timestampMS time.Time, } // VerifyBlockTrade verifies and creates block trade signature -func (e *Exchange) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, nonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { - if nonce == "" { +func (e *Exchange) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, tradeNonce, role string, ccy currency.Code, trades []BlockTradeParam) (string, error) { + if tradeNonce == "" { return "", errMissingNonce } if role != roleMaker && role != roleTaker { @@ -2410,7 +2410,7 @@ func (e *Exchange) VerifyBlockTrade(ctx context.Context, timestampMS time.Time, if !ccy.IsEmpty() { params.Set("currency", ccy.String()) } - params.Set("nonce", nonce) + params.Set("nonce", tradeNonce) params.Set("role", role) params.Set("trades", string(values)) resp := &struct { diff --git a/exchanges/exchange.go b/exchanges/exchange.go index 6e39ac36..e638a15d 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -62,6 +62,7 @@ var ( errConfigPairFormatRequiresDelimiter = errors.New("config pair format requires delimiter") errSetDefaultsNotCalled = errors.New("set defaults not called") errExchangeIsNil = errors.New("exchange is nil") + errInvalidEndpointKey = errors.New("invalid endpoint key") ) // SetRequester sets the instance of the requester @@ -1009,12 +1010,12 @@ func (b *Base) SetAssetPairStore(a asset.Item, f currency.PairStore) error { } // SetGlobalPairsManager sets defined asset and pairs management system with global formatting -func (b *Base) SetGlobalPairsManager(request, config *currency.PairFormat, assets ...asset.Item) error { - if request == nil { +func (b *Base) SetGlobalPairsManager(reqFmt, cfgFmt *currency.PairFormat, assets ...asset.Item) error { + if reqFmt == nil { return fmt.Errorf("%s cannot set pairs manager, request pair format not provided", b.Name) } - if config == nil { + if cfgFmt == nil { return fmt.Errorf("%s cannot set pairs manager, config pair format not provided", b.Name) } @@ -1024,14 +1025,14 @@ func (b *Base) SetGlobalPairsManager(request, config *currency.PairFormat, asset b.Name) } - if config.Delimiter == "" { + if cfgFmt.Delimiter == "" { return fmt.Errorf("exchange %s cannot set global pairs manager %w for assets %s", b.Name, errConfigPairFormatRequiresDelimiter, assets) } b.CurrencyPairs.UseGlobalFormat = true - b.CurrencyPairs.RequestFormat = request - b.CurrencyPairs.ConfigFormat = config + b.CurrencyPairs.RequestFormat = reqFmt + b.CurrencyPairs.ConfigFormat = cfgFmt if b.CurrencyPairs.Pairs != nil { return fmt.Errorf("%s cannot set pairs manager, pairs already set", @@ -1047,8 +1048,8 @@ func (b *Base) SetGlobalPairsManager(request, config *currency.PairFormat, asset } b.CurrencyPairs.Pairs[assets[i]] = new(currency.PairStore) b.CurrencyPairs.Pairs[assets[i]].AssetEnabled = true - b.CurrencyPairs.Pairs[assets[i]].ConfigFormat = config - b.CurrencyPairs.Pairs[assets[i]].RequestFormat = request + b.CurrencyPairs.Pairs[assets[i]].ConfigFormat = cfgFmt + b.CurrencyPairs.Pairs[assets[i]].RequestFormat = reqFmt } return nil @@ -1250,23 +1251,16 @@ func (e *Endpoints) SetDefaultEndpoints(m map[URL]string) error { } // SetRunningURL populates running URLs map -func (e *Endpoints) SetRunningURL(key, val string) error { +func (e *Endpoints) SetRunningURL(endpoint, val string) error { e.mu.Lock() defer e.mu.Unlock() - err := validateKey(key) - if err != nil { + if err := validateKey(endpoint); err != nil { return err } - _, err = url.ParseRequestURI(val) - if err != nil { - log.Warnf(log.ExchangeSys, - "Could not set custom URL for %s to %s for exchange %s. invalid URI for request.", - key, - val, - e.Exchange) - return nil + if _, err := url.ParseRequestURI(val); err != nil { + return fmt.Errorf("parse request URI for %s=%q (exchange %s): %w", endpoint, val, e.Exchange, err) } - e.defaults[key] = val + e.defaults[endpoint] = val return nil } @@ -1276,16 +1270,16 @@ func validateKey(keyVal string) error { return nil } } - return errors.New("keyVal invalid") + return errInvalidEndpointKey } // GetURL gets default url from URLs map -func (e *Endpoints) GetURL(key URL) (string, error) { +func (e *Endpoints) GetURL(endpoint URL) (string, error) { e.mu.RLock() defer e.mu.RUnlock() - val, ok := e.defaults[key.String()] + val, ok := e.defaults[endpoint.String()] if !ok { - return "", fmt.Errorf("no endpoint path found for the given key: %v", key) + return "", fmt.Errorf("no endpoint path found for the given key: %v", endpoint) } return val, nil } diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 37b72aae..930b5e7b 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -59,53 +59,26 @@ func TestSupportsRESTTickerBatchUpdates(t *testing.T) { } } -func TestCreateMap(t *testing.T) { +func TestSetRunningURL(t *testing.T) { t.Parallel() - b := Base{ - Name: "HELOOOOOOOO", - } + b := Base{Name: "HELOOOOOOOO"} b.API.Endpoints = b.NewEndpoints() - err := b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ - EdgeCase1: "http://test1url.com/", - EdgeCase2: "http://test2url.com/", - }) - if err != nil { - t.Error(err) - } - val, ok := b.API.Endpoints.defaults[EdgeCase1.String()] - if !ok || val != "http://test1url.com/" { - t.Errorf("CreateMap failed, incorrect value received for the given key") - } -} + assert.ErrorIs(t, b.API.Endpoints.SetRunningURL("meep", "http://google.com/"), errInvalidEndpointKey) -func TestSet(t *testing.T) { - t.Parallel() - b := Base{ - Name: "HELOOOOOOOO", - } - b.API.Endpoints = b.NewEndpoints() err := b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ EdgeCase1: "http://test1url.com/", EdgeCase2: "http://test2url.com/", }) - if err != nil { - t.Error(err) - } + assert.NoError(t, err, "SetDefaultEndpoints should not error") err = b.API.Endpoints.SetRunningURL(EdgeCase2.String(), "http://google.com/") - if err != nil { - t.Error(err) - } + assert.NoError(t, err, "SetRunningURL should not error") + val, ok := b.API.Endpoints.defaults[EdgeCase2.String()] - if !ok { - t.Error("set method or createmap failed") - } - if val != "http://google.com/" { - t.Errorf("vals didn't match. expecting: %s, got: %s\n", "http://google.com/", val) - } + assert.True(t, ok, "SetRunningURL should have set the value in defaults") + assert.Equal(t, "http://google.com/", val) + err = b.API.Endpoints.SetRunningURL(EdgeCase3.String(), "Added Edgecase3") - if err != nil { - t.Errorf("not expecting an error since invalid url val err should be logged but received: %v", err) - } + assert.ErrorContains(t, err, "invalid URI for request", "SetRunningURL should error on invalid endpoint key") } func TestGetURL(t *testing.T) { @@ -166,30 +139,22 @@ func TestGetAll(t *testing.T) { func TestSetDefaultEndpoints(t *testing.T) { t.Parallel() - b := Base{ - Name: "HELLLLLLO", - } + b := Base{Name: "HELLLLLLO"} b.API.Endpoints = b.NewEndpoints() err := b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ EdgeCase1: "http://test1.com.au/", EdgeCase2: "http://test2.com.au/", }) - if err != nil { - t.Error(err) - } + assert.NoError(t, err, "SetDefaultEndpoints should not error") b.API.Endpoints = b.NewEndpoints() err = b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ URL(1337): "http://test2.com.au/", }) - if err == nil { - t.Error("expecting an error due to invalid url key") - } + assert.ErrorIs(t, err, errInvalidEndpointKey, "SetDefaultEndpoints should error on invalid endpoint key") err = b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ EdgeCase1: "", }) - if err != nil { - t.Errorf("expecting a warning due to invalid url value but got an error: %v", err) - } + assert.ErrorContains(t, err, "empty url") } func TestSetClientProxyAddress(t *testing.T) { @@ -475,13 +440,9 @@ func TestSetCurrencyPairFormat(t *testing.T) { if spot.Delimiter != "~" { t.Error("incorrect pair format delimiter") } - futures, err := b.GetPairFormat(asset.Futures, false) - if err != nil { - t.Fatal(err) - } - if futures.Delimiter != ":)" { - t.Error("incorrect pair format delimiter") - } + f, err := b.GetPairFormat(asset.Futures, false) + require.NoError(t, err, "GetPairFormat must not error") + assert.Equal(t, ":)", f.Delimiter, "Delimiter should be set correctly") } func TestLoadConfigPairs(t *testing.T) { @@ -1785,10 +1746,8 @@ func TestSetAPIURL(t *testing.T) { mappy.Mappymap["RestSpotURL"] = "http://google.com/" b.API.Endpoints = b.NewEndpoints() b.Config.API.OldEndPoints.URL = "heloo" - err = b.SetAPIURL() - if err != nil { - t.Errorf("expecting a warning since invalid oldendpoints url but got an error: %v", err) - } + assert.ErrorContains(t, b.SetAPIURL(), "invalid URI for request") + mappy.Mappymap = make(map[string]string) b.Config.API.OldEndPoints = &config.APIEndpointsConfig{} b.Config.API.Endpoints = mappy.Mappymap @@ -1816,17 +1775,6 @@ func TestSetAPIURL(t *testing.T) { } } -func TestSetRunningURL(t *testing.T) { - b := Base{ - Name: "HELOOOOOOOO", - } - b.API.Endpoints = b.NewEndpoints() - err := b.API.Endpoints.SetRunningURL(EdgeCase1.String(), "http://google.com/") - if err != nil { - t.Error(err) - } -} - func TestAssetWebsocketFunctionality(t *testing.T) { b := Base{} if !b.IsAssetWebsocketSupported(asset.Spot) { diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index e7f66f81..1f4bdd21 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -218,7 +218,7 @@ func (e *Exchange) GetCryptoDepositAddress(ctx context.Context) (map[string]stri // 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 *Exchange) WithdrawCryptocurrency(ctx context.Context, currency, address, invoice, transport string, amount float64) (int64, error) { +func (e *Exchange) WithdrawCryptocurrency(ctx context.Context, ccy, address, invoice, transport string, amount float64) (int64, error) { type response struct { TaskID int64 `json:"task_id,string"` Result bool `json:"result"` @@ -227,7 +227,7 @@ func (e *Exchange) WithdrawCryptocurrency(ctx context.Context, currency, address } v := url.Values{} - v.Set("currency", currency) + v.Set("currency", ccy) v.Set("address", address) if invoice != "" { @@ -258,9 +258,9 @@ func (e *Exchange) GetWithdrawTXID(ctx context.Context, taskID int64) (string, e } // ExcodeCreate creates an EXMO coupon -func (e *Exchange) ExcodeCreate(ctx context.Context, currency string, amount float64) (ExcodeCreate, error) { +func (e *Exchange) ExcodeCreate(ctx context.Context, ccy string, amount float64) (ExcodeCreate, error) { v := url.Values{} - v.Set("currency", currency) + v.Set("currency", ccy) v.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result ExcodeCreate diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index c2876b3e..16df851c 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -2470,95 +2470,6 @@ func TestUnlockSubAccount(t *testing.T) { } } -func TestParseGateioMilliSecTimeUnmarshal(t *testing.T) { - t.Parallel() - var timeWhenTesting int64 = 1684981731098 - timeWhenTestingString := `"1684981731098"` // Normal string - integerJSON := `{"number": 1684981731098}` - float64JSON := `{"number": 1684981731.098}` - - time := time.UnixMilli(timeWhenTesting) - var in types.Time - err := json.Unmarshal([]byte(timeWhenTestingString), &in) - if err != nil { - t.Fatal(err) - } - if !in.Time().Equal(time) { - t.Fatalf("found %v, but expected %v", in.Time(), time) - } - inInteger := struct { - Number types.Time `json:"number"` - }{} - err = json.Unmarshal([]byte(integerJSON), &inInteger) - if err != nil { - t.Fatal(err) - } - if !inInteger.Number.Time().Equal(time) { - t.Fatalf("found %v, but expected %v", inInteger.Number.Time(), time) - } - - inFloat64 := struct { - Number types.Time `json:"number"` - }{} - err = json.Unmarshal([]byte(float64JSON), &inFloat64) - if err != nil { - t.Fatal(err) - } - if !inFloat64.Number.Time().Equal(time) { - t.Fatalf("found %v, but expected %v", inFloat64.Number.Time(), time) - } -} - -func TestParseTimeUnmarshal(t *testing.T) { - t.Parallel() - var timeWhenTesting int64 = 1684981731 - timeWhenTestingString := `"1684981731"` - integerJSON := `{"number": 1684981731}` - float64JSON := `{"number": 1684981731.234}` - timeWhenTestingStringMicroSecond := `"1691122380942.173000"` - - whenTime := time.Unix(timeWhenTesting, 0) - var in types.Time - err := json.Unmarshal([]byte(timeWhenTestingString), &in) - if err != nil { - t.Fatal(err) - } - if !in.Time().Equal(whenTime) { - t.Fatalf("found %v, but expected %v", in.Time(), whenTime) - } - inInteger := struct { - Number types.Time `json:"number"` - }{} - err = json.Unmarshal([]byte(integerJSON), &inInteger) - if err != nil { - t.Fatal(err) - } - if !inInteger.Number.Time().Equal(whenTime) { - t.Fatalf("found %v, but expected %v", inInteger.Number.Time(), whenTime) - } - - inFloat64 := struct { - Number types.Time `json:"number"` - }{} - err = json.Unmarshal([]byte(float64JSON), &inFloat64) - if err != nil { - t.Fatal(err) - } - msTime := time.UnixMilli(1684981731234) - if !inFloat64.Number.Time().Equal(time.UnixMilli(1684981731234)) { - t.Fatalf("found %v, but expected %v", inFloat64.Number.Time(), msTime) - } - - var microSeconds types.Time - err = json.Unmarshal([]byte(timeWhenTestingStringMicroSecond), µSeconds) - if err != nil { - t.Fatal(err) - } - if !microSeconds.Time().Equal(time.UnixMicro(1691122380942173)) { - t.Fatalf("found %v, but expected %v", microSeconds.Time(), time.UnixMicro(1691122380942173)) - } -} - func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() testexch.UpdatePairsOnce(t, e) diff --git a/exchanges/gateio/gateio_websocket_request_futures.go b/exchanges/gateio/gateio_websocket_request_futures.go index a5120f71..a5340697 100644 --- a/exchanges/gateio/gateio_websocket_request_futures.go +++ b/exchanges/gateio/gateio_websocket_request_futures.go @@ -23,8 +23,8 @@ func (e *Exchange) authenticateFutures(ctx context.Context, conn websocket.Conne } // WebsocketFuturesSubmitOrder submits an order via the websocket connection -func (e *Exchange) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, order *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) { - resps, err := e.WebsocketFuturesSubmitOrders(ctx, a, order) +func (e *Exchange) WebsocketFuturesSubmitOrder(ctx context.Context, a asset.Item, o *ContractOrderCreateParams) (*WebsocketFuturesOrderResponse, error) { + resps, err := e.WebsocketFuturesSubmitOrders(ctx, a, o) if err != nil { return nil, err } diff --git a/exchanges/gateio/gateio_websocket_request_spot.go b/exchanges/gateio/gateio_websocket_request_spot.go index 1939571a..6f794841 100644 --- a/exchanges/gateio/gateio_websocket_request_spot.go +++ b/exchanges/gateio/gateio_websocket_request_spot.go @@ -25,8 +25,8 @@ func (e *Exchange) authenticateSpot(ctx context.Context, conn websocket.Connecti } // WebsocketSpotSubmitOrder submits an order via the websocket connection -func (e *Exchange) WebsocketSpotSubmitOrder(ctx context.Context, order *CreateOrderRequest) (*WebsocketOrderResponse, error) { - resps, err := e.WebsocketSpotSubmitOrders(ctx, order) +func (e *Exchange) WebsocketSpotSubmitOrder(ctx context.Context, o *CreateOrderRequest) (*WebsocketOrderResponse, error) { + resps, err := e.WebsocketSpotSubmitOrders(ctx, o) if err != nil { return nil, err } diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index f893fe5a..e8e7725e 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -335,15 +335,15 @@ func (e *Exchange) GetBalances(ctx context.Context) ([]Balance, error) { } // GetCryptoDepositAddress returns a deposit address -func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, currency string) (DepositAddress, error) { +func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, depositAddLabel, ccy string) (DepositAddress, error) { response := DepositAddress{} req := make(map[string]any) - if depositAddlabel != "" { - req["label"] = depositAddlabel + if depositAddLabel != "" { + req["label"] = depositAddLabel } - err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+ccy+"/"+geminiNewAddress, req, &response) if err != nil { return response, err } @@ -354,13 +354,13 @@ func (e *Exchange) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, } // WithdrawCrypto withdraws crypto currency to a whitelisted address -func (e *Exchange) WithdrawCrypto(ctx context.Context, address, currency string, amount float64) (WithdrawalAddress, error) { +func (e *Exchange) WithdrawCrypto(ctx context.Context, address, ccy string, amount float64) (WithdrawalAddress, error) { response := WithdrawalAddress{} req := make(map[string]any) req["address"] = address req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(currency), req, &response) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(ccy), req, &response) if err != nil { return response, err } diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index 97efbd29..975d08bc 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -70,12 +70,12 @@ func (e *Exchange) GetCurrencies(ctx context.Context) (map[string]Currencies, er // GetCurrency returns the actual list of available currencies, tokens, ICO // etc. -func (e *Exchange) GetCurrency(ctx context.Context, currency string) (Currencies, error) { +func (e *Exchange) GetCurrency(ctx context.Context, symbol string) (Currencies, error) { type Response struct { Data Currencies } resp := Response{} - path := apiV2Currency + "/" + currency + path := apiV2Currency + "/" + symbol return resp.Data, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) } @@ -225,22 +225,22 @@ func (e *Exchange) GetBalances(ctx context.Context) (map[string]Balance, error) } // GetDepositAddresses returns a deposit address for a specific currency -func (e *Exchange) GetDepositAddresses(ctx context.Context, currency string) (DepositCryptoAddresses, error) { +func (e *Exchange) GetDepositAddresses(ctx context.Context, ccy string) (DepositCryptoAddresses, error) { var resp DepositCryptoAddresses return resp, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, - apiV2CryptoAddress+"/"+currency, + apiV2CryptoAddress+"/"+ccy, url.Values{}, otherRequests, &resp) } // GenerateNewAddress generates a new deposit address for a currency -func (e *Exchange) GenerateNewAddress(ctx context.Context, currency string) (DepositCryptoAddresses, error) { +func (e *Exchange) GenerateNewAddress(ctx context.Context, ccy string) (DepositCryptoAddresses, error) { resp := DepositCryptoAddresses{} err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, - apiV2CryptoAddress+"/"+currency, + apiV2CryptoAddress+"/"+ccy, url.Values{}, otherRequests, &resp) @@ -249,7 +249,7 @@ func (e *Exchange) GenerateNewAddress(ctx context.Context, currency string) (Dep } // GetTradeHistoryForCurrency returns your trade history -func (e *Exchange) GetTradeHistoryForCurrency(ctx context.Context, currency, start, end string) (AuthenticatedTradeHistoryResponse, error) { +func (e *Exchange) GetTradeHistoryForCurrency(ctx context.Context, ccyPair, start, end string) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start != "" { @@ -260,7 +260,7 @@ func (e *Exchange) GetTradeHistoryForCurrency(ctx context.Context, currency, sta values.Set("end", end) } - values.Set("currencyPair", currency) + values.Set("currencyPair", ccyPair) result := AuthenticatedTradeHistoryResponse{} return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, @@ -293,9 +293,9 @@ func (e *Exchange) GetTradeHistoryForAllCurrencies(ctx context.Context, start, e } // GetOrders List of your order history. -func (e *Exchange) GetOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { +func (e *Exchange) GetOrders(ctx context.Context, symbol string) ([]OrderHistoryResponse, error) { values := url.Values{} - values.Set("symbol", currency) + values.Set("symbol", symbol) var result []OrderHistoryResponse return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, @@ -306,9 +306,9 @@ func (e *Exchange) GetOrders(ctx context.Context, currency string) ([]OrderHisto } // GetOpenOrders List of your currently open orders. -func (e *Exchange) GetOpenOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, symbol string) ([]OrderHistoryResponse, error) { values := url.Values{} - values.Set("symbol", currency) + values.Set("symbol", symbol) var result []OrderHistoryResponse return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, @@ -330,11 +330,11 @@ func (e *Exchange) GetActiveOrderByClientOrderID(ctx context.Context, clientOrde } // PlaceOrder places an order on the exchange -func (e *Exchange) PlaceOrder(ctx context.Context, currency string, rate, amount float64, orderType, side string) (OrderResponse, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, symbol string, rate, amount float64, orderType, side string) (OrderResponse, error) { var result OrderResponse values := url.Values{} - values.Set("symbol", currency) + values.Set("symbol", symbol) values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64)) values.Set("quantity", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("side", side) @@ -381,11 +381,11 @@ func (e *Exchange) CancelAllExistingOrders(ctx context.Context) ([]Order, error) } // Withdraw allows for the withdrawal to a specific address -func (e *Exchange) Withdraw(ctx context.Context, currency, address string, amount float64) (bool, error) { +func (e *Exchange) Withdraw(ctx context.Context, ccy, address string, amount float64) (bool, error) { result := Withdraw{} values := url.Values{} - values.Set("currency", currency) + values.Set("currency", ccy) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 18fa0609..eb01e8ad 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -566,8 +566,8 @@ func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair curren } // GetDepositAddress returns a deposit address for a specified currency -func (e *Exchange) GetDepositAddress(ctx context.Context, currency currency.Code, _, _ string) (*deposit.Address, error) { - resp, err := e.GetDepositAddresses(ctx, currency.String()) +func (e *Exchange) GetDepositAddress(ctx context.Context, ccy currency.Code, _, _ string) (*deposit.Address, error) { + resp, err := e.GetDepositAddresses(ctx, ccy.String()) if err != nil { return nil, err } diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 013f376b..1c55a638 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -537,7 +537,7 @@ func (e *Exchange) GetOrderMatchResults(ctx context.Context, orderID int64) ([]O } // GetOrders returns a list of orders -func (e *Exchange) 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, orderTypes, start, end, states, from, direct, size string) ([]OrderInfo, error) { resp := struct { Orders []OrderInfo `json:"data"` }{} @@ -550,8 +550,8 @@ func (e *Exchange) GetOrders(ctx context.Context, symbol currency.Pair, types, s vals.Set("symbol", symbolValue) vals.Set("states", states) - if types != "" { - vals.Set("types", types) + if orderTypes != "" { + vals.Set("types", orderTypes) } if start != "" { @@ -601,7 +601,7 @@ func (e *Exchange) GetOpenOrders(ctx context.Context, symbol currency.Pair, acco } // GetOrdersMatch returns a list of matched orders -func (e *Exchange) 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, orderTypes, start, end, from, direct, size string) ([]OrderMatchInfo, error) { resp := struct { Orders []OrderMatchInfo `json:"data"` }{} @@ -613,8 +613,8 @@ func (e *Exchange) GetOrdersMatch(ctx context.Context, symbol currency.Pair, typ } vals.Set("symbol", symbolValue) - if types != "" { - vals.Set("types", types) + if orderTypes != "" { + vals.Set("types", orderTypes) } if start != "" { @@ -642,7 +642,7 @@ func (e *Exchange) GetOrdersMatch(ctx context.Context, symbol currency.Pair, typ } // MarginTransfer transfers assets into or out of the margin account -func (e *Exchange) MarginTransfer(ctx context.Context, symbol currency.Pair, currency string, amount float64, in bool) (int64, error) { +func (e *Exchange) MarginTransfer(ctx context.Context, symbol currency.Pair, ccy string, amount float64, in bool) (int64, error) { symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err @@ -653,7 +653,7 @@ func (e *Exchange) MarginTransfer(ctx context.Context, symbol currency.Pair, cur Amount string `json:"amount"` }{ Symbol: symbolValue, - Currency: currency, + Currency: ccy, Amount: strconv.FormatFloat(amount, 'f', -1, 64), } @@ -670,7 +670,7 @@ func (e *Exchange) MarginTransfer(ctx context.Context, symbol currency.Pair, cur } // MarginOrder submits a margin order application -func (e *Exchange) MarginOrder(ctx context.Context, symbol currency.Pair, currency string, amount float64) (int64, error) { +func (e *Exchange) MarginOrder(ctx context.Context, symbol currency.Pair, ccy string, amount float64) (int64, error) { symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err @@ -681,7 +681,7 @@ func (e *Exchange) MarginOrder(ctx context.Context, symbol currency.Pair, curren Amount string `json:"amount"` }{ Symbol: symbolValue, - Currency: currency, + Currency: ccy, Amount: strconv.FormatFloat(amount, 'f', -1, 64), } @@ -710,14 +710,14 @@ func (e *Exchange) MarginRepayment(ctx context.Context, orderID int64, amount fl } // GetMarginLoanOrders returns the margin loan orders -func (e *Exchange) 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, ccy, start, end, states, from, direct, size string) ([]MarginOrder, error) { vals := url.Values{} symbolValue, err := e.FormatSymbol(symbol, asset.Spot) if err != nil { return nil, err } vals.Set("symbol", symbolValue) - vals.Set("currency", currency) + vals.Set("currency", ccy) if start != "" { vals.Set("start-date", start) diff --git a/exchanges/kline/kline_datastorage.go b/exchanges/kline/kline_datastorage.go index 5af841e6..3e7bebbe 100644 --- a/exchanges/kline/kline_datastorage.go +++ b/exchanges/kline/kline_datastorage.go @@ -18,16 +18,14 @@ import ( ) // LoadFromDatabase returns Item from database seeded data -func LoadFromDatabase(exchange string, pair currency.Pair, a asset.Item, interval Interval, start, end time.Time) (*Item, error) { - retCandle, err := candle.Series(exchange, - pair.Base.String(), pair.Quote.String(), - int64(interval.Duration().Seconds()), a.String(), start, end) +func LoadFromDatabase(exch string, pair currency.Pair, a asset.Item, interval Interval, start, end time.Time) (*Item, error) { + retCandle, err := candle.Series(exch, pair.Base.String(), pair.Quote.String(), int64(interval.Duration().Seconds()), a.String(), start, end) if err != nil { return nil, err } ret := Item{ - Exchange: exchange, + Exchange: exch, Pair: pair, Interval: interval, Asset: a, diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 701fa107..dc77a8aa 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -338,26 +338,22 @@ func (e *Exchange) GetBalance(ctx context.Context) (map[string]Balance, error) { } // GetWithdrawInfo gets withdrawal fees -func (e *Exchange) GetWithdrawInfo(ctx context.Context, currency string, amount float64) (*WithdrawInformation, error) { +func (e *Exchange) GetWithdrawInfo(ctx context.Context, withdrawalAsset, withdrawalKey string, amount float64) (*WithdrawInformation, error) { params := url.Values{} - params.Set("asset", currency) - params.Set("key", "") + params.Set("asset", withdrawalAsset) + params.Set("key", withdrawalKey) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - var result WithdrawInformation - if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawInfo, params, &result); err != nil { - return nil, err - } - - return &result, nil + var result *WithdrawInformation + return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawInfo, params, &result) } // Withdraw withdraws funds -func (e *Exchange) Withdraw(ctx context.Context, asset, key string, amount float64) (string, error) { +func (e *Exchange) Withdraw(ctx context.Context, withdrawalAsset, withdrawalKey string, amount float64) (string, error) { params := url.Values{} - params.Set("asset", asset) - params.Set("key", key) - params.Set("amount", fmt.Sprintf("%f", amount)) + params.Set("asset", withdrawalAsset) + params.Set("key", withdrawalKey) + params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var referenceID string if err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdraw, params, &referenceID); err != nil { @@ -367,10 +363,10 @@ func (e *Exchange) Withdraw(ctx context.Context, asset, key string, amount float return referenceID, nil } -// GetDepositMethods gets withdrawal fees -func (e *Exchange) GetDepositMethods(ctx context.Context, currency string) ([]DepositMethods, error) { +// GetDepositMethods gets withdrawal fees for a specific asset +func (e *Exchange) GetDepositMethods(ctx context.Context, a string) ([]DepositMethods, error) { params := url.Values{} - params.Set("asset", currency) + params.Set("asset", a) var result []DepositMethods err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositMethods, params, &result) @@ -899,8 +895,8 @@ func getCryptocurrencyDepositFee(c currency.Code) float64 { return DepositFees[c] } -func calculateTradingFee(currency string, feePair map[string]TradeVolumeFee, purchasePrice, amount float64) float64 { - return (feePair[currency].Fee / 100) * purchasePrice * amount +func calculateTradingFee(ccy string, feePair map[string]TradeVolumeFee, purchasePrice, amount float64) float64 { + return (feePair[ccy].Fee / 100) * purchasePrice * amount } // GetCryptoDepositAddress returns a deposit address for a cryptocurrency diff --git a/exchanges/kraken/kraken_futures.go b/exchanges/kraken/kraken_futures.go index 6c0e5acf..be70ee34 100644 --- a/exchanges/kraken/kraken_futures.go +++ b/exchanges/kraken/kraken_futures.go @@ -295,10 +295,10 @@ func (e *Exchange) FuturesRecentOrders(ctx context.Context, symbol currency.Pair } // FuturesWithdrawToSpotWallet withdraws currencies from futures wallet to spot wallet -func (e *Exchange) FuturesWithdrawToSpotWallet(ctx context.Context, currency string, amount float64) (GenericResponse, error) { +func (e *Exchange) FuturesWithdrawToSpotWallet(ctx context.Context, ccy string, amount float64) (GenericResponse, error) { var resp GenericResponse params := url.Values{} - params.Set("currency", currency) + params.Set("currency", ccy) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) return resp, e.SendFuturesAuthRequest(ctx, http.MethodPost, futuresWithdraw, params, &resp) } diff --git a/exchanges/kraken/kraken_websocket.go b/exchanges/kraken/kraken_websocket.go index 1f23fc2b..48dc0820 100644 --- a/exchanges/kraken/kraken_websocket.go +++ b/exchanges/kraken/kraken_websocket.go @@ -314,23 +314,23 @@ func (e *Exchange) wsProcessOwnTrades(ownOrdersRaw json.RawMessage) error { Err: err, } } - trade := order.TradeHistory{ - Price: val.Price, - Amount: val.Vol, - Fee: val.Fee, - Exchange: e.Name, - TID: key, - Type: oType, - Side: oSide, - Timestamp: val.Time.Time(), - } e.Websocket.DataHandler <- &order.Detail{ Exchange: e.Name, OrderID: val.OrderTransactionID, - Trades: []order.TradeHistory{trade}, + Trades: []order.TradeHistory{ + { + Price: val.Price, + Amount: val.Vol, + Fee: val.Fee, + Exchange: e.Name, + TID: key, + Type: oType, + Side: oSide, + Timestamp: val.Time.Time(), + }, + }, } } - return nil } diff --git a/exchanges/mock/recording.go b/exchanges/mock/recording.go index 24673a5e..c2b72fa1 100644 --- a/exchanges/mock/recording.go +++ b/exchanges/mock/recording.go @@ -449,7 +449,7 @@ func GetExcludedItems() (Exclusion, error) { m.Lock() defer m.Unlock() if !set { - file, err := os.ReadFile(exclusionFile) + f, err := os.ReadFile(exclusionFile) if err != nil { if !strings.Contains(err.Error(), "no such file or directory") { return excludedList, err @@ -468,7 +468,7 @@ func GetExcludedItems() (Exclusion, error) { return excludedList, mErr } } else { - err = json.Unmarshal(file, &excludedList) + err = json.Unmarshal(f, &excludedList) if err != nil { return excludedList, err } diff --git a/exchanges/okx/okx.go b/exchanges/okx/okx.go index 2b4bd44c..c6de2cb2 100644 --- a/exchanges/okx/okx.go +++ b/exchanges/okx/okx.go @@ -1360,9 +1360,9 @@ func (e *Exchange) GetDepositWithdrawalStatus(ctx context.Context, ccy currency. } // SmallAssetsConvert Convert small assets in funding account to OKB. Only one convert is allowed within 24 hours -func (e *Exchange) SmallAssetsConvert(ctx context.Context, currency []string) (*SmallAssetConvertResponse, error) { +func (e *Exchange) SmallAssetsConvert(ctx context.Context, currencies []string) (*SmallAssetConvertResponse, error) { var resp *SmallAssetConvertResponse - return resp, e.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": currencies}, &resp, request.AuthenticatedRequest) } // GetPublicExchangeList retrieves exchanges diff --git a/exchanges/okx/okx_test.go b/exchanges/okx/okx_test.go index 49dcc585..11ef2a28 100644 --- a/exchanges/okx/okx_test.go +++ b/exchanges/okx/okx_test.go @@ -295,13 +295,13 @@ func TestGetBlockTrade(t *testing.T) { 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.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") + blockTrade := trades[0] + assert.Equal(t, mainPair.String(), blockTrade.InstrumentID, "InstrumentID should have correct value") + assert.NotEmpty(t, blockTrade.TradeID, "TradeID should not be empty") + assert.Positive(t, blockTrade.Price.Float64(), "Price should have a positive value") + assert.Positive(t, blockTrade.Size.Float64(), "Size should have a positive value") + assert.Contains(t, []order.Side{order.Buy, order.Sell}, blockTrade.Side, "Side should be a side") + assert.WithinRange(t, blockTrade.Timestamp.Time(), time.Now().Add(time.Hour*-24*90), time.Now(), "Timestamp should be within last 90 days") } testexch.UpdatePairsOnce(t, e) diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 915fc4d4..26b1e266 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -244,9 +244,9 @@ func (e *Exchange) 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 (e *Exchange) GetLoanOrders(ctx context.Context, currency string) (LoanOrders, error) { +func (e *Exchange) GetLoanOrders(ctx context.Context, ccy string) (LoanOrders, error) { resp := LoanOrders{} - path := "/public?command=returnLoanOrders¤cy=" + currency + path := "/public?command=returnLoanOrders¤cy=" + ccy return resp, e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } @@ -365,9 +365,9 @@ func (e *Exchange) GetDepositsWithdrawals(ctx context.Context, start, end string } // GetOpenOrders returns current unfilled opened orders -func (e *Exchange) GetOpenOrders(ctx context.Context, currency string) (OpenOrdersResponse, error) { +func (e *Exchange) GetOpenOrders(ctx context.Context, ccy string) (OpenOrdersResponse, error) { values := url.Values{} - values.Set("currencyPair", currency) + values.Set("currencyPair", ccy) result := OpenOrdersResponse{} return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) } @@ -381,7 +381,7 @@ func (e *Exchange) GetOpenOrdersForAllCurrencies(ctx context.Context) (OpenOrder } // GetAuthenticatedTradeHistoryForCurrency returns account trade history -func (e *Exchange) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { +func (e *Exchange) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, currencyPair string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start > 0 { @@ -396,7 +396,7 @@ func (e *Exchange) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, values.Set("end", strconv.FormatInt(end, 10)) } - values.Set("currencyPair", currency) + values.Set("currencyPair", currencyPair) result := AuthenticatedTradeHistoryResponse{} return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result.Data) } @@ -512,7 +512,7 @@ func (e *Exchange) GetAuthenticatedOrderTrades(ctx context.Context, orderID stri } // PlaceOrder places a new order on the exchange -func (e *Exchange) PlaceOrder(ctx context.Context, currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { +func (e *Exchange) PlaceOrder(ctx context.Context, currencyPair string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -523,7 +523,7 @@ func (e *Exchange) PlaceOrder(ctx context.Context, currency string, rate, amount orderType = order.Sell.Lower() } - values.Set("currencyPair", currency) + values.Set("currencyPair", currencyPair) values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64)) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -603,11 +603,11 @@ func (e *Exchange) 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 (e *Exchange) Withdraw(ctx context.Context, currency, address string, amount float64) (*Withdraw, error) { +func (e *Exchange) Withdraw(ctx context.Context, ccy, address string, amount float64) (*Withdraw, error) { result := &Withdraw{} values := url.Values{} - values.Set("currency", strings.ToUpper(currency)) + values.Set("currency", strings.ToUpper(ccy)) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) @@ -662,11 +662,11 @@ func (e *Exchange) GetTradableBalances(ctx context.Context) (map[string]map[stri } // TransferBalance transfers balances between your accounts -func (e *Exchange) TransferBalance(ctx context.Context, currency, from, to string, amount float64) (bool, error) { +func (e *Exchange) TransferBalance(ctx context.Context, ccy, from, to string, amount float64) (bool, error) { values := url.Values{} result := GenericResponse{} - values.Set("currency", currency) + values.Set("currency", ccy) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("fromAccount", from) values.Set("toAccount", to) @@ -690,7 +690,7 @@ func (e *Exchange) GetMarginAccountSummary(ctx context.Context) (Margin, error) } // PlaceMarginOrder places a margin order -func (e *Exchange) PlaceMarginOrder(ctx context.Context, currency string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { +func (e *Exchange) PlaceMarginOrder(ctx context.Context, currencyPair string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -701,7 +701,7 @@ func (e *Exchange) PlaceMarginOrder(ctx context.Context, currency string, rate, orderType = poloniexMarginSell } - values.Set("currencyPair", currency) + values.Set("currencyPair", currencyPair) values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64)) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -713,11 +713,11 @@ func (e *Exchange) PlaceMarginOrder(ctx context.Context, currency string, rate, } // GetMarginPosition returns a position on a margin order -func (e *Exchange) GetMarginPosition(ctx context.Context, currency string) (any, error) { +func (e *Exchange) GetMarginPosition(ctx context.Context, currencyPair string) (any, error) { values := url.Values{} - if currency != "" && currency != "all" { - values.Set("currencyPair", currency) + if currencyPair != "" && currencyPair != "all" { + values.Set("currencyPair", currencyPair) result := MarginPosition{} return result, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result) } @@ -731,9 +731,9 @@ func (e *Exchange) GetMarginPosition(ctx context.Context, currency string) (any, } // CloseMarginPosition closes a current margin position -func (e *Exchange) CloseMarginPosition(ctx context.Context, currency string) (bool, error) { +func (e *Exchange) CloseMarginPosition(ctx context.Context, currencyPair string) (bool, error) { values := url.Values{} - values.Set("currencyPair", currency) + values.Set("currencyPair", currencyPair) result := GenericResponse{} err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPositionClose, values, &result) @@ -749,9 +749,9 @@ func (e *Exchange) CloseMarginPosition(ctx context.Context, currency string) (bo } // CreateLoanOffer places a loan offer on the exchange -func (e *Exchange) CreateLoanOffer(ctx context.Context, currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) { +func (e *Exchange) CreateLoanOffer(ctx context.Context, ccy string, amount, rate float64, duration int, autoRenew bool) (int64, error) { values := url.Values{} - values.Set("currency", currency) + values.Set("currency", ccy) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("duration", strconv.Itoa(duration)) diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index cf72c23a..69f41c53 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -235,9 +235,9 @@ func (e *Exchange) WithdrawCoinsToAddress(ctx context.Context, coin string, amou } // CreateCoupon creates an exchange coupon for a specific currency -func (e *Exchange) CreateCoupon(ctx context.Context, currency string, amount float64) (CreateCoupon, error) { +func (e *Exchange) CreateCoupon(ctx context.Context, ccy string, amount float64) (CreateCoupon, error) { req := url.Values{} - req.Add("currency", currency) + req.Add("currency", ccy) req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result CreateCoupon diff --git a/go.mod b/go.mod index ab571211..6e72203f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/thrasher-corp/gocryptotrader -go 1.24.1 +go 1.25 require ( github.com/Masterminds/sprig/v3 v3.3.0 diff --git a/log/logger_rotate.go b/log/logger_rotate.go index d569c19a..b12ba70d 100644 --- a/log/logger_rotate.go +++ b/log/logger_rotate.go @@ -61,12 +61,12 @@ func (r *Rotate) openOrCreateFile(n int64) error { } } - file, err := os.OpenFile(logFile, os.O_APPEND|os.O_WRONLY, 0o600) + f, err := os.OpenFile(logFile, os.O_APPEND|os.O_WRONLY, 0o600) if err != nil { return r.openNew() } - r.output = file + r.output = f r.size = info.Size() return nil @@ -89,12 +89,12 @@ func (r *Rotate) openNew() error { } } - file, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) + f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) if err != nil { return fmt.Errorf("can't open new logfile: %s", err) } - r.output = file + r.output = f r.size = 0 return nil }