From 179519a3c341c20c1494acad6edea4ac19a9416a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:36:05 +1100 Subject: [PATCH] golangci-lint: Bump to v2.0.2 and fix issues (#1871) * build(deps): Bump golangci/golangci-lint-action from 6 to 7 Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6 to 7. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v6...v7) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * golangci-lint: Bump to v2 and fix issues * refactor: remove no longer need ifshort nolint directives, fix test grammar and improve for loop logic * nits: update order pair handling in tests and improve string replacement logic --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Adrian Gallagher --- .github/workflows/linter.yml | 4 +- .golangci.yml | 154 ++++++++++-------- Makefile | 2 +- .../config/strategyconfigbuilder/main.go | 27 +-- backtester/engine/setup.go | 4 +- .../portfolio/holdings/holdings_test.go | 2 +- backtester/report/report.go | 5 +- cmd/dbmigrate/main.go | 23 ++- cmd/dbseed/database.go | 24 +-- cmd/documentation/documentation.go | 9 +- common/common.go | 2 +- config/config_test.go | 2 +- .../currencyconverterapi.go | 4 +- .../exchangeratesapi.io/exchangeratesapi.go | 2 +- currency/pairs_test.go | 2 +- database/testhelpers/test_helpers.go | 32 ++-- encoding/json/common.go | 2 +- engine/datahistory_manager.go | 4 +- engine/order_manager_test.go | 4 +- engine/rpcserver.go | 68 ++++---- engine/withdraw_manager.go | 26 ++- exchanges/binance/binance_wrapper.go | 14 +- exchanges/binanceus/binanceus.go | 10 +- exchanges/binanceus/binanceus_test.go | 62 +++---- exchanges/bitfinex/bitfinex_wrapper.go | 5 +- exchanges/bithumb/bithumb_wrapper.go | 16 +- exchanges/btse/btse_websocket.go | 8 +- exchanges/btse/btse_wrapper.go | 15 +- exchanges/bybit/bybit_wrapper.go | 2 +- exchanges/deribit/deribit.go | 2 +- exchanges/deribit/deribit_websocket.go | 6 +- exchanges/deribit/deribit_wrapper.go | 10 +- exchanges/exchange_test.go | 2 +- exchanges/gateio/gateio.go | 2 +- exchanges/gateio/gateio_test.go | 2 +- exchanges/gemini/gemini_wrapper.go | 20 ++- exchanges/kucoin/kucoin_wrapper.go | 33 ++-- exchanges/margin/margin_test.go | 2 +- exchanges/okx/okx.go | 7 +- exchanges/okx/okx_wrapper.go | 14 +- exchanges/order/orders.go | 2 +- exchanges/poloniex/poloniex_test.go | 4 +- exchanges/stream/websocket_test.go | 2 +- exchanges/subscription/store_test.go | 2 +- gctscript/vm/vm_test.go | 2 +- 45 files changed, 342 insertions(+), 304 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 1bd1e4b5..52c588bb 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -10,6 +10,6 @@ jobs: with: go-version: '1.24.x' - name: golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v7 with: - version: v1.64.6 \ No newline at end of file + version: v2.0.2 \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index cb66cadf..c09cf7d1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,14 +1,13 @@ +version: "2" run: - timeout: 10m issues-exit-code: 1 tests: true linters: - disable-all: true + default: none enable: # defaults - errcheck - - gosimple - govet - ineffassign - staticcheck @@ -41,7 +40,6 @@ linters: # - forbidigo - forcetypeassert # - funlen - - gci # - ginkgolinter - gocheckcompilerdirectives # - gochecknoglobals @@ -53,22 +51,20 @@ linters: # - gocyclo # - godot # - godox - - gofmt - - gofumpt # - goheader - - goimports - gomoddirectives - gomodguard - goprintffuncname - gosec # - gosmopolitan - grouper + - iface # - importas # - inamedparam # - interfacebloat - intrange # - ireturn -# - lll +# - lll # - loggercheck # - maintidx - makezero @@ -79,6 +75,7 @@ linters: # - nakedret # - nestif - nilerr + - nilnesserr # - nilnil # - nlreturn - noctx @@ -92,15 +89,14 @@ linters: # - promlinter # - protogetter - reassign +# - recvcheck - revive - rowserrcheck # - sloglint # - spancheck - sqlclosecheck - - stylecheck - tagalign # - tagliatelle -# - tenv # Duplicate feature of another linter. Replaced by usetesting. - testableexamples - testifylint # - testpackage @@ -117,61 +113,91 @@ linters: # - wsl # - zerologlint -linters-settings: - depguard: + settings: + depguard: + rules: + prevent_json_package_use: + list-mode: lax + files: + - $all + allow: + - github.com/thrasher-corp/gocryptotrader/encoding/json + deny: + - pkg: encoding/json + desc: Please use the custom JSON package github.com/thrasher-corp/gocryptotrader/encoding/json instead of encoding/json to allow sonic/json switching. + goconst: + min-occurrences: 6 + gocritic: + disabled-checks: + - wrapperFunc + - importShadow + - methodExprCall + - evalOrder + enabled-tags: + - performance + - style + - experimental + govet: + enable: + - shadow + - nilness + - unusedwrite + staticcheck: + checks: + - all + - '-ST1000' # Disable at least one file in a package should have a package comment check + - '-QF1005' # Disable expand call to math.Pow check + - '-QF1008' # Disable embedded field from selector check + testifylint: + enable-all: true + disable: + - require-error + - float-compare + # We deliberately use Equal over Len to avoid spamming the contents of large Slices + - len + exclusions: + generated: lax + presets: + - common-false-positives + - legacy + - std-error-handling rules: - prevent_json_package_use: - list-mode: lax # allow unless explicitely denied - files: - - $all - allow: - - github.com/thrasher-corp/gocryptotrader/encoding/json - deny: - - pkg: encoding/json - desc: "Please use the custom JSON package github.com/thrasher-corp/gocryptotrader/encoding/json instead of encoding/json to allow sonic/json switching." - govet: - enable: - - shadow - - nilness - - unusedwrite - goconst: - min-occurrences: 6 - gocritic: - enabled-tags: - - performance - - style - - experimental - disabled-checks: - - wrapperFunc - - importShadow - - methodExprCall - - evalOrder - testifylint: - enable-all: true - disable: - - require-error - - float-compare - # We deliberately use Equal over Len to avoid spamming the contents of large Slices - - len - gofumpt: - extra-rules: true + - linters: + - gosec + text: Expect WriteFile permissions to be 0600 or less + - linters: + - govet + text: 'shadow: declaration of "err" shadows declaration at' + - linters: + - revive + text: 'should have a package comment' + paths: + - vendor + - web/ + - testdata + - database/models/ + - third_party$ + - builtin$ + - examples$ issues: max-issues-per-linter: 0 max-same-issues: 0 - - exclude-rules: - - text: "Expect WriteFile permissions to be 0600 or less" - linters: - - gosec - - text: 'shadow: declaration of "err" shadows declaration at' - linters: [ govet ] - - exclude-dirs: - - vendor - - web/ - - testdata - - database/models/ - - include: - - EXC0012 # revive: Comment exported (.+) should have comment( \(or a comment on this block\))? or be unexported - - EXC0014 # revive: Comment on exported (.+) should be of the form "(.+)..." +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + settings: + gofumpt: + extra-rules: true + exclusions: + generated: lax + paths: + - vendor + - web/ + - testdata + - database/models/ + - third_party$ + - builtin$ + - examples$ diff --git a/Makefile b/Makefile index 430f2541..1887a493 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/cmd/golangci-lint@v1.64.6 +LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v2.0.2 LINTBIN = $(GOPATH)/bin/golangci-lint GCTLISTENPORT=9050 GCTPROFILERLISTENPORT=8085 diff --git a/backtester/config/strategyconfigbuilder/main.go b/backtester/config/strategyconfigbuilder/main.go index 1f29cb10..1006461e 100644 --- a/backtester/config/strategyconfigbuilder/main.go +++ b/backtester/config/strategyconfigbuilder/main.go @@ -435,22 +435,24 @@ func parseDatabase(reader *bufio.Reader, cfg *config.Config) error { } } cfg.DataSettings.DatabaseData.Config.Port = uint32(port) //nolint:gosec // No overflow risk - err = database.DB.SetConfig(&cfg.DataSettings.DatabaseData.Config) - if err != nil { + + if err = database.DB.SetConfig(&cfg.DataSettings.DatabaseData.Config); err != nil { return fmt.Errorf("database failed to set config: %w", err) } - if cfg.DataSettings.DatabaseData.Config.Driver == database.DBPostgreSQL { + + switch cfg.DataSettings.DatabaseData.Config.Driver { + case database.DBPostgreSQL: _, err = dbPSQL.Connect(&cfg.DataSettings.DatabaseData.Config) - if err != nil { - return fmt.Errorf("database failed to connect: %v", err) - } - } else if cfg.DataSettings.DatabaseData.Config.Driver == database.DBSQLite || - cfg.DataSettings.DatabaseData.Config.Driver == database.DBSQLite3 { + case database.DBSQLite, database.DBSQLite3: _, err = dbsqlite3.Connect(cfg.DataSettings.DatabaseData.Config.Database) - if err != nil { - return fmt.Errorf("database failed to connect: %v", err) - } + default: + return fmt.Errorf("unsupported database driver: %q", cfg.DataSettings.DatabaseData.Config.Driver) } + + if err != nil { + return fmt.Errorf("database failed to connect: %w", err) + } + return nil } @@ -747,6 +749,5 @@ func quickParse(reader *bufio.Reader) string { if err != nil { log.Fatal(err) } - customSettingField = strings.Replace(customSettingField, "\r", "", -1) - return strings.Replace(customSettingField, "\n", "", -1) + return strings.TrimRight(customSettingField, "\r\n") } diff --git a/backtester/engine/setup.go b/backtester/engine/setup.go index a222359c..8f2ad685 100644 --- a/backtester/engine/setup.go +++ b/backtester/engine/setup.go @@ -116,7 +116,7 @@ func (bt *BackTest) SetupFromConfig(cfg *config.Config, templatePath, output str return err } - if cfg.FundingSettings.UseExchangeLevelFunding && !(cfg.DataSettings.LiveData != nil && cfg.DataSettings.LiveData.RealOrders) { + if cfg.FundingSettings.UseExchangeLevelFunding && (cfg.DataSettings.LiveData == nil || !cfg.DataSettings.LiveData.RealOrders) { for i := range cfg.FundingSettings.ExchangeLevelFunding { a := cfg.FundingSettings.ExchangeLevelFunding[i].Asset cq := cfg.FundingSettings.ExchangeLevelFunding[i].Currency @@ -473,7 +473,7 @@ func (bt *BackTest) SetupFromConfig(cfg *config.Config, templatePath, output str break } } - if !hasFunding && !(cfg.DataSettings.LiveData != nil && cfg.DataSettings.LiveData.RealOrders) { + if !hasFunding && (cfg.DataSettings.LiveData == nil || !cfg.DataSettings.LiveData.RealOrders) { return holdings.ErrInitialFundsZero } diff --git a/backtester/eventhandlers/portfolio/holdings/holdings_test.go b/backtester/eventhandlers/portfolio/holdings/holdings_test.go index 97a0b9c4..b1315d0e 100644 --- a/backtester/eventhandlers/portfolio/holdings/holdings_test.go +++ b/backtester/eventhandlers/portfolio/holdings/holdings_test.go @@ -83,7 +83,7 @@ func TestUpdate(t *testing.T) { if !errors.Is(err, nil) { t.Errorf("received: %v, expected: %v", err, nil) } - t1 := h.Timestamp // nolint:ifshort,nolintlint // false positive and triggers only on Windows + t1 := h.Timestamp err = h.Update(&fill.Fill{ Base: &event.Base{ Time: time.Now(), diff --git a/backtester/report/report.go b/backtester/report/report.go index 2fe2fdc7..65ab5f01 100644 --- a/backtester/report/report.go +++ b/backtester/report/report.go @@ -205,11 +205,12 @@ func (d *Data) enhanceCandles() error { enhancedCandle.OrderAmount = decimal.NewFromFloat(statsForCandles.FinalOrders.Orders[k].Order.Amount) enhancedCandle.PurchasePrice = statsForCandles.FinalOrders.Orders[k].Order.Price enhancedCandle.OrderDirection = statsForCandles.FinalOrders.Orders[k].Order.Side - if enhancedCandle.OrderDirection == order.Buy { + switch enhancedCandle.OrderDirection { + case order.Buy: enhancedCandle.Colour = "green" enhancedCandle.Position = "aboveBar" enhancedCandle.Shape = "arrowDown" - } else if enhancedCandle.OrderDirection == order.Sell { + case order.Sell: enhancedCandle.Colour = "red" enhancedCandle.Position = "belowBar" enhancedCandle.Shape = "arrowUp" diff --git a/cmd/dbmigrate/main.go b/cmd/dbmigrate/main.go index 30ebc2cc..115ce159 100644 --- a/cmd/dbmigrate/main.go +++ b/cmd/dbmigrate/main.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" "os" @@ -27,20 +26,20 @@ var ( ) func openDBConnection(cfg *database.Config) (err error) { - if cfg.Driver == database.DBPostgreSQL { + switch cfg.Driver { + case database.DBPostgreSQL: dbConn, err = dbPSQL.Connect(cfg) - if err != nil { - return fmt.Errorf("database failed to connect: %v, some features that utilise a database will be unavailable", err) - } - return nil - } else if cfg.Driver == database.DBSQLite || cfg.Driver == database.DBSQLite3 { + case database.DBSQLite, database.DBSQLite3: dbConn, err = dbsqlite3.Connect(cfg.Database) - if err != nil { - return fmt.Errorf("database failed to connect: %v, some features that utilise a database will be unavailable", err) - } - return nil + default: + return fmt.Errorf("unsupported database driver: %q", cfg.Driver) } - return errors.New("no connection established") + + if err != nil { + return fmt.Errorf("database failed to connect: %w, some features that utilise a database will be unavailable", err) + } + + return nil } func main() { diff --git a/cmd/dbseed/database.go b/cmd/dbseed/database.go index f11f449e..95402879 100644 --- a/cmd/dbseed/database.go +++ b/cmd/dbseed/database.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "github.com/thrasher-corp/gocryptotrader/config" @@ -45,18 +44,19 @@ func openDBConnection(c *cli.Context, cfg *database.Config) (err error) { if c.IsSet("verbose") { boil.DebugMode = true } - if cfg.Driver == database.DBPostgreSQL { + + switch cfg.Driver { + case database.DBPostgreSQL: dbConn, err = dbPSQL.Connect(cfg) - if err != nil { - return fmt.Errorf("database failed to connect: %v, some features that utilise a database will be unavailable", err) - } - return nil - } else if cfg.Driver == database.DBSQLite || cfg.Driver == database.DBSQLite3 { + case database.DBSQLite, database.DBSQLite3: dbConn, err = dbsqlite3.Connect(cfg.Database) - if err != nil { - return fmt.Errorf("database failed to connect: %v, some features that utilise a database will be unavailable", err) - } - return nil + default: + return fmt.Errorf("unsupported database driver: %q", cfg.Driver) } - return errors.New("no connection established") + + if err != nil { + return fmt.Errorf("database failed to connect: %w, some features that utilise a database will be unavailable", err) + } + + return nil } diff --git a/cmd/documentation/documentation.go b/cmd/documentation/documentation.go index 6cd22a5b..efbaf378 100644 --- a/cmd/documentation/documentation.go +++ b/cmd/documentation/documentation.go @@ -507,7 +507,7 @@ func GetPackageName(name string, capital bool) string { i = len(newStrings) - 1 } if capital { - return strings.Replace(cases.Title(language.English).String(newStrings[i]), "_", " ", -1) + return cases.Title(language.English).String(strings.ReplaceAll(newStrings[i], "_", " ")) } return newStrings[i] } @@ -589,8 +589,8 @@ func UpdateDocumentation(details DocumentationDetails) { continue } var mainPath string - switch { - case name == LicenseFile || name == ContributorFile: + switch name { + case LicenseFile, ContributorFile: mainPath = details.Directories[i] default: mainPath = filepath.Join(details.Directories[i], "README.md") @@ -605,8 +605,7 @@ func UpdateDocumentation(details DocumentationDetails) { func runTemplate(details DocumentationDetails, mainPath, name string) error { err := os.Remove(mainPath) - if err != nil && !(strings.Contains(err.Error(), "no such file or directory") || - strings.Contains(err.Error(), "The system cannot find the file specified.")) { + if err != nil && !os.IsNotExist(err) { return err } diff --git a/common/common.go b/common/common.go index c69b7701..551a02d8 100644 --- a/common/common.go +++ b/common/common.go @@ -588,7 +588,7 @@ func GenerateRandomString(length uint, characters ...string) (string, error) { return "", errors.New("invalid length, length must be non-zero positive integer") } b := make([]byte, length) - chars := strings.Replace(strings.Join(characters, ""), " ", "", -1) + chars := strings.ReplaceAll(strings.Join(characters, ""), " ", "") if chars == "" && len(characters) != 0 { return "", errors.New("invalid characters, character must not be empty") } else if chars == "" { diff --git a/config/config_test.go b/config/config_test.go index 8fb4fd63..de044551 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1153,7 +1153,7 @@ func TestGetForexProviders(t *testing.T) { func TestGetPrimaryForexProvider(t *testing.T) { t.Parallel() - fxr := "Fixer" // nolint:ifshort,nolintlint // false positive and triggers only on Windows + fxr := "Fixer" cfg := &Config{ Currency: currency.Config{ ForexProviders: []currency.FXSettings{ diff --git a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go index a03f6a07..38178095 100644 --- a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go +++ b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go @@ -57,7 +57,7 @@ func (c *CurrencyConverter) GetRates(baseCurrency, symbols string) (map[string]f continue } for k, v := range result { - rates[strings.Replace(k, "_", "", -1)] = v + rates[strings.ReplaceAll(k, "_", "")] = v } } } @@ -75,7 +75,7 @@ func (c *CurrencyConverter) GetRates(baseCurrency, symbols string) (map[string]f } for k, v := range result { - rates[strings.Replace(k, "_", "", -1)] = v + rates[strings.ReplaceAll(k, "_", "")] = v } return rates, nil diff --git a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go index 7a1cbb7f..81ef8cac 100644 --- a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go +++ b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go @@ -46,7 +46,7 @@ func (e *ExchangeRates) cleanCurrencies(baseCurrency, symbols string) string { } } - symbols = strings.Replace(symbols, "RUR", "RUB", -1) + symbols = strings.ReplaceAll(symbols, "RUR", "RUB") s := strings.Split(symbols, ",") cleanedCurrencies := make([]string, 0, len(s)) for _, x := range s { diff --git a/currency/pairs_test.go b/currency/pairs_test.go index 305a65b9..24aff225 100644 --- a/currency/pairs_test.go +++ b/currency/pairs_test.go @@ -216,7 +216,7 @@ func TestRemove(t *testing.T) { require.Equal(t, oldPairs[2], newPairs[0], "Remove should leave the final pair") newPairs = newPairs.Remove(oldPairs[0]) - assert.Len(t, newPairs, 1, newPairs, "Remove have no effect on non-included pairs") + assert.Len(t, newPairs, 1, "Remove should have no effect on non-included pairs") } func TestAdd(t *testing.T) { diff --git a/database/testhelpers/test_helpers.go b/database/testhelpers/test_helpers.go index 87a1ddd2..4ab34316 100644 --- a/database/testhelpers/test_helpers.go +++ b/database/testhelpers/test_helpers.go @@ -2,6 +2,7 @@ package testhelpers import ( "database/sql" + "fmt" "path/filepath" "reflect" @@ -41,27 +42,28 @@ func GetConnectionDetails() *database.Config { // ConnectToDatabase opens connection to database and returns pointer to instance of database.DB func ConnectToDatabase(conn *database.Config) (dbConn *database.Instance, err error) { - err = database.DB.SetConfig(conn) - if err != nil { + if err := database.DB.SetConfig(conn); err != nil { return nil, err } - if conn.Driver == database.DBPostgreSQL { - dbConn, err = psqlConn.Connect(conn) - if err != nil { - return nil, err - } - } else if conn.Driver == database.DBSQLite3 || conn.Driver == database.DBSQLite { - database.DB.DataPath = TempDir - dbConn, err = sqliteConn.Connect(conn.Database) - if err != nil { - return nil, err - } - } - err = migrateDB(database.DB.SQL) + switch conn.Driver { + case database.DBPostgreSQL: + dbConn, err = psqlConn.Connect(conn) + case database.DBSQLite3, database.DBSQLite: + database.DB.DataPath = TempDir + dbConn, err = sqliteConn.Connect(conn.Database) + default: + return nil, fmt.Errorf("unsupported database driver: %q", conn.Driver) + } + if err != nil { return nil, err } + + if err := migrateDB(database.DB.SQL); err != nil { + return nil, err + } + database.DB.SetConnected(true) return } diff --git a/encoding/json/common.go b/encoding/json/common.go index 2abea733..01e85788 100644 --- a/encoding/json/common.go +++ b/encoding/json/common.go @@ -1,4 +1,4 @@ -// json is an abstraction middleware package to allow switching between json encoder/decoder implementations +// Package json is an abstraction middleware package to allow switching between json encoder/decoder implementations // The default implementation is golang.org/encoding/json. // Build with `sonic_on` tag to switch to using github.com/bytedance/sonic package json diff --git a/engine/datahistory_manager.go b/engine/datahistory_manager.go index e36f06f4..181a0bed 100644 --- a/engine/datahistory_manager.go +++ b/engine/datahistory_manager.go @@ -464,7 +464,7 @@ ranges: lookup = append(lookup, *result) job.Results[result.IntervalStartDate.Unix()] = lookup } - completed := true // nolint:ifshort,nolintlint // false positive and triggers only on Windows + completed := true allResultsSuccessful := true allResultsFailed := true completionCheck: @@ -563,7 +563,7 @@ timesToFetch: job.Results[result.IntervalStartDate.Unix()] = lookup } - completed := true // nolint:ifshort,nolintlint // false positive and triggers only on Windows + completed := true allResultsSuccessful := true allResultsFailed := true completionCheck: diff --git a/engine/order_manager_test.go b/engine/order_manager_test.go index 56a55e17..cecf37f5 100644 --- a/engine/order_manager_test.go +++ b/engine/order_manager_test.go @@ -1707,12 +1707,12 @@ func TestGetByDetail(t *testing.T) { byOrig := m.orderStore.getByDetail(od) byID := m.orderStore.getByDetail(id) - if assert.NotNil(t, byOrig, od, "Retrieve by orig pointer should find a record") { + if assert.NotNil(t, byOrig, "Retrieve by orig pointer should find a record") { assert.NotSame(t, byOrig, od, "Retrieve by orig pointer should return a new pointer") assert.Equal(t, od.ClientOrderID, byOrig.ClientOrderID, "Retrieve by orig pointer should contain the correct ClientOrderID") } - if assert.NotNil(t, byID, od, "Retrieve by new pointer should find a record") { + if assert.NotNil(t, byID, "Retrieve by new pointer should find a record") { assert.NotSame(t, byID, id, "Retrieve by new pointer should return a different new pointer than we passed in") assert.NotSame(t, byID, od, "Retrieve by new pointer should return a different new pointer than the original object") assert.Equal(t, od.ClientOrderID, byID.ClientOrderID, "Retrieve by id pointer should contain the correct ClientOrderID") diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 1e8719f9..b3c11af1 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -1253,11 +1253,7 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ return nil, err } - buy := true - if !strings.EqualFold(r.Side, order.Buy.String()) && - !strings.EqualFold(r.Side, order.Bid.String()) { - buy = false - } + buy := strings.EqualFold(r.Side, order.Buy.String()) || strings.EqualFold(r.Side, order.Bid.String()) result, err := o.SimulateOrder(r.Amount, buy) if err != nil { @@ -1309,11 +1305,7 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g return nil, err } - buy := true - if !strings.EqualFold(r.Side, order.Buy.String()) && - !strings.EqualFold(r.Side, order.Bid.String()) { - buy = false - } + buy := strings.EqualFold(r.Side, order.Buy.String()) || strings.EqualFold(r.Side, order.Bid.String()) result, err := o.WhaleBomb(r.PriceTarget, buy) if err != nil { @@ -1799,24 +1791,23 @@ func (s *RPCServer) WithdrawalEventByID(_ context.Context, r *gctrpc.WithdrawalE log.Errorf(log.GRPCSys, "withdrawal event by id UpdatedAt: %s", err) } - if v.RequestDetails.Type == withdraw.Crypto { + switch v.RequestDetails.Type { + case withdraw.Crypto: resp.Event.Request.Crypto = new(gctrpc.CryptoWithdrawalEvent) resp.Event.Request.Crypto = &gctrpc.CryptoWithdrawalEvent{ Address: v.RequestDetails.Crypto.Address, AddressTag: v.RequestDetails.Crypto.AddressTag, Fee: v.RequestDetails.Crypto.FeeAmount, } - } else if v.RequestDetails.Type == withdraw.Fiat { - if v.RequestDetails.Fiat != (withdraw.FiatRequest{}) { - resp.Event.Request.Fiat = new(gctrpc.FiatWithdrawalEvent) - resp.Event.Request.Fiat = &gctrpc.FiatWithdrawalEvent{ - BankName: v.RequestDetails.Fiat.Bank.BankName, - AccountName: v.RequestDetails.Fiat.Bank.AccountName, - AccountNumber: v.RequestDetails.Fiat.Bank.AccountNumber, - Bsb: v.RequestDetails.Fiat.Bank.BSBNumber, - Swift: v.RequestDetails.Fiat.Bank.SWIFTCode, - Iban: v.RequestDetails.Fiat.Bank.IBAN, - } + case withdraw.Fiat: + resp.Event.Request.Fiat = new(gctrpc.FiatWithdrawalEvent) + resp.Event.Request.Fiat = &gctrpc.FiatWithdrawalEvent{ + BankName: v.RequestDetails.Fiat.Bank.BankName, + AccountName: v.RequestDetails.Fiat.Bank.AccountName, + AccountNumber: v.RequestDetails.Fiat.Bank.AccountNumber, + Bsb: v.RequestDetails.Fiat.Bank.BSBNumber, + Swift: v.RequestDetails.Fiat.Bank.SWIFTCode, + Iban: v.RequestDetails.Fiat.Bank.IBAN, } } @@ -2927,7 +2918,7 @@ func (s *RPCServer) UpdateExchangeSupportedPairs(ctx context.Context, r *gctrpc. return nil, err } - base := exch.GetBase() // nolint:ifshort,nolintlint // false positive and triggers only on Windows + base := exch.GetBase() if base == nil { return nil, errExchangeBaseNotFound } @@ -3634,26 +3625,26 @@ func parseMultipleEvents(ret []*withdraw.Response) *gctrpc.WithdrawalEventsByExc log.Errorf(log.Global, "withdrawal parseMultipleEvents UpdatedAt: %s", err) } - if ret[x].RequestDetails.Type == withdraw.Crypto { + switch ret[x].RequestDetails.Type { + case withdraw.Crypto: tempEvent.Request.Crypto = new(gctrpc.CryptoWithdrawalEvent) tempEvent.Request.Crypto = &gctrpc.CryptoWithdrawalEvent{ Address: ret[x].RequestDetails.Crypto.Address, AddressTag: ret[x].RequestDetails.Crypto.AddressTag, Fee: ret[x].RequestDetails.Crypto.FeeAmount, } - } else if ret[x].RequestDetails.Type == withdraw.Fiat { - if ret[x].RequestDetails.Fiat != (withdraw.FiatRequest{}) { - tempEvent.Request.Fiat = new(gctrpc.FiatWithdrawalEvent) - tempEvent.Request.Fiat = &gctrpc.FiatWithdrawalEvent{ - BankName: ret[x].RequestDetails.Fiat.Bank.BankName, - AccountName: ret[x].RequestDetails.Fiat.Bank.AccountName, - AccountNumber: ret[x].RequestDetails.Fiat.Bank.AccountNumber, - Bsb: ret[x].RequestDetails.Fiat.Bank.BSBNumber, - Swift: ret[x].RequestDetails.Fiat.Bank.SWIFTCode, - Iban: ret[x].RequestDetails.Fiat.Bank.IBAN, - } + case withdraw.Fiat: + tempEvent.Request.Fiat = new(gctrpc.FiatWithdrawalEvent) + tempEvent.Request.Fiat = &gctrpc.FiatWithdrawalEvent{ + BankName: ret[x].RequestDetails.Fiat.Bank.BankName, + AccountName: ret[x].RequestDetails.Fiat.Bank.AccountName, + AccountNumber: ret[x].RequestDetails.Fiat.Bank.AccountNumber, + Bsb: ret[x].RequestDetails.Fiat.Bank.BSBNumber, + Swift: ret[x].RequestDetails.Fiat.Bank.SWIFTCode, + Iban: ret[x].RequestDetails.Fiat.Bank.IBAN, } } + v.Event = append(v.Event, tempEvent) } return v @@ -3719,14 +3710,15 @@ func parseSingleEvents(ret *withdraw.Response) *gctrpc.WithdrawalEventsByExchang log.Errorf(log.Global, "withdrawal parseSingleEvents UpdatedAt: %s", err) } - if ret.RequestDetails.Type == withdraw.Crypto { + switch ret.RequestDetails.Type { + case withdraw.Crypto: tempEvent.Request.Crypto = new(gctrpc.CryptoWithdrawalEvent) tempEvent.Request.Crypto = &gctrpc.CryptoWithdrawalEvent{ Address: ret.RequestDetails.Crypto.Address, AddressTag: ret.RequestDetails.Crypto.AddressTag, Fee: ret.RequestDetails.Crypto.FeeAmount, } - } else if ret.RequestDetails.Type == withdraw.Fiat { + case withdraw.Fiat: if ret.RequestDetails.Fiat != (withdraw.FiatRequest{}) { tempEvent.Request.Fiat = new(gctrpc.FiatWithdrawalEvent) tempEvent.Request.Fiat = &gctrpc.FiatWithdrawalEvent{ @@ -5057,7 +5049,7 @@ func (s *RPCServer) GetTechnicalAnalysis(ctx context.Context, r *gctrpc.GetTechn bollinger, err = klines.GetBollingerBands(r.Period, r.StandardDeviationUp, r.StandardDeviationDown, - indicators.MaType(r.MovingAverageType)) //nolint:gosec // TODO: Make var types consistent + indicators.MaType(r.MovingAverageType)) //nolint:gosec,nolintlint // TODO: Make var types consistent, however this doesn't get flagged on Windows if err != nil { return nil, err } diff --git a/engine/withdraw_manager.go b/engine/withdraw_manager.go index 0869b58f..2e7e5003 100644 --- a/engine/withdraw_manager.go +++ b/engine/withdraw_manager.go @@ -69,22 +69,20 @@ func (m *WithdrawManager) SubmitWithdrawal(ctx context.Context, req *withdraw.Re return nil, withdraw.ErrStrExchangeNotSupportedByAddress } } - if req.Type == withdraw.Fiat { + switch req.Type { + case withdraw.Fiat: ret, err = exch.WithdrawFiatFunds(ctx, req) - if err != nil { - resp.Exchange.Status = err.Error() - } else { - resp.Exchange.Status = ret.Status - resp.Exchange.ID = ret.ID - } - } else if req.Type == withdraw.Crypto { + case withdraw.Crypto: ret, err = exch.WithdrawCryptocurrencyFunds(ctx, req) - if err != nil { - resp.Exchange.Status = err.Error() - } else { - resp.Exchange.Status = ret.Status - resp.Exchange.ID = ret.ID - } + default: + return nil, fmt.Errorf("unsupported withdrawal type: %v", req.Type) + } + + if err != nil { + resp.Exchange.Status = err.Error() + } else { + resp.Exchange.Status = ret.Status + resp.Exchange.ID = ret.ID } } dbwithdraw.Event(resp) diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 28b192d9..beff82b9 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -2445,17 +2445,22 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po } var c currency.Code - if collateralMode == collateral.SingleMode { + + switch collateralMode { + case collateral.SingleMode: var collateralAsset *UAsset - if strings.Contains(accountPosition.Symbol, usdtAsset.Asset) { + switch { + case strings.Contains(accountPosition.Symbol, usdtAsset.Asset): collateralAsset = usdtAsset - } else if strings.Contains(accountPosition.Symbol, busdAsset.Asset) { + case strings.Contains(accountPosition.Symbol, busdAsset.Asset): collateralAsset = busdAsset } + collateralTotal = collateralAsset.WalletBalance collateralAvailable = collateralAsset.AvailableBalance unrealisedPNL = collateralAsset.UnrealizedProfit c = currency.NewCode(collateralAsset.Asset) + if marginType == margin.Multi { isolatedMargin = collateralAsset.CrossUnPnl collateralUsed = collateralTotal + isolatedMargin @@ -2463,7 +2468,8 @@ func (b *Binance) GetFuturesPositionSummary(ctx context.Context, req *futures.Po isolatedMargin = accountPosition.IsolatedWallet collateralUsed = isolatedMargin } - } else if collateralMode == collateral.MultiMode { + + case collateral.MultiMode: collateralTotal = ai.TotalWalletBalance collateralUsed = ai.TotalWalletBalance - ai.AvailableBalance collateralAvailable = ai.AvailableBalance diff --git a/exchanges/binanceus/binanceus.go b/exchanges/binanceus/binanceus.go index d92a4543..cdc46dc9 100644 --- a/exchanges/binanceus/binanceus.go +++ b/exchanges/binanceus/binanceus.go @@ -807,13 +807,11 @@ func (bi *Binanceus) GetUsersSpotAssetSnapshot(ctx context.Context, startTime, e params := url.Values{} params.Set("type", "SPOT") params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10)) - if !(startTime.IsZero() && startTime.Unix() <= 0) && startTime.Before(time.Now()) { + if !startTime.IsZero() { params.Set("startTime", strconv.FormatInt(startTime.UnixMilli(), 10)) } - if !(endTime.IsZero() && endTime.Unix() <= 0) && endTime.After(time.Now()) { - if (params.Get("startTime") != "" && endTime.After(startTime)) || params.Get("startTime") == "" { - params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) - } + if !endTime.IsZero() { + params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10)) } if limit > 0 { params.Set("limit", strconv.FormatUint(limit, 10)) @@ -1728,7 +1726,7 @@ func (bi *Binanceus) GetSubAccountDepositHistory(ctx context.Context, email stri func (bi *Binanceus) GetReferralRewardHistory(ctx context.Context, userBusinessType, page, rows int) (*ReferralRewardHistoryResponse, error) { params := url.Values{} switch { - case !(userBusinessType == 0 || userBusinessType == 1): + case userBusinessType != 0 && userBusinessType != 1: return nil, errInvalidUserBusinessType case page == 0: return nil, errMissingPageNumber diff --git a/exchanges/binanceus/binanceus_test.go b/exchanges/binanceus/binanceus_test.go index 0701ab61..12cb7edf 100644 --- a/exchanges/binanceus/binanceus_test.go +++ b/exchanges/binanceus/binanceus_test.go @@ -210,31 +210,34 @@ func TestSubmitOrder(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) + pair := currency.NewPair(currency.BTC, currency.USD) err := bi.CancelOrder(context.Background(), &order.Cancel{ AssetType: asset.Spot, OrderID: "1337", }) - if err != nil && !errors.Is(err, errMissingCurrencySymbol) { - t.Error("Binanceus CancelOrder() error", err) - } + require.ErrorIs(t, err, errMissingCurrencySymbol) + err = bi.CancelOrder(context.Background(), &order.Cancel{ + AssetType: asset.Futures, + OrderID: "69", + Pair: pair, + }) + require.ErrorIs(t, err, asset.ErrNotSupported) err = bi.CancelOrder(context.Background(), &order.Cancel{ AssetType: asset.Spot, - Pair: currency.NewPair(currency.BTC, currency.USDT), + OrderID: "", + Pair: pair, }) - if err != nil && !(errors.Is(err, errEitherOrderIDOrClientOrderIDIsRequired) || strings.Contains(err.Error(), "ID not set")) { - t.Errorf("Binanceus CancelOrder() expecting %v, but found %v", errEitherOrderIDOrClientOrderIDIsRequired, err) - } + require.ErrorIs(t, err, order.ErrOrderIDNotSet) + + sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) cancellationOrder := &order.Cancel{ OrderID: "1", Pair: pair, AssetType: asset.Spot, } err = bi.CancelOrder(context.Background(), cancellationOrder) - if err != nil && !strings.Contains(err.Error(), "Unknown order sent.") { - t.Error("Binanceus CancelOrder() error", err) - } + assert.ErrorContains(t, err, "Unknown order sent.") } func TestCancelAllOrders(t *testing.T) { @@ -701,16 +704,14 @@ func TestGetReferralRewardHistory(t *testing.T) { func TestGetSubaccountTransferHistory(t *testing.T) { t.Parallel() - sharedtestvalues.SkipTestIfCredentialsUnset(t, bi) - _, er := bi.GetSubaccountTransferHistory(context.Background(), "", 0, 0, 0, 0) - if !errors.Is(er, errNotValidEmailAddress) { - t.Errorf("Binanceus GetSubaccountTransferHistory() expected %v, but received: %s", errNotValidEmailAddress, er) - } + + _, err := bi.GetSubaccountTransferHistory(context.Background(), "", 0, 0, 0, 0) + assert.ErrorIs(t, err, errNotValidEmailAddress) + sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, er = bi.GetSubaccountTransferHistory(context.Background(), "example@golang.org", 0, 0, 0, 0) - if er != nil && !(errors.Is(er, errNotValidEmailAddress) || strings.Contains(er.Error(), "Sub-account function is not enabled.")) { - t.Fatalf("Binanceus GetSubaccountTransferHistory() error %v", er) - } + + _, err = bi.GetSubaccountTransferHistory(context.Background(), "example@golang.org", 0, 0, 0, 0) + assert.Error(t, err, "GetSubaccountTransferHistory should return an error on a bogus email") } func TestExecuteSubAccountTransfer(t *testing.T) { @@ -871,18 +872,21 @@ func TestGetAllOpenOrders(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Parallel() + + _, err := bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{}) + assert.ErrorIs(t, err, errMissingCurrencySymbol) + + _, err = bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{ + Symbol: currency.NewBTCUSDT(), + }) + assert.ErrorIs(t, err, errEitherOrderIDOrClientOrderIDIsRequired) + sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders) - _, er := bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{Symbol: currency.NewPair(currency.BTC, currency.USDT)}) - if er != nil && !errors.Is(er, errEitherOrderIDOrClientOrderIDIsRequired) { - t.Errorf("Binanceus CancelExistingOrder() error expecting %v, but found %v", errEitherOrderIDOrClientOrderIDIsRequired, er) - } - _, er = bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{ - Symbol: currency.NewPair(currency.BTC, currency.USDT), + _, err = bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{ + Symbol: currency.NewBTCUSDT(), ClientSuppliedOrderID: "1234", }) - if er != nil && !strings.Contains(er.Error(), "Unknown order sent.") { - t.Error("Binanceus CancelExistingorder() error", er) - } + assert.ErrorContains(t, err, "Unknown order sent.") } func TestCancelOpenOrdersForSymbol(t *testing.T) { diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 577d5e0f..0ad05652 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -1135,10 +1135,11 @@ func (b *Bitfinex) fixCasing(in currency.Pair, a asset.Item) (string, error) { in = in.Lower() var checkString [2]byte - if a == asset.Spot || a == asset.Margin { + switch a { + case asset.Spot, asset.Margin: checkString[0] = 't' checkString[1] = 'T' - } else if a == asset.MarginFunding { + case asset.MarginFunding: checkString[0] = 'f' checkString[1] = 'F' } diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 5add75d0..3b17ef50 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -528,11 +528,13 @@ func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currenc Pair: pair, } - if orders.Data[i].Type == "bid" { + switch orders.Data[i].Type { + case "bid": orderDetail.Side = order.Buy - } else if orders.Data[i].Type == "ask" { + case "ask": orderDetail.Side = order.Sell } + return &orderDetail, nil } return nil, fmt.Errorf("%w %v", order.ErrOrderNotFound, orderID) @@ -661,9 +663,10 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ format.Delimiter), } - if resp.Data[i].Type == "bid" { + switch resp.Data[i].Type { + case "bid": orderDetail.Side = order.Buy - } else if resp.Data[i].Type == "ask" { + case "ask": orderDetail.Side = order.Sell } @@ -716,9 +719,10 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ format.Delimiter), } - if resp.Data[i].Type == "bid" { + switch resp.Data[i].Type { + case "bid": orderDetail.Side = order.Buy - } else if resp.Data[i].Type == "ask" { + case "ask": orderDetail.Side = order.Sell } diff --git a/exchanges/btse/btse_websocket.go b/exchanges/btse/btse_websocket.go index 04c244d0..66624cc2 100644 --- a/exchanges/btse/btse_websocket.go +++ b/exchanges/btse/btse_websocket.go @@ -295,12 +295,12 @@ func (b *BTSE) wsHandleData(respRaw []byte) error { } var price, amount float64 for i := range t.Data.SellQuote { - p := strings.Replace(t.Data.SellQuote[i].Price, ",", "", -1) + p := strings.ReplaceAll(t.Data.SellQuote[i].Price, ",", "") price, err = strconv.ParseFloat(p, 64) if err != nil { return err } - a := strings.Replace(t.Data.SellQuote[i].Size, ",", "", -1) + a := strings.ReplaceAll(t.Data.SellQuote[i].Size, ",", "") amount, err = strconv.ParseFloat(a, 64) if err != nil { return err @@ -314,12 +314,12 @@ func (b *BTSE) wsHandleData(respRaw []byte) error { }) } for j := range t.Data.BuyQuote { - p := strings.Replace(t.Data.BuyQuote[j].Price, ",", "", -1) + p := strings.ReplaceAll(t.Data.BuyQuote[j].Price, ",", "") price, err = strconv.ParseFloat(p, 64) if err != nil { return err } - a := strings.Replace(t.Data.BuyQuote[j].Size, ",", "", -1) + a := strings.ReplaceAll(t.Data.BuyQuote[j].Size, ",", "") amount, err = strconv.ParseFloat(a, 64) if err != nil { return err diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 652a13f6..a49f3866 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -546,12 +546,14 @@ func (b *BTSE) CancelAllOrders(ctx context.Context, orderCancellation *order.Can } func orderIntToType(i int) order.Type { - if i == 77 { + switch i { + case 77: return order.Market - } else if i == 76 { + case 76: return order.Limit + default: + return order.UnknownType } - return order.UnknownType } // GetOrderInfo returns order information based on order ID @@ -764,12 +766,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest Side: side, Price: resp[i].Price, Status: status, - } - - if resp[i].OrderType == 77 { - openOrder.Type = order.Market - } else if resp[i].OrderType == 76 { - openOrder.Type = order.Limit + Type: orderIntToType(resp[i].OrderType), } fills, err := b.TradeHistory(ctx, diff --git a/exchanges/bybit/bybit_wrapper.go b/exchanges/bybit/bybit_wrapper.go index 1e54eff3..0755ad37 100644 --- a/exchanges/bybit/bybit_wrapper.go +++ b/exchanges/bybit/bybit_wrapper.go @@ -1187,7 +1187,7 @@ func (by *Bybit) ConstructOrderDetails(tradeOrders []TradeOrder, assetType asset return nil, err } if (pair.IsEmpty() && len(filterPairs) > 0 && !filterPairs.Contains(ePair, true)) || - !(pair.IsEmpty() || pair.Equal(ePair)) { + (!pair.IsEmpty() && !pair.Equal(ePair)) { continue } orderType, err := order.StringToOrderType(tradeOrders[x].OrderType) diff --git a/exchanges/deribit/deribit.go b/exchanges/deribit/deribit.go index fb5734bd..3a84143a 100644 --- a/exchanges/deribit/deribit.go +++ b/exchanges/deribit/deribit.go @@ -2841,7 +2841,7 @@ func (d *Deribit) optionPairToString(pair currency.Pair) string { initialDelimiter = currency.UnderscoreDelimiter // Replace a capital D with d for decimal place in Strike price // Char 11 is either the hyphen before Strike price or first digit - q = q[:11] + strings.Replace(q[11:], "D", "d", -1) + q = q[:11] + strings.Replace(q[11:], "D", "d", 1) } return pair.Base.String() + initialDelimiter + q } diff --git a/exchanges/deribit/deribit_websocket.go b/exchanges/deribit/deribit_websocket.go index 63e960d1..e0fb3ae4 100644 --- a/exchanges/deribit/deribit_websocket.go +++ b/exchanges/deribit/deribit_websocket.go @@ -684,7 +684,9 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { if len(asks) == 0 && len(bids) == 0 { return nil } - if orderbookData.Type == "snapshot" { + + switch orderbookData.Type { + case "snapshot": return d.Websocket.Orderbook.LoadSnapshot(&orderbook.Base{ Exchange: d.Name, VerifyOrderbook: d.CanVerifyOrderbook, @@ -695,7 +697,7 @@ func (d *Deribit) processOrderbook(respRaw []byte, channels []string) error { Asset: a, LastUpdateID: orderbookData.ChangeID, }) - } else if orderbookData.Type == "change" { + case "change": return d.Websocket.Orderbook.Update(&orderbook.Update{ Asks: asks, Bids: bids, diff --git a/exchanges/deribit/deribit_wrapper.go b/exchanges/deribit/deribit_wrapper.go index 007183fe..988ca210 100644 --- a/exchanges/deribit/deribit_wrapper.go +++ b/exchanges/deribit/deribit_wrapper.go @@ -1301,9 +1301,10 @@ func (d *Deribit) GetFuturesPositionSummary(ctx context.Context, r *futures.Posi } var baseSize float64 - if r.Asset == asset.Futures { + switch r.Asset { + case asset.Futures: baseSize = pos[index].SizeCurrency - } else if r.Asset == asset.Options { + case asset.Options: baseSize = pos[index].Size } contractSize = multiplier * baseSize @@ -1507,10 +1508,7 @@ func (d *Deribit) GetHistoricalFundingRates(ctx context.Context, r *fundingrate. var fundingRates []fundingrate.Rate mfr := make(map[int64]struct{}) - for { - if ed.Equal(r.StartDate) || ed.Before(r.StartDate) { - break - } + for ed.After(r.StartDate) { var records []FundingRateHistory if d.Websocket.IsConnected() { records, err = d.WSRetrieveFundingRateHistory(p, r.StartDate, ed) diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 4be2b4f4..79c775d5 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -769,7 +769,7 @@ func TestFormatExchangeCurrencies(t *testing.T) { assert.Equal(t, "btc~usd^ltc~btc", got) _, err = e.FormatExchangeCurrencies(nil, asset.Spot) - assert.ErrorContains(t, err, "returned empty string", err, "FormatExchangeCurrencies should error correctly") + assert.ErrorContains(t, err, "returned empty string", "FormatExchangeCurrencies should error correctly") } func TestFormatExchangeCurrency(t *testing.T) { diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index ed2ede40..6062497e 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -3667,7 +3667,7 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 { // GetUnderlyingFromCurrencyPair returns an underlying string from a currency pair func (g *Gateio) GetUnderlyingFromCurrencyPair(p currency.Pair) (currency.Pair, error) { - pairString := strings.Replace(p.Upper().String(), currency.DashDelimiter, currency.UnderscoreDelimiter, -1) + pairString := strings.ReplaceAll(p.Upper().String(), currency.DashDelimiter, currency.UnderscoreDelimiter) ccies := strings.Split(pairString, currency.UnderscoreDelimiter) if len(ccies) < 2 { return currency.EMPTYPAIR, fmt.Errorf("invalid currency pair %v", p) diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index 985b6a1f..d385ebe0 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -3386,7 +3386,7 @@ func getPair(tb testing.TB, a asset.Item) currency.Pair { func TestGetClientOrderIDFromText(t *testing.T) { t.Parallel() - assert.Zero(t, getClientOrderIDFromText("api"), "should not return anything") + assert.Empty(t, getClientOrderIDFromText("api"), "should not return anything") assert.Equal(t, "t-123", getClientOrderIDFromText("t-123"), "should return t-123") } diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index 23be575b..5dcbbad1 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -436,7 +436,7 @@ allTrades: Timestamp: tradeTS, }) if i == len(tradeData)-1 { - if ts == tradeTS { + if ts.Equal(tradeTS) { break allTrades } ts = tradeTS @@ -548,12 +548,17 @@ func (g *Gemini) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa if err != nil { return nil, err } + var orderType order.Type - if resp.Type == "exchange limit" { + switch resp.Type { + case "exchange limit": orderType = order.Limit - } else if resp.Type == "market buy" || resp.Type == "market sell" { + case "market buy", "market sell": orderType = order.Market + default: + return nil, fmt.Errorf("unknown order type: %q", resp.Type) } + var side order.Side side, err = order.StringToOrderSide(resp.Side) if err != nil { @@ -657,12 +662,17 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque if err != nil { return nil, err } + var orderType order.Type - if resp[i].Type == "exchange limit" { + switch resp[i].Type { + case "exchange limit": orderType = order.Limit - } else if resp[i].Type == "market buy" || resp[i].Type == "market sell" { + case "market buy", "market sell": orderType = order.Market + default: + return nil, fmt.Errorf("unknown order type: %q", resp[i].Type) } + var side order.Side side, err = order.StringToOrderSide(resp[i].Side) if err != nil { diff --git a/exchanges/kucoin/kucoin_wrapper.go b/exchanges/kucoin/kucoin_wrapper.go index 7d32a8c9..d80fba0f 100644 --- a/exchanges/kucoin/kucoin_wrapper.go +++ b/exchanges/kucoin/kucoin_wrapper.go @@ -1004,9 +1004,10 @@ func (ku *Kucoin) GetOrderInfo(ctx context.Context, orderID string, pair currenc if err != nil { return nil, err } - if side == order.Sell { + switch side { + case order.Sell: side = order.Short - } else if side == order.Buy { + case order.Buy: side = order.Long } if !pair.IsEmpty() && !nPair.Equal(pair) { @@ -1202,7 +1203,7 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if err != nil { return nil, err } - if getOrdersRequest.Validate() != nil { + if err := getOrdersRequest.Validate(); err != nil { return nil, err } format, err := ku.GetPairFormat(getOrdersRequest.AssetType, true) @@ -1242,15 +1243,19 @@ func (ku *Kucoin) GetActiveOrders(ctx context.Context, getOrdersRequest *order.M if !enabled { continue } + side, err := order.StringToOrderSide(futuresOrders.Items[x].Side) if err != nil { return nil, err } - if side == order.Sell { + + switch side { + case order.Sell: side = order.Short - } else if side == order.Buy { + case order.Buy: side = order.Long } + oType, err := order.StringToOrderType(futuresOrders.Items[x].OrderType) if err != nil { return nil, fmt.Errorf("asset type: %v order type: %v err: %w", getOrdersRequest.AssetType, getOrdersRequest.Type, err) @@ -1442,18 +1447,18 @@ func (ku *Kucoin) GetOrderHistory(ctx context.Context, getOrdersRequest *order.M if getOrdersRequest == nil { return nil, common.ErrNilPointer } - err := ku.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType) - if err != nil { - return nil, err - } - if getOrdersRequest.Validate() != nil { - return nil, err - } - var sideString string - sideString, err = ku.OrderSideString(getOrdersRequest.Side) + if err := ku.CurrencyPairs.IsAssetEnabled(getOrdersRequest.AssetType); err != nil { + return nil, err + } + if err := getOrdersRequest.Validate(); err != nil { + return nil, err + } + + sideString, err := ku.OrderSideString(getOrdersRequest.Side) if err != nil { return nil, err } + var orders []order.Detail var orderSide order.Side var orderStatus order.Status diff --git a/exchanges/margin/margin_test.go b/exchanges/margin/margin_test.go index f0401b5f..d64c717e 100644 --- a/exchanges/margin/margin_test.go +++ b/exchanges/margin/margin_test.go @@ -79,7 +79,7 @@ func TestString(t *testing.T) { assert.Equal(t, spotIsolatedStr, SpotIsolated.String()) assert.Equal(t, cashStr, NoMargin.String()) assert.Equal(t, unknownStr, Type(30).String()) - assert.Equal(t, "", Unset.String()) + assert.Empty(t, Unset.String()) } func TestUpper(t *testing.T) { diff --git a/exchanges/okx/okx.go b/exchanges/okx/okx.go index e68c325d..84abe861 100644 --- a/exchanges/okx/okx.go +++ b/exchanges/okx/okx.go @@ -2333,7 +2333,9 @@ func (ok *Okx) GetFixedLoanBorrowQuote(ctx context.Context, borrowingCurrency cu if borrowType == "" { return nil, errBorrowTypeRequired } - if borrowType == "normal" { + + switch borrowType { + case "normal": if borrowingCurrency.IsEmpty() { return nil, currency.ErrCurrencyCodeEmpty } @@ -2346,11 +2348,12 @@ func (ok *Okx) GetFixedLoanBorrowQuote(ctx context.Context, borrowingCurrency cu if term == "" { return nil, errLendingTermIsRequired } - } else if borrowType == "reborrow" { + case "reborrow": if orderID == "" { return nil, order.ErrOrderIDNotSet } } + params := url.Values{} params.Set("type", borrowType) if !borrowingCurrency.IsEmpty() { diff --git a/exchanges/okx/okx_wrapper.go b/exchanges/okx/okx_wrapper.go index aae4084c..e1f2a611 100644 --- a/exchanges/okx/okx_wrapper.go +++ b/exchanges/okx/okx_wrapper.go @@ -1751,7 +1751,7 @@ allOrders: for i := range orderList { if req.StartTime.Equal(orderList[i].CreationTime.Time()) || orderList[i].CreationTime.Time().Before(req.StartTime) || - endTime == orderList[i].CreationTime.Time() { + endTime.Equal(orderList[i].CreationTime.Time()) { // reached end of orders to crawl break allOrders } @@ -1899,7 +1899,7 @@ allOrders: for i := range orderList { if req.StartTime.Equal(orderList[i].CreationTime.Time()) || orderList[i].CreationTime.Time().Before(req.StartTime) || - endTime == orderList[i].CreationTime.Time() { + endTime.Equal(orderList[i].CreationTime.Time()) { // reached end of orders to crawl break allOrders } @@ -2224,10 +2224,7 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His } // map of time indexes, allowing for easy lookup of slice index from unix time data mti := make(map[int64]int) - for { - if sd.Equal(r.EndDate) || sd.After(r.EndDate) { - break - } + for sd.Before(r.EndDate) { var frh []FundingRateResponse frh, err = ok.GetFundingRateHistory(ctx, fPair.String(), sd, r.EndDate, int64(requestLimit)) if err != nil { @@ -2279,10 +2276,7 @@ func (ok *Okx) GetHistoricalFundingRates(ctx context.Context, r *fundingrate.His if time.Since(r.StartDate) < kline.OneWeek.Duration() { billDetailsFunc = ok.GetBillsDetailLast7Days } - for { - if sd.Equal(r.EndDate) || sd.After(r.EndDate) { - break - } + for sd.Before(r.EndDate) { var fri time.Duration if len(ok.Features.Supports.FuturesCapabilities.SupportedFundingRateFrequencies) == 1 { // can infer funding rate interval from the only funding rate frequency defined diff --git a/exchanges/order/orders.go b/exchanges/order/orders.go index 905e19b2..9470d0f8 100644 --- a/exchanges/order/orders.go +++ b/exchanges/order/orders.go @@ -1251,7 +1251,7 @@ func (o *ClassificationError) Error() string { func (c *Cancel) StandardCancel() validate.Checker { return validate.Check(func() error { if c.OrderID == "" { - return errors.New("ID not set") + return ErrOrderIDNotSet } return nil }) diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 03fe1fe0..f1ebd0f6 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -345,9 +345,7 @@ func TestGetOrderTrades(t *testing.T) { case !sharedtestvalues.AreAPICredentialsSet(p) && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") case mockTests && err != nil: - if !(tt.errExpected && strings.Contains(err.Error(), tt.errMsgExpected)) { - t.Errorf("Could not mock get order trades: %s", err) - } + assert.ErrorContains(t, err, tt.errMsgExpected) } }) } diff --git a/exchanges/stream/websocket_test.go b/exchanges/stream/websocket_test.go index e37ef020..5b512e28 100644 --- a/exchanges/stream/websocket_test.go +++ b/exchanges/stream/websocket_test.go @@ -1401,7 +1401,7 @@ func TestRemoveURLQueryString(t *testing.T) { t.Parallel() assert.Equal(t, "https://www.google.com", removeURLQueryString("https://www.google.com?test=1"), "removeURLQueryString should remove query string") assert.Equal(t, "https://www.google.com", removeURLQueryString("https://www.google.com"), "removeURLQueryString should not change URL") - assert.Equal(t, "", removeURLQueryString(""), "removeURLQueryString should be equal") + assert.Empty(t, removeURLQueryString(""), "removeURLQueryString should be empty") } func TestWriteToConn(t *testing.T) { diff --git a/exchanges/subscription/store_test.go b/exchanges/subscription/store_test.go index 9d05e02d..94233bca 100644 --- a/exchanges/subscription/store_test.go +++ b/exchanges/subscription/store_test.go @@ -63,7 +63,7 @@ func TestAdd(t *testing.T) { require.NoError(t, s.Add(sub), "Should not error on a standard add") assert.NotNil(t, s.get(sub), "Should have stored the sub") assert.ErrorIs(t, s.Add(sub), ErrDuplicate, "Should error on duplicates") - assert.NotNil(t, sub.Key, sub, "Add should call EnsureKeyed") + assert.NotNil(t, sub.Key, "Add should call EnsureKeyed") } // TestGet exercises Get and get methods diff --git a/gctscript/vm/vm_test.go b/gctscript/vm/vm_test.go index 68d6f920..3467f5ba 100644 --- a/gctscript/vm/vm_test.go +++ b/gctscript/vm/vm_test.go @@ -268,7 +268,7 @@ func TestVMWithRunnerOnce(t *testing.T) { config: configHelper(true, true, maxTestVirtualMachines), started: 1, } - vmCount := VMSCount.Len() // nolint:ifshort,nolintlint // false positive and triggers only on Windows + vmCount := VMSCount.Len() VM := manager.New() if VM == nil { t.Fatal("Failed to allocate new VM exiting")