modernise: Run new gopls modernise tool against the codebase and fix minor issues (#1826)

* modernise: Run new gopls modernise tool against codebase

* Address shazbert's nits

* apichecker, gctcli: Simplify HTML scraping functions and improve depth limit handling

* refactor: Create minSyncInterval const and update order book limit handling for binance and binanceUS

* refactor: Various slice usage improvements and rename TODO

* tranches: Revert deleteByID changes due to performance decrease

Shazbert was a F1 driver in a past lifetime 🏎️

* tranches: Simply retrieve copy

Thanks to shazbert

* documentation: Sort contributors list by contributions

* tranches: Remove deadcode in deleteByID
This commit is contained in:
Adrian Gallagher
2025-03-21 09:17:10 +11:00
committed by GitHub
parent d857d704e3
commit 4651af5767
223 changed files with 1504 additions and 1752 deletions

View File

@@ -39,6 +39,7 @@ gam-phon | https://github.com/gam-phon
if1live | https://github.com/if1live
lozdog245 | https://github.com/lozdog245
MarkDzulko | https://github.com/MarkDzulko
soxipy | https://github.com/soxipy
blombard | https://github.com/blombard
cavapoo2 | https://github.com/cavapoo2
CodeLingoTeam | https://github.com/CodeLingoTeam
@@ -54,6 +55,5 @@ m1kola | https://github.com/m1kola
mattkanwisher | https://github.com/mattkanwisher
merkeld | https://github.com/merkeld
mKurrels | https://github.com/mKurrels
soxipy | https://github.com/soxipy
starit | https://github.com/starit
zeldrinn | https://github.com/zeldrinn

View File

@@ -160,11 +160,11 @@ Binaries will be published once the codebase reaches a stable condition.
| [shazbert](https://github.com/shazbert) | 362 |
| [dependabot[bot]](https://github.com/apps/dependabot) | 361 |
| [gloriousCode](https://github.com/gloriousCode) | 237 |
| [gbjk](https://github.com/gbjk) | 119 |
| [gbjk](https://github.com/gbjk) | 121 |
| [dependabot-preview[bot]](https://github.com/apps/dependabot-preview) | 88 |
| [xtda](https://github.com/xtda) | 47 |
| [lrascao](https://github.com/lrascao) | 27 |
| [Beadko](https://github.com/Beadko) | 21 |
| [Beadko](https://github.com/Beadko) | 22 |
| [Rots](https://github.com/Rots) | 15 |
| [vazha](https://github.com/vazha) | 15 |
| [ydm](https://github.com/ydm) | 15 |
@@ -195,6 +195,7 @@ Binaries will be published once the codebase reaches a stable condition.
| [if1live](https://github.com/if1live) | 2 |
| [lozdog245](https://github.com/lozdog245) | 2 |
| [MarkDzulko](https://github.com/MarkDzulko) | 2 |
| [soxipy](https://github.com/soxipy) | 2 |
| [blombard](https://github.com/blombard) | 1 |
| [cavapoo2](https://github.com/cavapoo2) | 1 |
| [CodeLingoTeam](https://github.com/CodeLingoTeam) | 1 |
@@ -210,6 +211,5 @@ Binaries will be published once the codebase reaches a stable condition.
| [mattkanwisher](https://github.com/mattkanwisher) | 1 |
| [merkeld](https://github.com/merkeld) | 1 |
| [mKurrels](https://github.com/mKurrels) | 1 |
| [soxipy](https://github.com/soxipy) | 2 |
| [starit](https://github.com/starit) | 1 |
| [zeldrinn](https://github.com/zeldrinn) | 1 |

View File

@@ -36,7 +36,7 @@ var (
const defaultTimeout = time.Second * 30
func jsonOutput(in interface{}) {
func jsonOutput(in any) {
j, err := json.MarshalIndent(in, "", " ")
if err != nil {
return

View File

@@ -52,7 +52,7 @@ type Event interface {
GetReasons() []string
GetClosePrice() decimal.Decimal
AppendReason(string)
AppendReasonf(string, ...interface{})
AppendReasonf(string, ...any)
}
// custom subloggers for backtester use

View File

@@ -362,7 +362,7 @@ func TestPrintSettings(t *testing.T) {
Goal: "To demonstrate rendering of settings",
StrategySettings: StrategySettings{
Name: dca,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"dca-dummy1": 30.0,
"dca-dummy2": 30.0,
"dca-dummy3": 30.0,
@@ -963,7 +963,7 @@ func TestGenerateConfigForRSIAPICustomSettings(t *testing.T) {
Goal: "To demonstrate the RSI strategy using API candle data and custom settings",
StrategySettings: StrategySettings{
Name: "rsi",
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"rsi-low": 30.0,
"rsi-high": 70.0,
"rsi-period": 14,
@@ -1206,7 +1206,7 @@ func TestGenerateConfigForTop2Bottom2(t *testing.T) {
Name: top2bottom2.Name,
SimultaneousSignalProcessing: true,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"mfi-low": 32,
"mfi-high": 68,
"mfi-period": 14,

View File

@@ -67,8 +67,8 @@ type StrategySettings struct {
// If true, won't track USD values against currency pair
// bool language is opposite to encourage use by default
DisableUSDTracking bool `json:"disable-usd-tracking"`
CustomSettings map[string]interface{} `json:"custom-settings,omitempty"`
DisableUSDTracking bool `json:"disable-usd-tracking"`
CustomSettings map[string]any `json:"custom-settings,omitempty"`
}
// ExchangeLevelFunding allows the portfolio manager to access

View File

@@ -554,8 +554,8 @@ func parseStratName(name string, strategiesToUse []string) (string, error) {
return "", errors.New("unrecognised strategy")
}
func customSettingsLoop(reader *bufio.Reader) map[string]interface{} {
resp := make(map[string]interface{})
func customSettingsLoop(reader *bufio.Reader) map[string]any {
resp := make(map[string]any)
customSettingField := "loopTime!"
for customSettingField != "" {
fmt.Println("Enter a custom setting name. Enter nothing to stop")

View File

@@ -808,7 +808,7 @@ func (f fakeEvent) GetUnderlyingPair() currency.Pair {
return f.Pair()
}
func (f fakeEvent) AppendReasonf(string, ...interface{}) {}
func (f fakeEvent) AppendReasonf(string, ...any) {}
func (f fakeEvent) GetBase() *event.Base {
return &event.Base{}

View File

@@ -92,7 +92,7 @@ func TestSetupFromConfig(t *testing.T) {
cfg.StrategySettings = config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"hello": "moto",
},
}
@@ -166,7 +166,7 @@ func TestLoadDataAPI(t *testing.T) {
},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"hello": "moto",
},
},
@@ -222,7 +222,7 @@ func TestLoadDataCSV(t *testing.T) {
},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"hello": "moto",
},
},
@@ -289,7 +289,7 @@ func TestLoadDataDatabase(t *testing.T) {
},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"hello": "moto",
},
},
@@ -367,7 +367,7 @@ func TestLoadDataLive(t *testing.T) {
},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
CustomSettings: map[string]any{
"hello": "moto",
},
},

View File

@@ -307,7 +307,7 @@ func (f fakeStrat) SupportsSimultaneousProcessing() bool {
func (f fakeStrat) SetSimultaneousProcessing(bool) {}
func (f fakeStrat) SetCustomSettings(map[string]interface{}) error {
func (f fakeStrat) SetCustomSettings(map[string]any) error {
return nil
}

View File

@@ -358,7 +358,7 @@ func (s *GRPCServer) ExecuteStrategyFromConfig(_ context.Context, request *btrpc
}
}
customSettings := make(map[string]interface{}, len(request.Config.StrategySettings.CustomSettings))
customSettings := make(map[string]any, len(request.Config.StrategySettings.CustomSettings))
for i := range request.Config.StrategySettings.CustomSettings {
customSettings[request.Config.StrategySettings.CustomSettings[i].KeyField] = request.Config.StrategySettings.CustomSettings[i].KeyValue
}

View File

@@ -3,6 +3,7 @@ package engine
import (
"errors"
"fmt"
"slices"
"github.com/gofrs/uuid"
gctcommon "github.com/thrasher-corp/gocryptotrader/common"
@@ -185,7 +186,7 @@ func (r *TaskManager) ClearTask(id uuid.UUID) error {
if r.tasks[i].IsRunning() {
return fmt.Errorf("%w %v, currently running. Stop it first", errCannotClear, r.tasks[i].MetaData.ID)
}
r.tasks = append(r.tasks[:i], r.tasks[i+1:]...)
r.tasks = slices.Delete(r.tasks, i, i+1)
return nil
}
return fmt.Errorf("%s %w", id, errTaskNotFound)
@@ -208,7 +209,7 @@ func (r *TaskManager) ClearAllTasks() (clearedRuns, remainingRuns []*TaskSummary
remainingRuns = append(remainingRuns, run)
} else {
clearedRuns = append(clearedRuns, run)
r.tasks = append(r.tasks[:i], r.tasks[i+1:]...)
r.tasks = slices.Delete(r.tasks, i, i+1)
i--
}
}

View File

@@ -173,7 +173,7 @@ type CurrencyPairStatistic struct {
Events []DataAtOffset `json:"-"`
MaxDrawdown Swing `json:"max-drawdown,omitempty"`
MaxDrawdown Swing `json:"max-drawdown"`
HighestCommittedFunds ValueAtTime `json:"highest-committed-funds"`
GeometricRatios *Ratios `json:"geometric-ratios"`
ArithmeticRatios *Ratios `json:"arithmetic-ratios"`

View File

@@ -278,7 +278,7 @@ func sortSignals(d []data.Handler) ([]cashCarrySignals, error) {
}
// SetCustomSettings can override default settings
func (s *Strategy) SetCustomSettings(customSettings map[string]interface{}) error {
func (s *Strategy) SetCustomSettings(customSettings map[string]any) error {
for k, v := range customSettings {
switch k {
case openShortDistancePercentageString:

View File

@@ -58,7 +58,7 @@ func TestSetCustomSettings(t *testing.T) {
t.Errorf("received: %v, expected: %v", err, nil)
}
float14 := float64(14)
mappalopalous := make(map[string]interface{})
mappalopalous := make(map[string]any)
mappalopalous[openShortDistancePercentageString] = float14
mappalopalous[closeShortDistancePercentageString] = float14

View File

@@ -87,7 +87,7 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, _ funding.IFundingTra
}
// SetCustomSettings not required for DCA
func (s *Strategy) SetCustomSettings(_ map[string]interface{}) error {
func (s *Strategy) SetCustomSettings(_ map[string]any) error {
return base.ErrCustomSettingsUnsupported
}

View File

@@ -135,7 +135,7 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, _ funding.IFundingTra
}
// SetCustomSettings allows a user to modify the RSI limits in their config
func (s *Strategy) SetCustomSettings(customSettings map[string]interface{}) error {
func (s *Strategy) SetCustomSettings(customSettings map[string]any) error {
for k, v := range customSettings {
switch k {
case rsiHighKey:

View File

@@ -44,7 +44,7 @@ func TestSetCustomSettings(t *testing.T) {
t.Errorf("received: %v, expected: %v", err, nil)
}
float14 := float64(14)
mappalopalous := make(map[string]interface{})
mappalopalous := make(map[string]any)
mappalopalous[rsiPeriodKey] = float14
mappalopalous[rsiLowKey] = float14
mappalopalous[rsiHighKey] = float14

View File

@@ -137,7 +137,7 @@ func (s *customStrategy) createSignal(_ data.Handler) (*signal.Signal, error) {
return nil, nil
}
func (s *customStrategy) SetCustomSettings(map[string]interface{}) error {
func (s *customStrategy) SetCustomSettings(map[string]any) error {
return nil
}

View File

@@ -25,7 +25,7 @@ type Handler interface {
UsingSimultaneousProcessing() bool
SupportsSimultaneousProcessing() bool
SetSimultaneousProcessing(bool)
SetCustomSettings(map[string]interface{}) error
SetCustomSettings(map[string]any) error
SetDefaults()
CloseAllPositions([]holdings.Holding, []data.Event) ([]signal.Event, error)
}

View File

@@ -211,7 +211,7 @@ func (s *Strategy) selectTopAndBottomPerformers(mfiFundEvents []mfiFundEvent, re
}
// SetCustomSettings allows a user to modify the MFI limits in their config
func (s *Strategy) SetCustomSettings(customSettings map[string]interface{}) error {
func (s *Strategy) SetCustomSettings(customSettings map[string]any) error {
for k, v := range customSettings {
switch k {
case mfiHighKey:

View File

@@ -51,7 +51,7 @@ func TestSetCustomSettings(t *testing.T) {
t.Errorf("received: %v, expected: %v", err, nil)
}
float14 := float64(14)
mappalopalous := make(map[string]interface{})
mappalopalous := make(map[string]any)
mappalopalous[mfiPeriodKey] = float14
mappalopalous[mfiLowKey] = float14
mappalopalous[mfiHighKey] = float14

View File

@@ -62,7 +62,7 @@ func (b *Base) AppendReason(y string) {
// AppendReasonf adds reasoning for a decision being made
// but with formatting
func (b *Base) AppendReasonf(y string, addons ...interface{}) {
func (b *Base) AppendReasonf(y string, addons ...any) {
y = fmt.Sprintf(y, addons...)
b.Reasons = append(b.Reasons, y)
}

View File

@@ -1016,22 +1016,22 @@ var leet = decimal.NewFromInt(1337)
// caring about the response, or dealing with import cycles
type fakeEvent struct{}
func (f *fakeEvent) GetHighPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetLowPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetOpenPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetVolume() decimal.Decimal { return leet }
func (f *fakeEvent) GetOffset() int64 { return 0 }
func (f *fakeEvent) SetOffset(int64) {}
func (f *fakeEvent) IsEvent() bool { return true }
func (f *fakeEvent) GetTime() time.Time { return time.Now() }
func (f *fakeEvent) Pair() currency.Pair { return pair }
func (f *fakeEvent) GetExchange() string { return exchName }
func (f *fakeEvent) GetInterval() gctkline.Interval { return gctkline.OneMin }
func (f *fakeEvent) GetAssetType() asset.Item { return asset.Spot }
func (f *fakeEvent) AppendReason(string) {}
func (f *fakeEvent) GetClosePrice() decimal.Decimal { return elite }
func (f *fakeEvent) AppendReasonf(_ string, _ ...interface{}) {}
func (f *fakeEvent) GetBase() *event.Base { return &event.Base{} }
func (f *fakeEvent) GetUnderlyingPair() currency.Pair { return pair }
func (f *fakeEvent) GetConcatReasons() string { return "" }
func (f *fakeEvent) GetReasons() []string { return nil }
func (f *fakeEvent) GetHighPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetLowPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetOpenPrice() decimal.Decimal { return leet }
func (f *fakeEvent) GetVolume() decimal.Decimal { return leet }
func (f *fakeEvent) GetOffset() int64 { return 0 }
func (f *fakeEvent) SetOffset(int64) {}
func (f *fakeEvent) IsEvent() bool { return true }
func (f *fakeEvent) GetTime() time.Time { return time.Now() }
func (f *fakeEvent) Pair() currency.Pair { return pair }
func (f *fakeEvent) GetExchange() string { return exchName }
func (f *fakeEvent) GetInterval() gctkline.Interval { return gctkline.OneMin }
func (f *fakeEvent) GetAssetType() asset.Item { return asset.Spot }
func (f *fakeEvent) AppendReason(string) {}
func (f *fakeEvent) GetClosePrice() decimal.Decimal { return elite }
func (f *fakeEvent) AppendReasonf(_ string, _ ...any) {}
func (f *fakeEvent) GetBase() *event.Base { return &event.Base{} }
func (f *fakeEvent) GetUnderlyingPair() currency.Pair { return pair }
func (f *fakeEvent) GetConcatReasons() string { return "" }
func (f *fakeEvent) GetReasons() []string { return nil }

View File

@@ -3,6 +3,7 @@ package trackingcurrencies
import (
"errors"
"fmt"
"slices"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/engine"
@@ -101,12 +102,9 @@ func CreateUSDTrackingPairs(tp []TrackingPair, em *engine.ExchangeManager) ([]Tr
// CurrencyIsUSDTracked checks if the currency passed in
// tracks against USD value, ie is in rankedUSDs
func CurrencyIsUSDTracked(code currency.Code) bool {
for i := range rankedUSDs {
if code.Equal(rankedUSDs[i]) {
return true
}
}
return false
return slices.ContainsFunc(rankedUSDs, func(c currency.Code) bool {
return c.Equal(code)
})
}
// pairContainsUSD is a simple check to ensure that the currency pair

View File

@@ -81,7 +81,7 @@ func (s *CustomStrategy) createSignal(d data.Handler) (*signal.Signal, error) {
}
// SetCustomSettings can override default settings
func (s *CustomStrategy) SetCustomSettings(map[string]interface{}) error {
func (s *CustomStrategy) SetCustomSettings(map[string]any) error {
return base.ErrCustomSettingsUnsupported
}

View File

@@ -59,7 +59,7 @@ func (s *CustomStrategy) createSignal(_ data.Handler) (*signal.Signal, error) {
return nil, nil
}
func (s *CustomStrategy) SetCustomSettings(map[string]interface{}) error {
func (s *CustomStrategy) SetCustomSettings(map[string]any) error {
return nil
}

View File

@@ -10,6 +10,7 @@ import (
"net/url"
"os"
"regexp"
"slices"
"strconv"
"strings"
"sync"
@@ -301,19 +302,16 @@ func checkExistingExchanges(exchName string) bool {
// checkMissingExchanges checks if any supported exchanges are missing api checker functionality
func checkMissingExchanges() []string {
tempArray := make([]string, len(usageData.Exchanges))
for x := range usageData.Exchanges {
tempArray[x] = usageData.Exchanges[x].Name
exchanges := make([]string, len(usageData.Exchanges))
for i, exch := range usageData.Exchanges {
exchanges[i] = exch.Name
}
supportedExchs := exchange.Exchanges
for z := 0; z < len(supportedExchs); {
if common.StringSliceContainsInsensitive(tempArray, supportedExchs[z]) {
supportedExchs = append(supportedExchs[:z], supportedExchs[z+1:]...)
continue
}
z++
}
return supportedExchs
supportedExchs := slices.Clone(exchange.Exchanges)
return slices.DeleteFunc(supportedExchs, func(exchName string) bool {
return common.StringSliceContainsInsensitive(exchanges, exchName)
})
}
// readFileData reads the file data from the given json file
@@ -461,8 +459,6 @@ func checkChangeLog(htmlData *HTMLScrapingData) (string, error) {
dataStrings, err = htmlScrapeBitfinex(htmlData)
case pathBitmex:
dataStrings, err = htmlScrapeBitmex(htmlData)
case pathANX:
dataStrings, err = htmlScrapeANX(htmlData)
case pathPoloniex:
dataStrings, err = htmlScrapePoloniex(htmlData)
case pathBTCMarkets:
@@ -513,7 +509,7 @@ func checkChangeLog(htmlData *HTMLScrapingData) (string, error) {
}
// addExch appends exchange data to updates.json for future api checks
func addExch(exchName, checkType string, data interface{}, isUpdate bool) error {
func addExch(exchName, checkType string, data any, isUpdate bool) error {
var file []byte
if !isUpdate {
if checkExistingExchanges(exchName) {
@@ -554,7 +550,7 @@ func addExch(exchName, checkType string, data interface{}, isUpdate bool) error
}
// fillData fills exchange data based on the given checkType
func fillData(exchName, checkType string, data interface{}) (ExchangeInfo, error) {
func fillData(exchName, checkType string, data any) (ExchangeInfo, error) {
switch checkType {
case github:
tempData, ok := data.(GithubData)
@@ -743,27 +739,13 @@ func htmlScrapeHitBTC(htmlData *HTMLScrapingData) ([]string, error) {
if err != nil {
return nil, err
}
aBody := string(a)
r, err := regexp.Compile(htmlData.RegExp)
if err != nil {
return nil, err
}
str := r.FindAllString(aBody, -1)
var resp []string
for x := range str {
tempStr := strings.Replace(str[x], "section-v-", "", 1)
var repeat bool
for y := range resp {
if tempStr == resp[y] {
repeat = true
break
}
}
if !repeat {
resp = append(resp, tempStr)
}
}
return resp, nil
return r.FindAllString(string(a), -1), nil
}
// htmlScrapeBTCMarkets gets the check string for BTCMarkets exchange
@@ -844,41 +826,6 @@ loop:
return resp, nil
}
// htmlScrapeANX gets the check string for BTCMarkets exchange
func htmlScrapeANX(htmlData *HTMLScrapingData) ([]string, error) {
temp, err := sendHTTPGetRequest(htmlData.Path, nil)
if err != nil {
return nil, err
}
defer temp.Body.Close()
a, err := io.ReadAll(temp.Body)
if err != nil {
return nil, err
}
aBody := string(a)
r, err := regexp.Compile(htmlData.RegExp)
if err != nil {
return nil, err
}
str := r.FindAllString(aBody, -1)
var resp []string
for x := range str {
tempStr := strings.Replace(str[x], "section-v-", "", 1)
var repeat bool
for y := range resp {
if tempStr == resp[y] {
repeat = true
break
}
}
if !repeat {
resp = append(resp, tempStr)
}
}
return resp, nil
}
// htmlScrapeExmo gets the check string for Exmo Exchange
func htmlScrapeExmo(htmlData *HTMLScrapingData) ([]string, error) {
header := map[string]string{
@@ -1098,7 +1045,7 @@ func trelloCreateNewCheck(newCheckName string) error {
if err != nil {
return err
}
var resp interface{}
var resp any
params := url.Values{}
params.Set("name", newName)
return sendAuthReq(http.MethodPost,
@@ -1180,7 +1127,7 @@ func nameStateChanges(currentName, currentState string) (string, error) {
// trelloUpdateCheckItem updates a check item for trello
func trelloUpdateCheckItem(checkItemID, name, state string) error {
var resp interface{}
var resp any
params := url.Values{}
newName, err := nameStateChanges(name, state)
if err != nil {
@@ -1217,7 +1164,7 @@ func updateFile(name string) error {
}
// SendGetReq sends get req
func sendGetReq(path string, result interface{}) error {
func sendGetReq(path string, result any) error {
var requester *request.Requester
var err error
if strings.Contains(path, "github") {
@@ -1244,7 +1191,7 @@ func sendGetReq(path string, result interface{}) error {
}
// sendAuthReq sends auth req
func sendAuthReq(method, path string, result interface{}) error {
func sendAuthReq(method, path string, result any) error {
requester, err := request.New("Apichecker",
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(time.Second*10, 100, 1)))
@@ -1292,7 +1239,7 @@ func trelloCreateNewList() error {
if trelloBoardID == "" {
return errors.New("trelloBoardID not set, cannot create a new list")
}
var resp interface{}
var resp any
listName := createList
if configData.CreateListName != "" {
listName = configData.CreateListName
@@ -1327,7 +1274,7 @@ func trelloDeleteCheckItem(checkitemID string) error {
if checkitemID == "" {
return errors.New("checkitemID cannot be empty")
}
var resp interface{}
var resp any
return sendAuthReq(http.MethodDelete,
fmt.Sprintf(pathDeleteCheckitems, trelloChecklistID, checkitemID, apiKey, apiToken),
&resp)
@@ -1344,7 +1291,7 @@ func trelloCreateNewCard() error {
if trelloListID == "" {
return errors.New("trelloListID not set, cannot create a new checklist")
}
var resp interface{}
var resp any
cardName := createCard
if configData.CreateCardName != "" {
cardName = configData.CreateCardName
@@ -1385,7 +1332,7 @@ func trelloCreateNewChecklist() error {
if !areAPIKeysSet() || (trelloCardID == "") {
return errors.New("apikeys or trelloCardID not set, cannot create a new checklist")
}
var resp interface{}
var resp any
checklistName := createChecklist
if configData.CreateChecklistName != "" {
checklistName = configData.CreateChecklistName
@@ -1540,22 +1487,14 @@ func htmlScrapeBitfinex(htmlData *HTMLScrapingData) ([]string, error) {
if err != nil {
return nil, err
}
str := r.FindAllString(string(a), -1)
var resp []string
for x := range str {
tempStr := strings.Replace(str[x], "section-v-", "", 1)
var repeat bool
for y := range resp {
if tempStr == resp[y] {
repeat = true
break
}
}
if !repeat {
resp = append(resp, tempStr)
}
matches := r.FindAllString(string(a), -1)
results := make([]string, 0, len(matches))
for _, match := range matches {
s := strings.Replace(match, "section-v-", "", 1)
results = append(results, s)
}
return resp, nil
slices.Sort(results)
return slices.Clip(slices.Compact(results)), nil
}
// htmlScrapeBinance gets checkstring for binance exchange

View File

@@ -5,6 +5,7 @@ import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
gctfile "github.com/thrasher-corp/gocryptotrader/common/file"
"github.com/thrasher-corp/gocryptotrader/encoding/json"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
@@ -221,15 +222,10 @@ func TestHTMLScrapeCoinbasepro(t *testing.T) {
func TestHTMLScrapeBitfinex(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{
DateFormat: "2006-01-02",
RegExp: `section-v-(2\d{3}-\d{1,2}-\d{1,2})`,
Path: "https://docs.bitfinex.com/docs/changelog",
}
_, err := htmlScrapeBitfinex(&data)
if err != nil {
t.Error(err)
}
data := HTMLScrapingData{DateFormat: "2006-01-02", RegExp: `section-v-(2\d{3}-\d{1,2}-\d{1,2})`, Path: "https://docs.bitfinex.com/docs/changelog"}
r, err := htmlScrapeBitfinex(&data)
require.NoError(t, err, "htmlScrapeBitfinex must not error")
require.NotEmpty(t, r, "htmlScrapeBitfinex must return a non empty result")
}
func TestHTMLScrapeBitmex(t *testing.T) {
@@ -251,13 +247,10 @@ func TestHTMLScrapeBitmex(t *testing.T) {
func TestHTMLScrapeHitBTC(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{
RegExp: `newest version \d{1}.\d{1}`,
Path: "https://api.hitbtc.com/",
}
if _, err := htmlScrapeHitBTC(&data); err != nil {
t.Error(err)
}
data := HTMLScrapingData{RegExp: `newest version \d{1}.\d{1}`, Path: "https://api.hitbtc.com/"}
r, err := htmlScrapeHitBTC(&data)
require.NoError(t, err, "htmlScrapeHitBTC must not error")
require.NotEmpty(t, r, "htmlScrapeHitBTC must return a non empty result")
}
func TestHTMLScrapeBTSE(t *testing.T) {
@@ -296,17 +289,6 @@ func TestHTMLScrapeBitflyer(t *testing.T) {
}
}
func TestHTMLScrapeANX(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{
RegExp: `ANX Exchange API v\d{1}`,
Path: "https://anxv3.docs.apiary.io/#reference/quickstart-catalog",
}
if _, err := htmlScrapeANX(&data); err != nil {
t.Error(err)
}
}
func TestHTMLPoloniex(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{

View File

@@ -9,6 +9,8 @@ import (
"net/http"
"os"
"path/filepath"
"slices"
"sort"
"strings"
"text/template"
"time"
@@ -313,6 +315,10 @@ func main() {
},
}...)
sort.Slice(contributors, func(i, j int) bool {
return contributors[i].Contributions > contributors[j].Contributions
})
if verbose {
fmt.Println("Contributor List Fetched")
for i := range contributors {
@@ -391,16 +397,6 @@ func GetConfiguration() (Config, error) {
return c, nil
}
// IsExcluded returns if the file path is included in the exclusion list
func IsExcluded(path string, exclusion []string) bool {
for i := range exclusion {
if path == exclusion[i] {
return true
}
}
return false
}
// GetProjectDirectoryTree uses filepath walk functions to get each individual
// directory name and path to match templates with
func GetProjectDirectoryTree(c *Config) ([]string, error) {
@@ -423,7 +419,7 @@ func GetProjectDirectoryTree(c *Config) ([]string, error) {
}
if info.IsDir() {
// Bypass what is contained in config.json directory exclusion
if IsExcluded(info.Name(), c.Exclusions.Directories) {
if slices.Contains(c.Exclusions.Directories, info.Name()) {
if verbose {
fmt.Println("Excluding Directory:", info.Name())
}
@@ -559,7 +555,7 @@ func UpdateDocumentation(details DocumentationDetails) {
name = strings.Join(temp, " ")
}
if IsExcluded(name, details.Config.Exclusions.Files) {
if slices.Contains(details.Config.Exclusions.Files, name) {
if verbose {
fmt.Println("Excluding file:", name)
}

View File

@@ -357,10 +357,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{p, assetTypes[i]}),
Function: "UpdateTicker",
Error: msg,
Response: jsonifyInterface([]interface{}{updateTickerResponse}),
Response: jsonifyInterface([]any{updateTickerResponse}),
})
var GetCachedTickerResponse *ticker.Price
@@ -371,10 +371,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{p, assetTypes[i]}),
Function: "GetCachedTicker",
Error: msg,
Response: jsonifyInterface([]interface{}{GetCachedTickerResponse}),
Response: jsonifyInterface([]any{GetCachedTickerResponse}),
})
var updateOrderbookResponse *orderbook.Base
@@ -385,10 +385,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{p, assetTypes[i]}),
Function: "UpdateOrderbook",
Error: msg,
Response: jsonifyInterface([]interface{}{updateOrderbookResponse}),
Response: jsonifyInterface([]any{updateOrderbookResponse}),
})
var GetCachedOrderbookResponse *orderbook.Base
@@ -399,10 +399,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{p, assetTypes[i]}),
Function: "GetCachedOrderbook",
Error: msg,
Response: jsonifyInterface([]interface{}{GetCachedOrderbookResponse}),
Response: jsonifyInterface([]any{GetCachedOrderbookResponse}),
})
var fetchTradablePairsResponse []currency.Pair
@@ -413,10 +413,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{assetTypes[i]}),
SentParams: jsonifyInterface([]any{assetTypes[i]}),
Function: "FetchTradablePairs",
Error: msg,
Response: jsonifyInterface([]interface{}{fetchTradablePairsResponse}),
Response: jsonifyInterface([]any{fetchTradablePairsResponse}),
})
// r6
err = e.UpdateTradablePairs(context.TODO(), false)
@@ -426,10 +426,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{false}),
SentParams: jsonifyInterface([]any{false}),
Function: "UpdateTradablePairs",
Error: msg,
Response: jsonifyInterface([]interface{}{nil}),
Response: jsonifyInterface([]any{nil}),
})
var getHistoricTradesResponse []trade.Data
@@ -440,10 +440,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], time.Now().Add(-time.Hour), time.Now()}),
SentParams: jsonifyInterface([]any{p, assetTypes[i], time.Now().Add(-time.Hour), time.Now()}),
Function: "GetHistoricTrades",
Error: msg,
Response: jsonifyInterface([]interface{}{getHistoricTradesResponse}),
Response: jsonifyInterface([]any{getHistoricTradesResponse}),
})
var getRecentTradesResponse []trade.Data
@@ -454,10 +454,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{p, assetTypes[i]}),
Function: "GetRecentTrades",
Error: msg,
Response: jsonifyInterface([]interface{}{getRecentTradesResponse}),
Response: jsonifyInterface([]any{getRecentTradesResponse}),
})
var getHistoricCandlesResponse *kline.Item
@@ -472,7 +472,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
Function: "GetHistoricCandles",
Error: msg,
Response: getHistoricCandlesResponse,
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], startTime, endTime, kline.OneDay}),
SentParams: jsonifyInterface([]any{p, assetTypes[i], startTime, endTime, kline.OneDay}),
})
var getHistoricCandlesExtendedResponse *kline.Item
@@ -486,7 +486,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
Function: "GetHistoricCandlesExtended",
Error: msg,
Response: getHistoricCandlesExtendedResponse,
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], startTime, endTime, kline.OneDay}),
SentParams: jsonifyInterface([]any{p, assetTypes[i], startTime, endTime, kline.OneDay}),
})
var getServerTimeResponse time.Time
@@ -500,7 +500,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
Function: "GetServerTime",
Error: msg,
Response: getServerTimeResponse,
SentParams: jsonifyInterface([]interface{}{assetTypes[i]}),
SentParams: jsonifyInterface([]any{assetTypes[i]}),
})
err = e.UpdateOrderExecutionLimits(context.TODO(), assetTypes[i])
@@ -511,10 +511,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{assetTypes[i]}),
SentParams: jsonifyInterface([]any{assetTypes[i]}),
Function: "UpdateOrderExecutionLimits",
Error: msg,
Response: jsonifyInterface([]interface{}{""}),
Response: jsonifyInterface([]any{""}),
})
fundingRateRequest := &fundingrate.HistoricalRatesRequest{
@@ -532,10 +532,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{fundingRateRequest}),
SentParams: jsonifyInterface([]any{fundingRateRequest}),
Function: "GetFundingRates",
Error: msg,
Response: jsonifyInterface([]interface{}{fundingRateResponse}),
Response: jsonifyInterface([]any{fundingRateResponse}),
})
var isPerpetualFutures bool
@@ -546,10 +546,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{assetTypes[i], p}),
SentParams: jsonifyInterface([]any{assetTypes[i], p}),
Function: "IsPerpetualFutureCurrency",
Error: msg,
Response: jsonifyInterface([]interface{}{isPerpetualFutures}),
Response: jsonifyInterface([]any{isPerpetualFutures}),
})
}
@@ -563,7 +563,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
Function: "GetCachedAccountInfo",
Error: msg,
Response: jsonifyInterface([]interface{}{GetCachedAccountInfoResponse}),
Response: jsonifyInterface([]any{GetCachedAccountInfoResponse}),
})
var getFundingHistoryResponse []exchange.FundingHistory
@@ -576,7 +576,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
Function: "GetAccountFundingHistory",
Error: msg,
Response: jsonifyInterface([]interface{}{getFundingHistoryResponse}),
Response: jsonifyInterface([]any{getFundingHistoryResponse}),
})
feeType := exchange.FeeBuilder{
@@ -593,10 +593,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{feeType}),
SentParams: jsonifyInterface([]any{feeType}),
Function: "GetFeeByType-Trade",
Error: msg,
Response: jsonifyInterface([]interface{}{getFeeByTypeResponse}),
Response: jsonifyInterface([]any{getFeeByTypeResponse}),
})
s := &order.Submit{
@@ -617,10 +617,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{*s}),
SentParams: jsonifyInterface([]any{*s}),
Function: "SubmitOrder",
Error: msg,
Response: jsonifyInterface([]interface{}{submitOrderResponse}),
Response: jsonifyInterface([]any{submitOrderResponse}),
})
modifyRequest := order.Modify{
@@ -639,7 +639,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{modifyRequest}),
SentParams: jsonifyInterface([]any{modifyRequest}),
Function: "ModifyOrder",
Error: msg,
Response: modifyOrderResponse,
@@ -658,10 +658,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{cancelRequest}),
SentParams: jsonifyInterface([]any{cancelRequest}),
Function: "CancelOrder",
Error: msg,
Response: jsonifyInterface([]interface{}{nil}),
Response: jsonifyInterface([]any{nil}),
})
var request []order.Cancel
@@ -680,10 +680,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{cancelRequest}),
SentParams: jsonifyInterface([]any{cancelRequest}),
Function: "CancelBatchOrders",
Error: msg,
Response: jsonifyInterface([]interface{}{CancelBatchOrdersResponse}),
Response: jsonifyInterface([]any{CancelBatchOrdersResponse}),
})
var cancellAllOrdersResponse order.CancelAllResponse
@@ -694,10 +694,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{cancelRequest}),
SentParams: jsonifyInterface([]any{cancelRequest}),
Function: "CancelAllOrders",
Error: msg,
Response: jsonifyInterface([]interface{}{cancellAllOrdersResponse}),
Response: jsonifyInterface([]any{cancellAllOrdersResponse}),
})
var r15 *order.Detail
@@ -708,10 +708,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{config.OrderSubmission.OrderID, p, assetTypes[i]}),
SentParams: jsonifyInterface([]any{config.OrderSubmission.OrderID, p, assetTypes[i]}),
Function: "GetOrderInfo",
Error: msg,
Response: jsonifyInterface([]interface{}{r15}),
Response: jsonifyInterface([]any{r15}),
})
historyRequest := order.MultiOrderRequest{
@@ -730,10 +730,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{historyRequest}),
SentParams: jsonifyInterface([]any{historyRequest}),
Function: "GetOrderHistory",
Error: msg,
Response: jsonifyInterface([]interface{}{getOrderHistoryResponse}),
Response: jsonifyInterface([]any{getOrderHistoryResponse}),
})
orderRequest := order.MultiOrderRequest{
@@ -752,10 +752,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{orderRequest}),
SentParams: jsonifyInterface([]any{orderRequest}),
Function: "GetActiveOrders",
Error: msg,
Response: jsonifyInterface([]interface{}{getActiveOrdersResponse}),
Response: jsonifyInterface([]any{getActiveOrdersResponse}),
})
var getDepositAddressResponse *deposit.Address
@@ -766,7 +766,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p.Base, ""}),
SentParams: jsonifyInterface([]any{p.Base, ""}),
Function: "GetDepositAddress",
Error: msg,
Response: getDepositAddressResponse,
@@ -786,10 +786,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{feeType}),
SentParams: jsonifyInterface([]any{feeType}),
Function: "GetFeeByType-Crypto-Withdraw",
Error: msg,
Response: jsonifyInterface([]interface{}{GetFeeByTypeResponse}),
Response: jsonifyInterface([]any{GetFeeByTypeResponse}),
})
withdrawRequest := withdraw.Request{
@@ -811,7 +811,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{withdrawRequest}),
SentParams: jsonifyInterface([]any{withdrawRequest}),
Function: "WithdrawCryptocurrencyFunds",
Error: msg,
Response: withdrawCryptocurrencyFundsResponse,
@@ -833,10 +833,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{feeType}),
SentParams: jsonifyInterface([]any{feeType}),
Function: "GetFeeByType-FIAT-Withdraw",
Error: msg,
Response: jsonifyInterface([]interface{}{getFeeByTypeFiatResponse}),
Response: jsonifyInterface([]any{getFeeByTypeFiatResponse}),
})
withdrawRequestFiat := withdraw.Request{
@@ -876,7 +876,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{withdrawRequestFiat}),
SentParams: jsonifyInterface([]any{withdrawRequestFiat}),
Function: "WithdrawFiatFunds",
Error: msg,
Response: withdrawFiatFundsResponse,
@@ -889,7 +889,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{withdrawRequestFiat}),
SentParams: jsonifyInterface([]any{withdrawRequestFiat}),
Function: "WithdrawFiatFundsToInternationalBank",
Error: msg,
Response: withdrawFiatFundsInternationalResponse,
@@ -913,7 +913,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{marginRateHistoryRequest}),
SentParams: jsonifyInterface([]any{marginRateHistoryRequest}),
Function: "GetMarginRatesHistory",
Error: msg,
Response: marginRateHistoryResponse,
@@ -931,10 +931,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{positionSummaryRequest}),
SentParams: jsonifyInterface([]any{positionSummaryRequest}),
Function: "GetFuturesPositionSummary",
Error: msg,
Response: jsonifyInterface([]interface{}{positionSummaryResponse}),
Response: jsonifyInterface([]any{positionSummaryResponse}),
})
calculatePNLRequest := &futures.PNLCalculatorRequest{
@@ -957,10 +957,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{calculatePNLRequest}),
SentParams: jsonifyInterface([]any{calculatePNLRequest}),
Function: "CalculatePNL",
Error: msg,
Response: jsonifyInterface([]interface{}{calculatePNLResponse}),
Response: jsonifyInterface([]any{calculatePNLResponse}),
})
collateralCalculator := &futures.CollateralCalculator{
@@ -980,10 +980,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{collateralCalculator}),
SentParams: jsonifyInterface([]any{collateralCalculator}),
Function: "ScaleCollateral",
Error: msg,
Response: jsonifyInterface([]interface{}{scaleCollateralResponse}),
Response: jsonifyInterface([]any{scaleCollateralResponse}),
})
totalCollateralCalculator := &futures.TotalCollateralCalculator{
@@ -997,10 +997,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{totalCollateralCalculator}),
SentParams: jsonifyInterface([]any{totalCollateralCalculator}),
Function: "CalculateTotalCollateral",
Error: msg,
Response: jsonifyInterface([]interface{}{calculateTotalCollateralResponse}),
Response: jsonifyInterface([]any{calculateTotalCollateralResponse}),
})
var futuresPositionsResponse []futures.PositionResponse
@@ -1016,10 +1016,10 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{futuresPositionsRequest}),
SentParams: jsonifyInterface([]any{futuresPositionsRequest}),
Function: "GetFuturesPositionOrders",
Error: msg,
Response: jsonifyInterface([]interface{}{futuresPositionsResponse}),
Response: jsonifyInterface([]any{futuresPositionsResponse}),
})
response = append(response, responseContainer)
@@ -1027,7 +1027,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
return response
}
func jsonifyInterface(params []interface{}) json.RawMessage {
func jsonifyInterface(params []any) json.RawMessage {
response, _ := json.MarshalIndent(params, "", " ")
return response
}

View File

@@ -57,7 +57,7 @@ type ExchangeAssetPairResponses struct {
type EndpointResponse struct {
Function string `json:"function"`
Error string `json:"error"`
Response interface{} `json:"response"`
Response any `json:"response"`
SentParams json.RawMessage `json:"sentParams"`
}

View File

@@ -170,6 +170,17 @@ func isUnacceptableError(t *testing.T, err error) error {
return err
}
var validWrapperParams = []reflect.Type{
assetParam,
orderSubmitParam,
orderModifyParam,
orderCancelParam,
orderCancelsParam,
pairKeySliceParam,
getOrdersRequestParam,
latestRateRequest,
}
func executeExchangeWrapperTests(ctx context.Context, t *testing.T, exch exchange.IBotExchange, assetParams []assetPair) {
t.Helper()
iExchange := reflect.TypeOf(&exch).Elem()
@@ -184,15 +195,11 @@ func executeExchangeWrapperTests(ctx context.Context, t *testing.T, exch exchang
var assetLen int
for y := range method.Type().NumIn() {
input := method.Type().In(y)
for _, t := range []reflect.Type{
assetParam, orderSubmitParam, orderModifyParam, orderCancelParam, orderCancelsParam, pairKeySliceParam, getOrdersRequestParam, latestRateRequest,
} {
if input.AssignableTo(t) {
// this allows wrapper functions that support assets types
// to be tested with all supported assets
assetLen = len(assetParams) - 1
break
}
if slices.ContainsFunc(validWrapperParams, func(t reflect.Type) bool {
return input.AssignableTo(t)
}) {
assetLen = len(assetParams) - 1
break
}
}
tt := time.Now()
@@ -239,7 +246,7 @@ func CallExchangeMethod(t *testing.T, methodToCall reflect.Value, methodValues [
continue
}
if isUnacceptableError(t, err) != nil {
literalInputs := make([]interface{}, len(methodValues))
literalInputs := make([]any, len(methodValues))
for j := range methodValues {
if methodValues[j].Kind() == reflect.Ptr {
// dereference pointers just to add a bit more clarity
@@ -699,12 +706,7 @@ func isFiat(t *testing.T, c string) bool {
currency.ZCAD.Item.Lower,
currency.ZJPY.Item.Lower,
}
for i := range fiats {
if fiats[i] == c {
return true
}
}
return false
return slices.Contains(fiats, c)
}
// disruptFormatting adds in an unused delimiter and strange casing features to

View File

@@ -35,7 +35,7 @@ var (
const defaultTimeout = time.Second * 30
func jsonOutput(in interface{}) {
func jsonOutput(in any) {
j, err := json.MarshalIndent(in, "", " ")
if err != nil {
return

View File

@@ -371,7 +371,6 @@ func getOrderbook(c *cli.Context) error {
var (
exchangeName, pair, assetType string
depthLimit int64
exchangeStyle bool
err error
)
@@ -407,12 +406,15 @@ func getOrderbook(c *cli.Context) error {
}
}
if c.IsSet("depthlimit") {
depthLimit = c.Int64("depthlimit")
} else if c.Args().Get(4) != "" {
depthLimit, err = strconv.ParseInt(c.Args().Get(4), 10, 64)
if err != nil {
const depthCeiling uint64 = 100 // The maximum the depth can be regardless of user entry
depthLimit := depthCeiling
if d := c.Uint64("depthlimit"); d > 0 && d < depthCeiling {
depthLimit = d
} else if d := c.Args().Get(4); d != "" {
if du, err := strconv.ParseUint(d, 10, 64); err != nil {
return err
} else if du > 0 && du < depthCeiling {
depthLimit = du
}
}
@@ -449,20 +451,9 @@ func getOrderbook(c *cli.Context) error {
}
if exchangeStyle {
var maxLen, bidLen, askLen int64
bidLen = int64(len(result.Bids) - 1)
askLen = int64(len(result.Asks) - 1)
if bidLen >= askLen {
maxLen = bidLen
} else {
maxLen = askLen
}
if depthLimit > 0 && depthLimit < maxLen {
maxLen = depthLimit
}
if maxLen > 100 {
maxLen = 100
}
bidLen := uint64(len(result.Bids) - 1) //nolint:gosec // Can fit in uint64
askLen := uint64(len(result.Asks) - 1) //nolint:gosec // Can fit in uint64
maxLen := min(max(bidLen, askLen), depthLimit)
renderOrderbookExchangeStyle(result, exchangeName, assetType, maxLen, askLen, bidLen)
} else {
jsonOutput(result)
@@ -516,7 +507,6 @@ func getOrderbookStream(c *cli.Context) error {
var (
exchangeName, pair, assetType string
depthLimit int64
exchangeStyle bool
err error
)
@@ -552,12 +542,15 @@ func getOrderbookStream(c *cli.Context) error {
}
}
if c.IsSet("depthlimit") {
depthLimit = c.Int64("depthlimit")
} else if c.Args().Get(4) != "" {
depthLimit, err = strconv.ParseInt(c.Args().Get(4), 10, 64)
if err != nil {
const depthCeiling uint64 = 50 // The maximum the depth can be regardless of user entry
depthLimit := depthCeiling
if d := c.Uint64("depthlimit"); d > 0 && d < depthCeiling {
depthLimit = d
} else if d := c.Args().Get(4); d != "" {
if du, err := strconv.ParseUint(d, 10, 64); err != nil {
return err
} else if du > 0 && du < depthCeiling {
depthLimit = du
}
}
@@ -610,21 +603,9 @@ func getOrderbookStream(c *cli.Context) error {
continue
}
bidLen := int64(len(resp.Bids) - 1)
askLen := int64(len(resp.Asks) - 1)
var maxLen int64
if bidLen >= askLen {
maxLen = bidLen
} else {
maxLen = askLen
}
if depthLimit > 0 && depthLimit < maxLen {
maxLen = depthLimit
}
if maxLen > 50 {
maxLen = 50
}
bidLen := uint64(len(resp.Bids) - 1) //nolint:gosec // Can fit in uint64
askLen := uint64(len(resp.Asks) - 1) //nolint:gosec // Can fit in uint64
maxLen := min(max(bidLen, askLen), depthLimit)
if exchangeStyle {
renderOrderbookExchangeStyle(resp, exchangeName, assetType, maxLen, askLen, bidLen)
@@ -660,7 +641,7 @@ func getOrderbookStream(c *cli.Context) error {
}
}
func renderOrderbookExchangeStyle(resp *gctrpc.OrderbookResponse, exchangeName, assetType string, maxLen, askLen, bidLen int64) {
func renderOrderbookExchangeStyle(resp *gctrpc.OrderbookResponse, exchangeName, assetType string, maxLen, askLen, bidLen uint64) {
maxLen-- // ensure we get the 0 index at the correct max length
upperBase := strings.ToUpper(resp.Pair.Base)
upperQuote := strings.ToUpper(resp.Pair.Quote)
@@ -670,16 +651,17 @@ func renderOrderbookExchangeStyle(resp *gctrpc.OrderbookResponse, exchangeName,
fmt.Printf("%sPrice(%v)\t\tAmount(%s)\n",
grayText, upperQuote, upperBase)
for i := maxLen; i >= 0; i-- {
for i := uint64(0); i <= maxLen; i++ {
j := maxLen - i
var askAmount, askPrice float64
if i <= askLen {
askAmount = resp.Asks[i].Amount
askPrice = resp.Asks[i].Price
if j <= askLen {
askAmount = resp.Asks[j].Amount
askPrice = resp.Asks[j].Price
}
fmt.Printf(printFmt, redText, askPrice, askAmount)
}
fmt.Println()
for i := int64(0); i <= maxLen; i++ {
for i := uint64(0); i <= maxLen; i++ {
var bidAmount, bidPrice float64
if i <= bidLen {
bidAmount = resp.Bids[i].Amount

View File

@@ -26,7 +26,7 @@ type WebsocketEvent struct {
Exchange string `json:"exchange,omitempty"`
AssetType string `json:"assetType,omitempty"`
Event string
Data interface{}
Data any
}
// WebsocketAuth is the struct used for a websocket auth request
@@ -37,9 +37,9 @@ type WebsocketAuth struct {
// WebsocketEventResponse is the struct used for websocket event responses
type WebsocketEventResponse struct {
Event string `json:"event"`
Data interface{} `json:"data"`
Error string `json:"error"`
Event string `json:"event"`
Data any `json:"data"`
Error string `json:"error"`
}
// WebsocketOrderbookTickerRequest is a struct used for ticker and orderbook
@@ -51,7 +51,7 @@ type WebsocketOrderbookTickerRequest struct {
}
// SendWebsocketEvent sends a websocket event message
func SendWebsocketEvent(event string, reqData interface{}, result *WebsocketEventResponse) error {
func SendWebsocketEvent(event string, reqData any, result *WebsocketEventResponse) error {
req := WebsocketEvent{
Event: event,
}

14
common/cache/cache.go vendored
View File

@@ -8,35 +8,35 @@ func New(capacity uint64) *LRUCache {
}
// Add new entry to Cache return true if entry removed
func (l *LRUCache) Add(k, v interface{}) {
func (l *LRUCache) Add(k, v any) {
l.m.Lock()
l.lru.Add(k, v)
l.m.Unlock()
}
// Get looks up a key's value from the cache.
func (l *LRUCache) Get(key interface{}) (value interface{}) {
func (l *LRUCache) Get(key any) (value any) {
l.m.Lock()
defer l.m.Unlock()
return l.lru.Get(key)
}
// GetOldest looks up old key's value from the cache.
func (l *LRUCache) getOldest() (key, value interface{}) {
func (l *LRUCache) getOldest() (key, value any) {
l.m.Lock()
defer l.m.Unlock()
return l.lru.getOldest()
}
// getNewest looks up a key's value from the cache.
func (l *LRUCache) getNewest() (key, value interface{}) {
func (l *LRUCache) getNewest() (key, value any) {
l.m.Lock()
defer l.m.Unlock()
return l.lru.getNewest()
}
// ContainsOrAdd checks if cache contains key if not adds to cache
func (l *LRUCache) ContainsOrAdd(key, value interface{}) bool {
func (l *LRUCache) ContainsOrAdd(key, value any) bool {
l.m.Lock()
defer l.m.Unlock()
if l.lru.Contains(key) {
@@ -47,14 +47,14 @@ func (l *LRUCache) ContainsOrAdd(key, value interface{}) bool {
}
// Contains checks if cache contains key
func (l *LRUCache) Contains(key interface{}) bool {
func (l *LRUCache) Contains(key any) bool {
l.m.Lock()
defer l.m.Unlock()
return l.lru.Contains(key)
}
// Remove entry from cache
func (l *LRUCache) Remove(key interface{}) bool {
func (l *LRUCache) Remove(key any) bool {
l.m.Lock()
defer l.m.Unlock()
return l.lru.Remove(key)

View File

@@ -15,11 +15,11 @@ type LRUCache struct {
type LRU struct {
Cap uint64
l *list.List
items map[interface{}]*list.Element
items map[any]*list.Element
}
// item holds key/value for the cache
type item struct {
key interface{}
value interface{}
key any
value any
}

14
common/cache/lru.go vendored
View File

@@ -16,12 +16,12 @@ func NewLRUCache(capacity uint64) *LRU {
return &LRU{
Cap: capacity,
l: list.New(),
items: make(map[interface{}]*list.Element),
items: make(map[any]*list.Element),
}
}
// Add adds a value to the cache
func (l *LRU) Add(key, value interface{}) {
func (l *LRU) Add(key, value any) {
if f, o := l.items[key]; o {
l.l.MoveToFront(f)
if v, ok := f.Value.(*item); ok {
@@ -39,7 +39,7 @@ func (l *LRU) Add(key, value interface{}) {
}
// Get returns keys value from cache if found
func (l *LRU) Get(key interface{}) interface{} {
func (l *LRU) Get(key any) any {
if i, f := l.items[key]; f {
l.l.MoveToFront(i)
if v, ok := i.Value.(*item); ok {
@@ -50,7 +50,7 @@ func (l *LRU) Get(key interface{}) interface{} {
}
// GetOldest returns the oldest entry
func (l *LRU) getOldest() (key, value interface{}) {
func (l *LRU) getOldest() (key, value any) {
if x := l.l.Back(); x != nil {
if v, ok := x.Value.(*item); ok {
return v.key, v.value
@@ -60,7 +60,7 @@ func (l *LRU) getOldest() (key, value interface{}) {
}
// GetNewest returns the newest entry
func (l *LRU) getNewest() (key, value interface{}) {
func (l *LRU) getNewest() (key, value any) {
if x := l.l.Front(); x != nil {
if v, ok := x.Value.(*item); ok {
return v.key, v.value
@@ -70,13 +70,13 @@ func (l *LRU) getNewest() (key, value interface{}) {
}
// Contains check if key is in cache this does not update LRU
func (l *LRU) Contains(key interface{}) (f bool) {
func (l *LRU) Contains(key any) (f bool) {
_, f = l.items[key]
return
}
// Remove removes key from the cache, if the key was removed.
func (l *LRU) Remove(key interface{}) bool {
func (l *LRU) Remove(key any) bool {
if i, f := l.items[key]; f {
l.removeElement(i)
return true

View File

@@ -594,7 +594,7 @@ func GenerateRandomString(length uint, characters ...string) (string, error) {
// GetTypeAssertError returns additional information for when an assertion failure
// occurs.
// fieldDescription is an optional way to return what the affected field was for
func GetTypeAssertError(required string, received interface{}, fieldDescription ...string) error {
func GetTypeAssertError(required string, received any, fieldDescription ...string) error {
var description string
if len(fieldDescription) > 0 {
description = " for: " + strings.Join(fieldDescription, ", ")

View File

@@ -11,7 +11,7 @@ import (
)
// FloatFromString format
func FloatFromString(raw interface{}) (float64, error) {
func FloatFromString(raw any) (float64, error) {
str, ok := raw.(string)
if !ok {
return 0, fmt.Errorf("unable to parse, value not string: %T", raw)
@@ -24,7 +24,7 @@ func FloatFromString(raw interface{}) (float64, error) {
}
// IntFromString format
func IntFromString(raw interface{}) (int, error) {
func IntFromString(raw any) (int, error) {
str, ok := raw.(string)
if !ok {
return 0, fmt.Errorf("unable to parse, value not string: %T", raw)
@@ -37,7 +37,7 @@ func IntFromString(raw interface{}) (int, error) {
}
// Int64FromString format
func Int64FromString(raw interface{}) (int64, error) {
func Int64FromString(raw any) (int64, error) {
str, ok := raw.(string)
if !ok {
return 0, fmt.Errorf("unable to parse, value not string: %T", raw)
@@ -50,7 +50,7 @@ func Int64FromString(raw interface{}) (int64, error) {
}
// TimeFromUnixTimestampFloat format
func TimeFromUnixTimestampFloat(raw interface{}) (time.Time, error) {
func TimeFromUnixTimestampFloat(raw any) (time.Time, error) {
ts, ok := raw.(float64)
if !ok {
return time.Time{}, fmt.Errorf("unable to parse, value not float64: %T", raw)
@@ -167,7 +167,7 @@ func numberToHumanFriendlyString(str string, dec uint, decPoint, thousandsSep st
}
// InterfaceToFloat64OrZeroValue returns the type assertion value or variable zero value
func InterfaceToFloat64OrZeroValue(r interface{}) float64 {
func InterfaceToFloat64OrZeroValue(r any) float64 {
if v, ok := r.(float64); ok {
return v
}
@@ -175,7 +175,7 @@ func InterfaceToFloat64OrZeroValue(r interface{}) float64 {
}
// InterfaceToIntOrZeroValue returns the type assertion value or variable zero value
func InterfaceToIntOrZeroValue(r interface{}) int {
func InterfaceToIntOrZeroValue(r any) int {
if v, ok := r.(int); ok {
return v
}
@@ -183,7 +183,7 @@ func InterfaceToIntOrZeroValue(r interface{}) int {
}
// InterfaceToStringOrZeroValue returns the type assertion value or variable zero value
func InterfaceToStringOrZeroValue(r interface{}) string {
func InterfaceToStringOrZeroValue(r any) string {
if v, ok := r.(string); ok {
return v
}

View File

@@ -196,7 +196,7 @@ func TestNumberToHumanFriendlyString(t *testing.T) {
}
func TestInterfaceToFloat64OrZeroValue(t *testing.T) {
var x interface{}
var x any
if r := InterfaceToFloat64OrZeroValue(x); r != 0 {
t.Errorf("expected 0, got: %v", r)
}
@@ -207,7 +207,7 @@ func TestInterfaceToFloat64OrZeroValue(t *testing.T) {
}
func TestInterfaceToIntOrZeroValue(t *testing.T) {
var x interface{}
var x any
if r := InterfaceToIntOrZeroValue(x); r != 0 {
t.Errorf("expected 0, got: %v", r)
}
@@ -218,7 +218,7 @@ func TestInterfaceToIntOrZeroValue(t *testing.T) {
}
func TestInterfaceToStringOrZeroValue(t *testing.T) {
var x interface{}
var x any
if r := InterfaceToStringOrZeroValue(x); r != "" {
t.Errorf("expected empty string, got: %v", r)
}

View File

@@ -7,6 +7,7 @@ import (
"flag"
"net/http"
"net/url"
"slices"
"strings"
"github.com/thrasher-corp/gocryptotrader/common"
@@ -137,7 +138,7 @@ func (s *SMSGlobal) RemoveContact(contact Contact) error {
for x := range s.Contacts {
if s.Contacts[x].Name == contact.Name && s.Contacts[x].Number == contact.Number {
s.Contacts = append(s.Contacts[:x], s.Contacts[x+1:]...)
s.Contacts = slices.Delete(s.Contacts, x, x+1)
return nil
}
}

View File

@@ -274,7 +274,7 @@ func (t *Telegram) SendMessage(text string, chatID int64) error {
}
// SendHTTPRequest sends an authenticated HTTP request
func (t *Telegram) SendHTTPRequest(path string, data []byte, result interface{}) error {
func (t *Telegram) SendHTTPRequest(path string, data []byte, result any) error {
headers := make(map[string]string)
headers["content-type"] = "application/json"

View File

@@ -21,14 +21,14 @@ type GetUpdateResponse struct {
Result []struct {
UpdateID int64 `json:"update_id"`
Message MessageType `json:"message"`
EditedMessage interface{} `json:"edited_message"`
ChannelPost interface{} `json:"channel_post"`
EditedChannelPost interface{} `json:"edited_channel_post"`
InlineQuery interface{} `json:"inline_query"`
ChosenInlineResult interface{} `json:"chosen_inline_result"`
CallbackQuery interface{} `json:"callback_query"`
ShippingQuery interface{} `json:"shipping_query"`
PreCheckoutQuery interface{} `json:"pre_checkout_query"`
EditedMessage any `json:"edited_message"`
ChannelPost any `json:"channel_post"`
EditedChannelPost any `json:"edited_channel_post"`
InlineQuery any `json:"inline_query"`
ChosenInlineResult any `json:"chosen_inline_result"`
CallbackQuery any `json:"callback_query"`
ShippingQuery any `json:"shipping_query"`
PreCheckoutQuery any `json:"pre_checkout_query"`
} `json:"result"`
}
@@ -50,7 +50,7 @@ type MessageType struct {
ForwardFromMessageID int64 `json:"forward_from_message_id"`
ForwardSignature string `json:"forward_signature"`
ForwardDate int64 `json:"forward_date"`
ReplyToMessage interface{} `json:"reply_to_message"`
ReplyToMessage any `json:"reply_to_message"`
EditDate int64 `json:"edit_date"`
MediaGroupID string `json:"media_group_id"`
AuthorSignature string `json:"author_signature"`

View File

@@ -1719,9 +1719,10 @@ func SetConfig(c *Config) {
func (c *Config) RemoveExchange(exchName string) bool {
m.Lock()
defer m.Unlock()
for x := range c.Exchanges {
if strings.EqualFold(c.Exchanges[x].Name, exchName) {
c.Exchanges = append(c.Exchanges[:x], c.Exchanges[x+1:]...)
c.Exchanges = slices.Delete(c.Exchanges, x, x+1)
return true
}
}

View File

@@ -1369,8 +1369,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
}
// Make a sneaky copy for bank account testing
//nolint: gocritic
cpy := append(cfg.Exchanges[:0:0], cfg.Exchanges...)
cpy := slices.Clone(cfg.Exchanges)
// Test empty exchange name for an enabled exchange
cfg.Exchanges[0].Enabled = true

View File

@@ -299,9 +299,9 @@ type BankTransaction struct {
// FeaturesSupportedConfig stores the exchanges supported features
type FeaturesSupportedConfig struct {
REST bool `json:"restAPI"`
RESTCapabilities protocol.Features `json:"restCapabilities,omitempty"`
RESTCapabilities protocol.Features `json:"restCapabilities,omitzero"`
Websocket bool `json:"websocketAPI"`
WebsocketCapabilities protocol.Features `json:"websocketCapabilities,omitempty"`
WebsocketCapabilities protocol.Features `json:"websocketCapabilities,omitzero"`
}
// FeaturesEnabledConfig stores the exchanges enabled features

View File

@@ -682,7 +682,7 @@ func (c *Coinmarketcap) GetPriceConversion(amount float64, currencyID int64, atH
}
// SendHTTPRequest sends a valid HTTP request
func (c *Coinmarketcap) SendHTTPRequest(method, endpoint string, v url.Values, result interface{}) error {
func (c *Coinmarketcap) SendHTTPRequest(method, endpoint string, v url.Values, result any) error {
headers := make(map[string]string)
headers["Accept"] = "application/json"
headers["X-CMC_PRO_API_KEY"] = c.APIkey

View File

@@ -112,23 +112,23 @@ type OHLC struct {
// CryptoCurrencyInfo defines cryptocurrency information
type CryptoCurrencyInfo map[string]struct {
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Category string `json:"category"`
Slug string `json:"slug"`
Logo string `json:"logo"`
Tags []string `json:"tags"`
Platform interface{} `json:"platform"`
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Category string `json:"category"`
Slug string `json:"slug"`
Logo string `json:"logo"`
Tags []string `json:"tags"`
Platform any `json:"platform"`
Urls struct {
Website []string `json:"website"`
Explorer []string `json:"explorer"`
SourceCode []string `json:"source_code"`
MessageBoard []string `json:"message_board"`
Chat []interface{} `json:"chat"`
Announcement []interface{} `json:"announcement"`
Reddit []string `json:"reddit"`
Twitter []string `json:"twitter"`
Website []string `json:"website"`
Explorer []string `json:"explorer"`
SourceCode []string `json:"source_code"`
MessageBoard []string `json:"message_board"`
Chat []any `json:"chat"`
Announcement []any `json:"announcement"`
Reddit []string `json:"reddit"`
Twitter []string `json:"twitter"`
} `json:"urls"`
}
@@ -170,19 +170,19 @@ type CryptocurrencyHistoricalListings struct {
// CryptocurrencyLatestListings defines latest cryptocurrency listing data
type CryptocurrencyLatestListings struct {
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Slug string `json:"slug"`
CmcRank int `json:"cmc_rank"`
NumMarketPairs int `json:"num_market_pairs"`
CirculatingSupply float64 `json:"circulating_supply"`
TotalSupply float64 `json:"total_supply"`
MaxSupply float64 `json:"max_supply"`
LastUpdated time.Time `json:"last_updated"`
DateAdded time.Time `json:"date_added"`
Tags []string `json:"tags"`
Platform interface{} `json:"platform"`
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Slug string `json:"slug"`
CmcRank int `json:"cmc_rank"`
NumMarketPairs int `json:"num_market_pairs"`
CirculatingSupply float64 `json:"circulating_supply"`
TotalSupply float64 `json:"total_supply"`
MaxSupply float64 `json:"max_supply"`
LastUpdated time.Time `json:"last_updated"`
DateAdded time.Time `json:"date_added"`
Tags []string `json:"tags"`
Platform any `json:"platform"`
Quote struct {
USD Currency `json:"USD"`
BTC Currency `json:"BTC"`
@@ -240,12 +240,12 @@ type CryptocurrencyOHLCHistorical struct {
// CryptocurrencyOHLCLatest defines open high low close latest data
type CryptocurrencyOHLCLatest map[string]struct {
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
LastUpdated time.Time `json:"last_updated"`
TimeOpen time.Time `json:"time_open"`
TimeClose interface{} `json:"time_close"`
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
LastUpdated time.Time `json:"last_updated"`
TimeOpen time.Time `json:"time_open"`
TimeClose any `json:"time_close"`
Quote struct {
USD OHLC `json:"USD"`
} `json:"quote"`
@@ -253,19 +253,19 @@ type CryptocurrencyOHLCLatest map[string]struct {
// CryptocurrencyLatestQuotes defines latest cryptocurrency quotation data
type CryptocurrencyLatestQuotes map[string]struct {
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Slug string `json:"slug"`
CirculatingSupply float64 `json:"circulating_supply"`
TotalSupply float64 `json:"total_supply"`
MaxSupply float64 `json:"max_supply"`
DateAdded time.Time `json:"date_added"`
NumMarketPairs int `json:"num_market_pairs"`
CmcRank int `json:"cmc_rank"`
LastUpdated time.Time `json:"last_updated"`
Tags []string `json:"tags"`
Platform interface{} `json:"platform"`
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Slug string `json:"slug"`
CirculatingSupply float64 `json:"circulating_supply"`
TotalSupply float64 `json:"total_supply"`
MaxSupply float64 `json:"max_supply"`
DateAdded time.Time `json:"date_added"`
NumMarketPairs int `json:"num_market_pairs"`
CmcRank int `json:"cmc_rank"`
LastUpdated time.Time `json:"last_updated"`
Tags []string `json:"tags"`
Platform any `json:"platform"`
Quote struct {
USD Currency `json:"USD"`
} `json:"quote"`
@@ -288,11 +288,11 @@ type CryptocurrencyHistoricalQuotes struct {
// ExchangeInfo defines exchange information
type ExchangeInfo map[string]struct {
Urls struct {
Website []string `json:"website"`
Twitter []string `json:"twitter"`
Blog []interface{} `json:"blog"`
Chat []string `json:"chat"`
Fee []string `json:"fee"`
Website []string `json:"website"`
Twitter []string `json:"twitter"`
Blog []any `json:"blog"`
Chat []string `json:"chat"`
Fee []string `json:"fee"`
} `json:"urls"`
Logo string `json:"logo"`
ID int `json:"id"`

View File

@@ -64,13 +64,13 @@ type FXSettings struct {
// File defines a full currency file generated by the currency storage
// analysis system
type File struct {
LastMainUpdate interface{} `json:"lastMainUpdate"`
Cryptocurrency []*Item `json:"cryptocurrencies"`
FiatCurrency []*Item `json:"fiatCurrencies"`
UnsetCurrency []*Item `json:"unsetCurrencies"`
Contracts []*Item `json:"contracts"`
Token []*Item `json:"tokens"`
Stable []*Item `json:"stableCurrencies"`
LastMainUpdate any `json:"lastMainUpdate"`
Cryptocurrency []*Item `json:"cryptocurrencies"`
FiatCurrency []*Item `json:"fiatCurrencies"`
UnsetCurrency []*Item `json:"unsetCurrencies"`
Contracts []*Item `json:"contracts"`
Token []*Item `json:"tokens"`
Stable []*Item `json:"stableCurrencies"`
}
// Const here are packaged defined delimiters

View File

@@ -3,6 +3,7 @@ package base
import (
"errors"
"fmt"
"maps"
"strings"
"sync"
@@ -101,9 +102,7 @@ func (f *FXHandler) GetCurrencyData(baseCurrency string, currencies []string) (m
err)
}
for key, val := range rateNew {
rates[key] = val
}
maps.Copy(rates, rateNew)
return rates, nil
}
@@ -125,9 +124,7 @@ func (f *FXHandler) backupGetRate(base string, currencies []string) (map[string]
continue
}
for k, v := range newRate {
rate[k] = v
}
maps.Copy(rate, newRate)
if len(shunt) != 0 {
continue
@@ -142,9 +139,7 @@ func (f *FXHandler) backupGetRate(base string, currencies []string) (map[string]
continue
}
for k, v := range newRate {
rate[k] = v
}
maps.Copy(rate, newRate)
if len(shunt) != 0 {
continue

View File

@@ -149,7 +149,7 @@ func (c *CurrencyConverter) GetCountries() (map[string]CountryItem, error) {
// SendHTTPRequest sends a HTTP request, if account is not free it automatically
// upgrades request to SSL.
func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values, result interface{}) error {
func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values, result any) error {
var path string
var auth request.AuthType
if c.APIKey == "" || c.APIKey == defaultAPIKey {

View File

@@ -141,7 +141,7 @@ func (c *CurrencyLayer) Convert(from, to, date string, amount float64) (float64,
// QueryTimeFrame returns historical exchange rates for a time-period.
// (maximum range: 365 days)
func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, baseCurrency string, currencies []string) (map[string]interface{}, error) {
func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, baseCurrency string, currencies []string) (map[string]any, error) {
if c.APIKeyLvl >= AccountPro {
return nil, errors.New("insufficient API privileges, upgrade to basic to use this function")
}
@@ -193,7 +193,7 @@ func (c *CurrencyLayer) QueryCurrencyChange(startDate, endDate, baseCurrency str
// SendHTTPRequest sends a HTTP request, if account is not free it automatically
// upgrades request to SSL.
func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, result interface{}) error {
func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, result any) error {
var path string
values.Set("access_key", c.APIKey)

View File

@@ -92,15 +92,15 @@ type ConversionRate struct {
// TimeFrame is a response type holding exchange rates for a time period
type TimeFrame struct {
Success bool `json:"success"`
Error Error `json:"error"`
Terms string `json:"terms"`
Privacy string `json:"privacy"`
Timeframe bool `json:"timeframe"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Source string `json:"source"`
Quotes map[string]interface{} `json:"quotes"`
Success bool `json:"success"`
Error Error `json:"error"`
Terms string `json:"terms"`
Privacy string `json:"privacy"`
Timeframe bool `json:"timeframe"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Source string `json:"source"`
Quotes map[string]any `json:"quotes"`
}
// ChangeRate is the response type that holds rate change data.

View File

@@ -254,7 +254,7 @@ func (e *ExchangeRates) GetSupportedCurrencies() ([]string, error) {
}
// SendHTTPRequest sends a HTTPS request to the desired endpoint and returns the result
func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, result interface{}) error {
func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, result any) error {
if e.APIKey == "" {
return errors.New("api key must be set")
}

View File

@@ -168,7 +168,7 @@ func (f *Fixer) ConvertCurrency(from, to, date string, amount float64) (float64,
// GetTimeSeriesData returns daily historical exchange rate data between two
// specified dates for all available or a specific set of currencies.
func (f *Fixer) GetTimeSeriesData(startDate, endDate, baseCurrency string, symbols []string) (map[string]interface{}, error) {
func (f *Fixer) GetTimeSeriesData(startDate, endDate, baseCurrency string, symbols []string) (map[string]any, error) {
if f.APIKeyLvl < fixerAPIProfessional {
return nil, errors.New("insufficient API privileges, upgrade to professional to use this function")
}
@@ -219,7 +219,7 @@ func (f *Fixer) GetFluctuationData(startDate, endDate, baseCurrency string, symb
}
// SendOpenHTTPRequest sends a typical get request
func (f *Fixer) SendOpenHTTPRequest(endpoint string, v url.Values, result interface{}) error {
func (f *Fixer) SendOpenHTTPRequest(endpoint string, v url.Values, result any) error {
if v == nil {
v = url.Values{}
}

View File

@@ -59,13 +59,13 @@ type Conversion struct {
// TimeSeries holds timeseries data
type TimeSeries struct {
Success bool `json:"success"`
Error RespError `json:"error"`
Timeseries bool `json:"timeseries"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]interface{} `json:"rates"`
Success bool `json:"success"`
Error RespError `json:"error"`
Timeseries bool `json:"timeseries"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]any `json:"rates"`
}
// Fluctuation holds fluctuation data

View File

@@ -122,7 +122,7 @@ func (o *OXR) GetSupportedCurrencies() ([]string, error) {
// GetTimeSeries returns historical exchange rates for a given time period,
// where available.
func (o *OXR) GetTimeSeries(baseCurrency, startDate, endDate string, symbols []string, prettyPrint, showAlternative bool) (map[string]interface{}, error) {
func (o *OXR) GetTimeSeries(baseCurrency, startDate, endDate string, symbols []string, prettyPrint, showAlternative bool) (map[string]any, error) {
if o.APIKeyLvl < APIEnterpriseAccess {
return nil, errors.New("upgrade account, insufficient access")
}
@@ -170,7 +170,7 @@ func (o *OXR) ConvertCurrency(amount float64, from, to string) (float64, error)
// GetOHLC returns historical Open, High Low, Close (OHLC) and Average exchange
// rates for a given time period, ranging from 1 month to 1 minute, where
// available.
func (o *OXR) GetOHLC(startTime, period, baseCurrency string, symbols []string, prettyPrint bool) (map[string]interface{}, error) {
func (o *OXR) GetOHLC(startTime, period, baseCurrency string, symbols []string, prettyPrint bool) (map[string]any, error) {
if o.APIKeyLvl < APIUnlimitedAccess {
return nil, errors.New("upgrade account, insufficient access")
}
@@ -213,7 +213,7 @@ func (o *OXR) GetUsageStats(prettyPrint bool) (Usage, error) {
}
// SendHTTPRequest sends a HTTP request
func (o *OXR) SendHTTPRequest(endpoint string, values url.Values, result interface{}) error {
func (o *OXR) SendHTTPRequest(endpoint string, values url.Values, result any) error {
headers := make(map[string]string)
headers["Authorization"] = "Token " + o.APIKey
path := APIURL + endpoint + "?" + values.Encode()

View File

@@ -69,16 +69,16 @@ type Historical struct {
// TimeSeries holds historic rate data
type TimeSeries struct {
Disclaimer string `json:"disclaimer"`
License string `json:"license"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]interface{} `json:"rates"`
Error bool `json:"error"`
Status int `json:"status"`
Message string `json:"message"`
Description string `json:"description"`
Disclaimer string `json:"disclaimer"`
License string `json:"license"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]any `json:"rates"`
Error bool `json:"error"`
Status int `json:"status"`
Message string `json:"message"`
Description string `json:"description"`
}
// Convert holds historic rate data
@@ -104,16 +104,16 @@ type Convert struct {
// OHLC holds open high low close values
type OHLC struct {
Disclaimer string `json:"disclaimer"`
License string `json:"license"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]interface{} `json:"rates"`
Error bool `json:"error"`
Status int `json:"status"`
Message string `json:"message"`
Description string `json:"description"`
Disclaimer string `json:"disclaimer"`
License string `json:"license"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Base string `json:"base"`
Rates map[string]any `json:"rates"`
Error bool `json:"error"`
Status int `json:"status"`
Message string `json:"message"`
Description string `json:"description"`
}
// Usage holds usage statistical data

View File

@@ -33,7 +33,7 @@ func (m *MockProvider) GetSupportedCurrencies() ([]string, error) {
func (m *MockProvider) GetRates(baseCurrency, symbols string) (map[string]float64, error) {
c := map[string]float64{}
for _, s := range strings.Split(symbols, ",") {
for s := range strings.SplitSeq(symbols, ",") {
// The year is 2027; The USD is nearly worthless. The world reserve currency is eggs.
c[baseCurrency+s] = 1 / (1 + rand.Float64()) //nolint:gosec // Doesn't need to be a strong random number
}

View File

@@ -124,10 +124,7 @@ func (f *PairFormat) clone() *PairFormat {
func MatchPairsWithNoDelimiter(currencyPair string, pairs Pairs, pairFmt PairFormat) (Pair, error) {
for i := range pairs {
fPair := pairs[i].Format(pairFmt)
maxLen := 6
if len(currencyPair) < maxLen {
maxLen = len(currencyPair)
}
maxLen := min(len(currencyPair), 6)
for j := 1; j <= maxLen; j++ {
if fPair.Base.String() == currencyPair[0:j] &&
fPair.Quote.String() == currencyPair[j:] {

View File

@@ -5,8 +5,8 @@ package currency
// is a delimiter present in the string, otherwise it will return an error.
type Pair struct {
Delimiter string `json:"delimiter,omitempty"`
Base Code `json:"base,omitempty"`
Quote Code `json:"quote,omitempty"`
Base Code `json:"base"`
Quote Code `json:"quote"`
}
// Pairs defines a list of pairs

View File

@@ -75,10 +75,10 @@ type IDatabase interface {
// without giving the receiver access to all functionality
type ISQL interface {
BeginTx(context.Context, *sql.TxOptions) (*sql.Tx, error)
Exec(string, ...interface{}) (sql.Result, error)
Query(string, ...interface{}) (*sql.Rows, error)
QueryRow(string, ...interface{}) *sql.Row
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
Exec(string, ...any) (sql.Result, error)
Query(string, ...any) (*sql.Rows, error)
QueryRow(string, ...any) *sql.Row
ExecContext(context.Context, string, ...any) (sql.Result, error)
QueryContext(context.Context, string, ...any) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...any) *sql.Row
}

View File

@@ -61,7 +61,7 @@ func Event(id, msgtype, message string) {
}
// GetEvent () returns list of order events matching query
func GetEvent(startTime, endTime time.Time, order string, limit int) (interface{}, error) {
func GetEvent(startTime, endTime time.Time, order string, limit int) (any, error) {
if database.DB.SQL == nil {
return nil, database.ErrDatabaseSupportDisabled
}

View File

@@ -36,7 +36,7 @@ func TestAudit(t *testing.T) {
config *database.Config
runner func(t *testing.T)
closer func(dbConn *database.Instance) error
output interface{}
output any
}{
{
"SQLite-Write",

View File

@@ -48,7 +48,7 @@ func TestScript(t *testing.T) {
config *database.Config
runner func()
closer func(dbConn *database.Instance) error
output interface{}
output any
}{
{
"SQLite-Write",

View File

@@ -309,7 +309,7 @@ func getInRangeSQLite(exchangeName, assetType, base, quote string, startDate, en
if err != nil {
return nil, err
}
wheres := map[string]interface{}{
wheres := map[string]any{
"exchange_name_id": exchangeUUID,
"asset": strings.ToLower(assetType),
"base": strings.ToUpper(base),
@@ -351,7 +351,7 @@ func getInRangePostgres(exchangeName, assetType, base, quote string, startDate,
if err != nil {
return nil, err
}
wheres := map[string]interface{}{
wheres := map[string]any{
"exchange_name_id": exchangeUUID,
"asset": strings.ToLower(assetType),
"base": strings.ToUpper(base),
@@ -414,7 +414,7 @@ func DeleteTrades(trades ...Data) error {
}
func deleteTradesSQLite(ctx context.Context, tx *sql.Tx, trades ...Data) error {
tradeIDs := make([]interface{}, len(trades))
tradeIDs := make([]any, len(trades))
for i := range trades {
tradeIDs[i] = trades[i].ID
}
@@ -424,7 +424,7 @@ func deleteTradesSQLite(ctx context.Context, tx *sql.Tx, trades ...Data) error {
}
func deleteTradesPostgres(ctx context.Context, tx *sql.Tx, trades ...Data) error {
tradeIDs := make([]interface{}, len(trades))
tradeIDs := make([]any, len(trades))
for i := range trades {
tradeIDs[i] = trades[i].ID
}
@@ -433,7 +433,7 @@ func deleteTradesPostgres(ctx context.Context, tx *sql.Tx, trades ...Data) error
return err
}
func generateQuery(clauses map[string]interface{}, start, end time.Time, isSQLite bool) []qm.QueryMod {
func generateQuery(clauses map[string]any, start, end time.Time, isSQLite bool) []qm.QueryMod {
query := []qm.QueryMod{
qm.OrderBy("timestamp"),
}

View File

@@ -276,7 +276,7 @@ func generateWhereQuery(columns, id []string, limit int) []qm.QueryMod {
return queries
}
func generateWhereBetweenQuery(column string, start, end interface{}, limit int) []qm.QueryMod {
func generateWhereBetweenQuery(column string, start, end any, limit int) []qm.QueryMod {
return []qm.QueryMod{
qm.Limit(limit),
qm.Where(column+" BETWEEN ? AND ?", start, end),

View File

@@ -60,7 +60,7 @@ func TestWithdraw(t *testing.T) {
config *database.Config
runner func(t *testing.T)
closer func(dbConn *database.Instance) error
output interface{}
output any
}{
{
"SQLite-Write",

View File

@@ -35,7 +35,7 @@ func TestDatabaseConnect(t *testing.T) {
name string
config *database.Config
closer func(dbConn *database.Instance) error
output interface{}
output any
}{
{
"SQLite",

View File

@@ -39,16 +39,16 @@ func init() {
// NewDispatcher creates a new Dispatcher for relaying data.
func NewDispatcher() *Dispatcher {
return &Dispatcher{
routes: make(map[uuid.UUID][]chan interface{}),
routes: make(map[uuid.UUID][]chan any),
outbound: sync.Pool{
New: getChan,
},
}
}
func getChan() interface{} {
func getChan() any {
// Create unbuffered channel for data pass
return make(chan interface{})
return make(chan any)
}
// Start starts the dispatch system by spawning workers and allocating memory
@@ -202,7 +202,7 @@ func (d *Dispatcher) relayer() {
}
// publish relays data to the subscribed subsystems
func (d *Dispatcher) publish(id uuid.UUID, data interface{}) error {
func (d *Dispatcher) publish(id uuid.UUID, data any) error {
if d == nil {
return errDispatcherNotInitialized
}
@@ -235,7 +235,7 @@ func (d *Dispatcher) publish(id uuid.UUID, data interface{}) error {
// Subscribe subscribes a system and returns a communication chan, this does not
// ensure initial push.
func (d *Dispatcher) subscribe(id uuid.UUID) (chan interface{}, error) {
func (d *Dispatcher) subscribe(id uuid.UUID) (chan any, error) {
if d == nil {
return nil, errDispatcherNotInitialized
}
@@ -258,7 +258,7 @@ func (d *Dispatcher) subscribe(id uuid.UUID) (chan interface{}, error) {
}
// Get an unused channel from the channel pool
ch, ok := d.outbound.Get().(chan interface{})
ch, ok := d.outbound.Get().(chan any)
if !ok {
return nil, errTypeAssertionFailure
}
@@ -269,7 +269,7 @@ func (d *Dispatcher) subscribe(id uuid.UUID) (chan interface{}, error) {
}
// Unsubscribe unsubs a routine from the dispatcher
func (d *Dispatcher) unsubscribe(id uuid.UUID, usedChan chan interface{}) error {
func (d *Dispatcher) unsubscribe(id uuid.UUID, usedChan chan any) error {
if d == nil {
return errDispatcherNotInitialized
}

View File

@@ -93,7 +93,7 @@ func TestSubscribe(t *testing.T) {
_, err = d.subscribe(nonEmptyUUID)
assert.ErrorIs(t, err, errDispatcherUUIDNotFoundInRouteList, "subscribe should error correctly")
d.outbound.New = func() interface{} { return "omg" }
d.outbound.New = func() any { return "omg" }
_, err = d.subscribe(id)
assert.ErrorIs(t, err, errTypeAssertionFailure, "subscribe should error correctly")
@@ -119,19 +119,19 @@ func TestUnsubscribe(t *testing.T) {
assert.ErrorIs(t, err, errChannelIsNil, "unsubscribe should error correctly")
// will return nil if not running
err = d.unsubscribe(nonEmptyUUID, make(chan interface{}))
err = d.unsubscribe(nonEmptyUUID, make(chan any))
assert.NoError(t, err, "unsubscribe should not error")
err = d.start(0, 0)
require.NoError(t, err, "start should not error")
err = d.unsubscribe(nonEmptyUUID, make(chan interface{}))
err = d.unsubscribe(nonEmptyUUID, make(chan any))
assert.ErrorIs(t, err, errDispatcherUUIDNotFoundInRouteList, "unsubscribe should error correctly")
id, err := d.getNewID(uuid.NewV4)
require.NoError(t, err, "getNewID should not error")
err = d.unsubscribe(id, make(chan interface{}))
err = d.unsubscribe(id, make(chan any))
assert.ErrorIs(t, err, errChannelNotFoundInUUIDRef, "unsubscribe should error correctly")
ch, err := d.subscribe(id)
@@ -169,8 +169,8 @@ func TestPublish(t *testing.T) {
assert.ErrorIs(t, err, errNoData, "publish should error correctly")
// demonstrate job limit error
d.routes[nonEmptyUUID] = []chan interface{}{
make(chan interface{}),
d.routes[nonEmptyUUID] = []chan any{
make(chan any),
}
for range 200 {
if err = d.publish(nonEmptyUUID, "test"); err != nil {

View File

@@ -28,7 +28,7 @@ type Dispatcher struct {
// channels, a relayer will be given a unique id through its job channel,
// then publish the data across the full registered channels for that uuid.
// See relayer() method below.
routes map[uuid.UUID][]chan interface{}
routes map[uuid.UUID][]chan any
// routesMtx protects the routes variable ensuring acceptable read/write access
routesMtx sync.Mutex
@@ -61,7 +61,7 @@ type Dispatcher struct {
// job defines a relaying job associated with a ticket which allows routing to
// routines that require specific data
type job struct {
Data interface{}
Data any
ID uuid.UUID
}
@@ -75,7 +75,7 @@ type Mux struct {
// Pipe defines an outbound object to the desired routine
type Pipe struct {
// Channel to get all our lovely information
c chan interface{}
c chan any
// ID to tracked system
id uuid.UUID
// Reference to multiplexer

View File

@@ -43,7 +43,7 @@ func (m *Mux) Subscribe(id uuid.UUID) (Pipe, error) {
}
// Unsubscribe returns channel to the pool for the full signature set
func (m *Mux) Unsubscribe(id uuid.UUID, ch chan interface{}) error {
func (m *Mux) Unsubscribe(id uuid.UUID, ch chan any) error {
if m == nil {
return errMuxIsNil
}
@@ -52,7 +52,7 @@ func (m *Mux) Unsubscribe(id uuid.UUID, ch chan interface{}) error {
// Publish takes in a persistent memory address and dispatches changes to
// required pipes.
func (m *Mux) Publish(data interface{}, ids ...uuid.UUID) error {
func (m *Mux) Publish(data any, ids ...uuid.UUID) error {
if m == nil {
return errMuxIsNil
}
@@ -91,6 +91,6 @@ func (p *Pipe) Release() error {
}
// Channel returns the Pipe's channel
func (p *Pipe) Channel() <-chan interface{} {
func (p *Pipe) Channel() <-chan any {
return p.c
}

View File

@@ -309,7 +309,7 @@ This will generate a readme file for the exchange which can be found in the new
```go
// SendHTTPRequest sends an unauthenticated HTTP request
func (f *FTX) SendHTTPRequest(ctx context.Context, path string, result interface{}) error {
func (f *FTX) SendHTTPRequest(ctx context.Context, path string, result any) error {
// This is used to generate the *http.Request, used in conjunction with the
// generate functionality below.
item := &request.Item{
@@ -414,7 +414,7 @@ Ensure each endpoint is implemented and has an associated test to improve test c
Authenticated request function is created based on the way the exchange documentation specifies: https://docs.ftx.com/#authentication
```go
// SendAuthHTTPRequest sends an authenticated request
func (f *FTX) SendAuthHTTPRequest(ctx context.Context, method, path string, data, result interface{}) error {
func (f *FTX) SendAuthHTTPRequest(ctx context.Context, method, path string, data, result any) error {
// A potential example below of closing over authenticated variables which may
// be required to regenerate on every request between each attempt after rate
// limiting. This is for when signatures are based on timestamps/nonces that are
@@ -553,12 +553,12 @@ type PlaceOrder struct {
}
```
For `POST` or `DELETE` requests, params are sent through a map[string]interface{}:
For `POST` or `DELETE` requests, params are sent through a map[string]any:
```go
// Order places an order
func (f *FTX) Order(ctx context.Context, marketName, side, orderType, reduceOnly, ioc, postOnly, clientID string, price, size float64) (PlaceOrder, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["market"] = marketName
req["side"] = side
req["price"] = price
@@ -863,14 +863,14 @@ type WsResponseData struct {
ResponseType string `json:"type"`
Channel string `json:"channel"`
Market string `json:"market"`
Data interface{} `json:"data"`
Data any `json:"data"`
}
```
- Unmarshall the raw data into the main type:
```go
var result map[string]interface{}
var result map[string]any
err := json.Unmarshal(respRaw, &result)
if err != nil {
return err

View File

@@ -7,6 +7,6 @@ import "testing"
func BenchmarkUnmarshal(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
_ = Unmarshal([]byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`), &map[string]interface{}{})
_ = Unmarshal([]byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`), &map[string]any{})
}
}

View File

@@ -207,7 +207,7 @@ func restLogger(inner http.Handler, name string) http.Handler {
}
// writeResponse outputs a JSON response of the response interface
func writeResponse(w http.ResponseWriter, response interface{}) error {
func writeResponse(w http.ResponseWriter, response any) error {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
return json.NewEncoder(w).Encode(response)
@@ -466,7 +466,7 @@ func (h *websocketHub) run() {
}
// SendWebsocketMessage sends a websocket event to the client
func (c *websocketClient) SendWebsocketMessage(evt interface{}) error {
func (c *websocketClient) SendWebsocketMessage(evt any) error {
data, err := json.Marshal(evt)
if err != nil {
log.Errorf(log.APIServerMgr, "websocket: failed to send message: %s\n", err)
@@ -667,7 +667,7 @@ func (m *apiServerManager) WebsocketClientHandler(w http.ResponseWriter, r *http
go client.write()
}
func wsAuth(client *websocketClient, data interface{}) error {
func wsAuth(client *websocketClient, data any) error {
d, ok := data.([]byte)
if !ok {
return common.GetTypeAssertError("[]byte", data)
@@ -722,7 +722,7 @@ func wsAuth(client *websocketClient, data interface{}) error {
return nil
}
func wsGetConfig(client *websocketClient, _ interface{}) error {
func wsGetConfig(client *websocketClient, _ any) error {
wsResp := WebsocketEventResponse{
Event: "GetConfig",
Data: config.GetConfig(),
@@ -730,7 +730,7 @@ func wsGetConfig(client *websocketClient, _ interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsSaveConfig(client *websocketClient, data interface{}) error {
func wsSaveConfig(client *websocketClient, data any) error {
d, ok := data.([]byte)
if !ok {
return common.GetTypeAssertError("[]byte", data)
@@ -774,7 +774,7 @@ func wsSaveConfig(client *websocketClient, data interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetAccountInfo(client *websocketClient, _ interface{}) error {
func wsGetAccountInfo(client *websocketClient, _ any) error {
accountInfo := getAllActiveAccounts(client.exchangeManager)
wsResp := WebsocketEventResponse{
Event: "GetAccountInfo",
@@ -783,7 +783,7 @@ func wsGetAccountInfo(client *websocketClient, _ interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetTickers(client *websocketClient, _ interface{}) error {
func wsGetTickers(client *websocketClient, _ any) error {
wsResp := WebsocketEventResponse{
Event: "GetTickers",
}
@@ -791,7 +791,7 @@ func wsGetTickers(client *websocketClient, _ interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetTicker(client *websocketClient, data interface{}) error {
func wsGetTicker(client *websocketClient, data any) error {
d, ok := data.([]byte)
if !ok {
return common.GetTypeAssertError("[]byte", data)
@@ -843,7 +843,7 @@ func wsGetTicker(client *websocketClient, data interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetOrderbooks(client *websocketClient, _ interface{}) error {
func wsGetOrderbooks(client *websocketClient, _ any) error {
wsResp := WebsocketEventResponse{
Event: "GetOrderbooks",
}
@@ -851,7 +851,7 @@ func wsGetOrderbooks(client *websocketClient, _ interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetOrderbook(client *websocketClient, data interface{}) error {
func wsGetOrderbook(client *websocketClient, data any) error {
d, ok := data.([]byte)
if !ok {
return common.GetTypeAssertError("[]byte", data)
@@ -897,7 +897,7 @@ func wsGetOrderbook(client *websocketClient, data interface{}) error {
return client.SendWebsocketMessage(WebsocketEventResponse{Event: "GetOrderbook", Data: ob})
}
func wsGetExchangeRates(client *websocketClient, _ interface{}) error {
func wsGetExchangeRates(client *websocketClient, _ any) error {
wsResp := WebsocketEventResponse{
Event: "GetExchangeRates",
}
@@ -911,7 +911,7 @@ func wsGetExchangeRates(client *websocketClient, _ interface{}) error {
return client.SendWebsocketMessage(wsResp)
}
func wsGetPortfolio(client *websocketClient, _ interface{}) error {
func wsGetPortfolio(client *websocketClient, _ any) error {
wsResp := WebsocketEventResponse{
Event: "GetPortfolio",
}

View File

@@ -243,7 +243,7 @@ func TestGetAllActiveAccounts(t *testing.T) {
}
}
func makeHTTPGetRequest(t *testing.T, response interface{}) *http.Response {
func makeHTTPGetRequest(t *testing.T, response any) *http.Response {
t.Helper()
w := httptest.NewRecorder()

View File

@@ -88,14 +88,14 @@ type WebsocketEvent struct {
Exchange string `json:"exchange,omitempty"`
AssetType string `json:"assetType,omitempty"`
Event string
Data interface{}
Data any
}
// WebsocketEventResponse is the struct used for websocket event responses
type WebsocketEventResponse struct {
Event string `json:"event"`
Data interface{} `json:"data"`
Error string `json:"error"`
Event string `json:"event"`
Data any `json:"data"`
Error string `json:"error"`
}
// WebsocketOrderbookTickerRequest is a struct used for ticker and orderbook
@@ -164,5 +164,5 @@ var wsHandlers = map[string]wsCommandHandler{
type wsCommandHandler struct {
authRequired bool
handler func(client *websocketClient, data interface{}) error
handler func(client *websocketClient, data any) error
}

View File

@@ -3,6 +3,8 @@ package engine
import (
"errors"
"fmt"
"maps"
"slices"
"strings"
"sync"
@@ -97,9 +99,9 @@ func (m *DepositAddressManager) GetDepositAddressesByExchange(exchName string) (
return nil, ErrDepositAddressNotFound
}
cpy := make(map[string][]deposit.Address, len(r))
for k, v := range r {
cpy[k] = v
cpy := maps.Clone(r)
for k, v := range cpy {
cpy[k] = slices.Clone(v)
}
return cpy, nil
}

View File

@@ -327,7 +327,7 @@ func TestRegisterWebsocketDataHandler(t *testing.T) {
}
e = &Engine{WebsocketRoutineManager: &WebsocketRoutineManager{}}
err = e.RegisterWebsocketDataHandler(func(_ string, _ interface{}) error { return nil }, false)
err = e.RegisterWebsocketDataHandler(func(_ string, _ any) error { return nil }, false)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}

View File

@@ -3,6 +3,7 @@ package engine
import (
"errors"
"fmt"
"slices"
"strings"
"sync/atomic"
"time"
@@ -147,7 +148,7 @@ func (m *eventManager) Remove(eventID int64) bool {
defer m.m.Unlock()
for i := range m.events {
if m.events[i].ID == eventID {
m.events = append(m.events[:i], m.events[i+1:]...)
m.events = slices.Delete(m.events, i, i+1)
return true
}
}

View File

@@ -2542,7 +2542,7 @@ func (s *RPCServer) GCTScriptStatus(_ context.Context, _ *gctrpc.GCTScriptStatus
Status: fmt.Sprintf("%v of %v virtual machines running", gctscript.VMSCount.Len(), s.gctScriptManager.GetMaxVirtualMachines()),
}
gctscript.AllVMSync.Range(func(_, v interface{}) bool {
gctscript.AllVMSync.Range(func(_, v any) bool {
vm, ok := v.(*gctscript.VM)
if !ok {
log.Errorf(log.GRPCSys, "%v", common.GetTypeAssertError("*gctscript.VM", v))

View File

@@ -1216,8 +1216,8 @@ func (d *dummyServer) SetHeader(metadata.MD) error { return nil }
func (d *dummyServer) SendHeader(metadata.MD) error { return nil }
func (d *dummyServer) SetTrailer(metadata.MD) {}
func (d *dummyServer) Context() context.Context { return context.Background() }
func (d *dummyServer) SendMsg(_ interface{}) error { return nil }
func (d *dummyServer) RecvMsg(_ interface{}) error { return nil }
func (d *dummyServer) SendMsg(_ any) error { return nil }
func (d *dummyServer) RecvMsg(_ any) error { return nil }
func TestGetHistoricTrades(t *testing.T) {
engerino := RPCTestSetup(t)

View File

@@ -30,6 +30,7 @@ const (
SyncItemOrderbook
SyncItemTrade
SyncManagerName = "exchange_syncer"
minSyncInterval = time.Second
)
var (
@@ -452,10 +453,7 @@ func (m *SyncManager) worker() {
}
defer cleanup()
interval := greatestCommonDivisor(m.config.TimeoutWebsocket, m.config.TimeoutREST)
if interval > time.Second {
interval = time.Second
}
interval := min(greatestCommonDivisor(m.config.TimeoutWebsocket, m.config.TimeoutREST), minSyncInterval)
t := time.NewTicker(interval)
for {
@@ -905,7 +903,7 @@ func (m *SyncManager) WaitForInitialSync() error {
return nil
}
func relayWebsocketEvent(result interface{}, event, assetType, exchangeName string) {
func relayWebsocketEvent(result any, event, assetType, exchangeName string) {
evt := WebsocketEvent{
Data: result,
Event: event,

View File

@@ -194,7 +194,7 @@ func (m *WebsocketRoutineManager) websocketDataReceiver(ws *stream.Websocket) er
// websocketDataHandler is the default central point for exchange websocket
// implementations to send processed data which will then pass that to an
// appropriate handler.
func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data interface{}) error {
func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data any) error {
switch d := data.(type) {
case string:
log.Infoln(log.WebsocketMgr, d)

View File

@@ -275,8 +275,8 @@ func TestRegisterWebsocketDataHandlerWithFunctionality(t *testing.T) {
}
// externally defined capture device
dataChan := make(chan interface{})
fn := func(_ string, data interface{}) error {
dataChan := make(chan any)
fn := func(_ string, data any) error {
switch data.(type) {
case string:
dataChan <- data
@@ -295,7 +295,7 @@ func TestRegisterWebsocketDataHandlerWithFunctionality(t *testing.T) {
}
mock := stream.NewWebsocket()
mock.ToRoutine = make(chan interface{})
mock.ToRoutine = make(chan any)
m.state = readyState
err = m.websocketDataReceiver(mock)
if err != nil {

View File

@@ -39,4 +39,4 @@ type WebsocketRoutineManager struct {
// WebsocketDataHandler defines a function signature for a function that handles
// data coming from websocket connections.
type WebsocketDataHandler func(service string, incoming interface{}) error
type WebsocketDataHandler func(service string, incoming any) error

View File

@@ -21,7 +21,7 @@ const (
var (
// pool is a silent shared pool between all notice instances for alerting
// external routines waiting on a state change.
pool = sync.Pool{New: func() interface{} { return make(chan bool) }}
pool = sync.Pool{New: func() any { return make(chan bool) }}
preAllocBufferSize = PreAllocCommsDefaultBuffer
mu sync.RWMutex

View File

@@ -50,7 +50,7 @@ type Alphapoint struct {
// GetTicker returns current ticker information from Alphapoint for a selected
// currency pair ie "BTCUSD"
func (a *Alphapoint) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["productPair"] = currencyPair
response := Ticker{}
@@ -76,7 +76,7 @@ func (a *Alphapoint) GetTicker(ctx context.Context, currencyPair string) (Ticker
// 0 (default: 0)
// Count: specifies the number of trades to return (default: 10)
func (a *Alphapoint) GetTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = currencyPair
req["startIndex"] = startIndex
req["Count"] = count
@@ -98,7 +98,7 @@ func (a *Alphapoint) GetTrades(ctx context.Context, currencyPair string, startIn
// StartDate - specifies the starting time in epoch time, type is long
// EndDate - specifies the end time in epoch time, type is long
func (a *Alphapoint) GetTradesByDate(ctx context.Context, currencyPair string, startDate, endDate int64) (Trades, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = currencyPair
req["startDate"] = startDate
req["endDate"] = endDate
@@ -122,7 +122,7 @@ func (a *Alphapoint) GetTradesByDate(ctx context.Context, currencyPair string, s
// GetOrderbook fetches the current orderbook for a given currency pair
// CurrencyPair - trade pair (ex: “BTCUSD”)
func (a *Alphapoint) GetOrderbook(ctx context.Context, currencyPair string) (Orderbook, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["productPair"] = currencyPair
response := Orderbook{}
@@ -180,7 +180,7 @@ func (a *Alphapoint) CreateAccount(ctx context.Context, firstName, lastName, ema
)
}
req := make(map[string]interface{})
req := make(map[string]any)
req["firstname"] = firstName
req["lastname"] = lastName
req["email"] = email
@@ -207,7 +207,7 @@ func (a *Alphapoint) GetUserInfo(ctx context.Context) (UserInfo, error) {
exchange.RestSpot,
http.MethodPost,
alphapointUserInfo,
map[string]interface{}{},
map[string]any{},
&response)
if err != nil {
return UserInfo{}, err
@@ -257,7 +257,7 @@ func (a *Alphapoint) SetUserInfo(ctx context.Context, firstName, lastName, cell2
},
}
req := make(map[string]interface{})
req := make(map[string]any)
req["userInfoKVP"] = userInfoKVPs
err := a.SendAuthenticatedHTTPRequest(ctx,
@@ -284,7 +284,7 @@ func (a *Alphapoint) GetAccountInformation(ctx context.Context) (AccountInfo, er
exchange.RestSpot,
http.MethodPost,
alphapointAccountInfo,
map[string]interface{}{},
map[string]any{},
&response,
)
if err != nil {
@@ -301,7 +301,7 @@ func (a *Alphapoint) GetAccountInformation(ctx context.Context) (AccountInfo, er
// StartIndex - Starting index, if less than 0 then start from the beginning
// Count - Returns last trade, (Default: 30)
func (a *Alphapoint) GetAccountTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = currencyPair
req["startIndex"] = startIndex
req["count"] = count
@@ -331,7 +331,7 @@ func (a *Alphapoint) GetDepositAddresses(ctx context.Context) ([]DepositAddresse
exchange.RestSpot,
http.MethodPost,
alphapointDepositAddresses,
map[string]interface{}{},
map[string]any{},
&response,
)
if err != nil {
@@ -349,7 +349,7 @@ func (a *Alphapoint) GetDepositAddresses(ctx context.Context) ([]DepositAddresse
// amount - Amount (ex: “.011”)
// address - Withdraw address
func (a *Alphapoint) WithdrawCoins(ctx context.Context, symbol, product, address string, amount float64) error {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = symbol
req["product"] = product
req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64)
@@ -388,7 +388,7 @@ func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderT
// price - Price in USD
func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType string, quantity, price float64) (int64, error) {
orderTypeNumber := a.convertOrderTypeToOrderTypeNumber(orderType)
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = symbol
req["side"] = side
req["orderType"] = orderTypeNumber
@@ -421,7 +421,7 @@ func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType st
// be modified to the lowest ask price. “1” means "Execute now", which will
// convert a limit order into a market order.
func (a *Alphapoint) ModifyExistingOrder(ctx context.Context, symbol string, orderID, action int64) (int64, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = symbol
req["serverOrderId"] = orderID
req["modifyAction"] = action
@@ -447,7 +447,7 @@ func (a *Alphapoint) ModifyExistingOrder(ctx context.Context, symbol string, ord
// symbol - Instrument code (ex: “BTCUSD”)
// OrderID - Order id (ex: 1000)
func (a *Alphapoint) CancelExistingOrder(ctx context.Context, orderID int64, omsid string) (int64, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["OrderId"] = orderID
req["OMSId"] = omsid
response := Response{}
@@ -471,7 +471,7 @@ func (a *Alphapoint) CancelExistingOrder(ctx context.Context, orderID int64, oms
// CancelAllExistingOrders cancels all open orders by symbol.
// symbol - Instrument code (ex: “BTCUSD”)
func (a *Alphapoint) CancelAllExistingOrders(ctx context.Context, omsid string) error {
req := make(map[string]interface{})
req := make(map[string]any)
req["OMSId"] = omsid
response := Response{}
@@ -499,7 +499,7 @@ func (a *Alphapoint) GetOrders(ctx context.Context) ([]OpenOrders, error) {
exchange.RestSpot,
http.MethodPost,
alphapointOpenOrders,
map[string]interface{}{},
map[string]any{},
&response,
)
if err != nil {
@@ -517,7 +517,7 @@ func (a *Alphapoint) GetOrders(ctx context.Context) ([]OpenOrders, error) {
// quantity - Quantity
// price - Price in USD
func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quantity, price float64) (float64, error) {
req := make(map[string]interface{})
req := make(map[string]any)
req["ins"] = symbol
req["side"] = side
req["qty"] = strconv.FormatFloat(quantity, 'f', -1, 64)
@@ -541,7 +541,7 @@ func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quant
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (a *Alphapoint) SendHTTPRequest(_ context.Context, ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error {
func (a *Alphapoint) SendHTTPRequest(_ context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error {
endpoint, err := a.API.Endpoints.GetURL(ep)
if err != nil {
return err
@@ -572,7 +572,7 @@ func (a *Alphapoint) SendHTTPRequest(_ context.Context, ep exchange.URL, method,
}
// SendAuthenticatedHTTPRequest sends an authenticated request
func (a *Alphapoint) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error {
func (a *Alphapoint) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]any, result any) error {
creds, err := a.GetCredentials(ctx)
if err != nil {
return err

View File

@@ -3,6 +3,7 @@ package asset
import (
"errors"
"fmt"
"slices"
"strings"
"github.com/thrasher-corp/gocryptotrader/encoding/json"
@@ -144,14 +145,7 @@ func (a Items) Strings() []string {
// Contains returns whether or not the supplied asset exists
// in the list of Items
func (a Items) Contains(i Item) bool {
if i.IsValid() {
for x := range a {
if a[x] == i {
return true
}
}
}
return false
return slices.Contains(a, i)
}
// JoinToString joins an asset type array and converts it to a string

View File

@@ -26,9 +26,7 @@ import (
// Binance is the overarching type across the Binance package
type Binance struct {
exchange.Base
// Valid string list that is required by the exchange
validLimits []int
obm *orderbookManager
obm *orderbookManager
}
const (
@@ -124,10 +122,6 @@ func (b *Binance) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) {
// symbol: string of currency pair
// limit: returned limit amount
func (b *Binance) GetOrderBook(ctx context.Context, obd OrderBookDataRequestParams) (*OrderBook, error) {
if err := b.CheckLimit(obd.Limit); err != nil {
return nil, err
}
params := url.Values{}
symbol, err := b.FormatSymbol(obd.Symbol, asset.Spot)
if err != nil {
@@ -406,7 +400,7 @@ func (b *Binance) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([
}
path := candleStick + "?" + params.Encode()
var resp interface{}
var resp any
err = b.SendHTTPRequest(ctx,
exchange.RestSpotSupplementary,
@@ -416,16 +410,16 @@ func (b *Binance) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([
if err != nil {
return nil, err
}
responseData, ok := resp.([]interface{})
responseData, ok := resp.([]any)
if !ok {
return nil, common.GetTypeAssertError("[]interface{}", resp)
return nil, common.GetTypeAssertError("[]any", resp)
}
klineData := make([]CandleStick, len(responseData))
for x := range responseData {
individualData, ok := responseData[x].([]interface{})
individualData, ok := responseData[x].([]any)
if !ok {
return nil, common.GetTypeAssertError("[]interface{}", responseData[x])
return nil, common.GetTypeAssertError("[]any", responseData[x])
}
if len(individualData) != 12 {
return nil, errors.New("unexpected kline data length")
@@ -796,7 +790,7 @@ func (b *Binance) GetMarginAccount(ctx context.Context) (*MarginAccount, error)
}
// SendHTTPRequest sends an unauthenticated request
func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error {
func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error {
endpointPath, err := b.API.Endpoints.GetURL(ePath)
if err != nil {
return err
@@ -817,7 +811,7 @@ func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path
// SendAPIKeyHTTPRequest is a special API request where the api key is
// appended to the headers without a secret
func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error {
func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result any) error {
endpointPath, err := b.API.Endpoints.GetURL(ePath)
if err != nil {
return err
@@ -846,7 +840,7 @@ func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL,
}
// SendAuthHTTPRequest sends an authenticated HTTP request
func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result interface{}) error {
func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result any) error {
creds, err := b.GetCredentials(ctx)
if err != nil {
return err
@@ -912,21 +906,6 @@ func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, m
return json.Unmarshal(interim, result)
}
// CheckLimit checks value against a variable list
func (b *Binance) CheckLimit(limit int) error {
for x := range b.validLimits {
if b.validLimits[x] == limit {
return nil
}
}
return errors.New("incorrect limit values - valid values are 5, 10, 20, 50, 100, 500, 1000")
}
// SetValues sets the default valid values
func (b *Binance) SetValues() {
b.validLimits = []int{5, 10, 20, 50, 100, 500, 1000, 5000}
}
// GetFee returns an estimate of fee based on type of transaction
func (b *Binance) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) {
var fee float64

View File

@@ -268,7 +268,7 @@ func (b *Binance) GetFuturesKlineData(ctx context.Context, symbol currency.Pair,
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
var data [][10]interface{}
var data [][10]any
rateBudget := getKlineRateBudget(limit)
err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesKlineData+params.Encode(), rateBudget, &data)
if err != nil {
@@ -388,7 +388,7 @@ func (b *Binance) GetContinuousKlineData(ctx context.Context, pair, contractType
}
rateBudget := getKlineRateBudget(limit)
var data [][10]interface{}
var data [][10]any
err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesContinuousKline+params.Encode(), rateBudget, &data)
if err != nil {
return nil, err
@@ -503,7 +503,7 @@ func (b *Binance) GetIndexPriceKlines(ctx context.Context, pair, interval string
}
rateBudget := getKlineRateBudget(limit)
var data [][10]interface{}
var data [][10]any
err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesIndexKline+params.Encode(), rateBudget, &data)
if err != nil {
return nil, err
@@ -621,7 +621,7 @@ func (b *Binance) GetMarkPriceKline(ctx context.Context, symbol currency.Pair, i
params.Set("endTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
var data [][10]interface{}
var data [][10]any
rateBudget := getKlineRateBudget(limit)
err = b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPriceKline+params.Encode(), rateBudget, &data)
if err != nil {

View File

@@ -18,7 +18,6 @@ import (
var mockTests = false
func TestMain(m *testing.M) {
b = new(Binance)
if err := testexch.Setup(b); err != nil {
log.Fatal(err)

View File

@@ -1969,8 +1969,7 @@ func BenchmarkWsHandleData(bb *testing.B) {
<-b.Websocket.DataHandler
}
}()
bb.ResetTimer()
for range bb.N {
for bb.Loop() {
for x := range lines {
assert.NoError(bb, b.wsHandleData(lines[x]))
}
@@ -1990,7 +1989,7 @@ func TestSubscribe(t *testing.T) {
var req WsPayload
require.NoError(tb, json.Unmarshal(msg, &req), "Unmarshal should not error")
require.ElementsMatch(tb, req.Params, exp, "Params should have correct channels")
return w.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf(`{"result":null,"id":%d}`, req.ID)))
return w.WriteMessage(websocket.TextMessage, fmt.Appendf(nil, `{"result":null,"id":%d}`, req.ID))
}
b = testexch.MockWsInstance[Binance](t, mockws.CurryWsMockUpgrader(t, mock))
} else {
@@ -2012,7 +2011,7 @@ func TestSubscribeBadResp(t *testing.T) {
var req WsPayload
err := json.Unmarshal(msg, &req)
require.NoError(tb, err, "Unmarshal should not error")
return w.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf(`{"result":{"error":"carrots"},"id":%d}`, req.ID)))
return w.WriteMessage(websocket.TextMessage, fmt.Appendf(nil, `{"result":{"error":"carrots"},"id":%d}`, req.ID))
}
b := testexch.MockWsInstance[Binance](t, mockws.CurryWsMockUpgrader(t, mock)) //nolint:govet // Intentional shadow to avoid future copy/paste mistakes
err := b.Subscribe(channels)

View File

@@ -47,7 +47,7 @@ type ExchangeInfo struct {
Interval string `json:"interval"`
Limit int `json:"limit"`
} `json:"rateLimits"`
ExchangeFilters interface{} `json:"exchangeFilters"`
ExchangeFilters any `json:"exchangeFilters"`
Symbols []*struct {
Symbol string `json:"symbol"`
Status string `json:"status"`
@@ -125,7 +125,7 @@ type CoinInfo struct {
// OrderBookDataRequestParams represents Klines request data.
type OrderBookDataRequestParams struct {
Symbol currency.Pair `json:"symbol"` // Required field; example LTCBTC,BTCUSDT
Limit int `json:"limit"` // Default 100; max 1000. Valid limits:[5, 10, 20, 50, 100, 500, 1000]
Limit int `json:"limit"` // Default 100; max 5000. If limit > 5000, then the response will truncate to 5000
}
// OrderbookItem stores an individual orderbook item
@@ -157,7 +157,7 @@ type OrderBook struct {
type DepthUpdateParams []struct {
PriceLevel float64
Quantity float64
ignore []interface{}
ignore []any
}
// WebsocketDepthStream is the difference for the update depth stream

View File

@@ -177,8 +177,8 @@ func (b *Binance) URecentTrades(ctx context.Context, symbol currency.Pair, fromI
}
// UFuturesHistoricalTrades gets historical public trades for USDTMarginedFutures
func (b *Binance) UFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]interface{}, error) {
var resp []interface{}
func (b *Binance) UFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]any, error) {
var resp []any
params := url.Values{}
symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures)
if err != nil {
@@ -253,7 +253,7 @@ func (b *Binance) UKlineData(ctx context.Context, symbol currency.Pair, interval
rateBudget = uFuturesKlineMaxRate
}
var data [][10]interface{}
var data [][10]any
err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesKlineData+params.Encode(), rateBudget, &data)
if err != nil {
return nil, err

View File

@@ -66,7 +66,6 @@ func (b *Binance) SetDefaults() {
b.Verbose = true
b.API.CredentialsValidator.RequiresKey = true
b.API.CredentialsValidator.RequiresSecret = true
b.SetValues()
for a, ps := range defaultAssetPairStores {
if err := b.SetAssetPairStore(a, ps); err != nil {

View File

@@ -623,7 +623,7 @@ type UFuturesSymbolInfo struct {
// CExchangeInfo stores exchange info for cfutures
type CExchangeInfo struct {
ExchangeFilters []interface{} `json:"exchangeFilters"`
ExchangeFilters []any `json:"exchangeFilters"`
RateLimits []struct {
Interval string `json:"interval"`
IntervalNum int64 `json:"intervalNul"`

Some files were not shown because too many files have changed in this diff Show More