mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-29 15:10:37 +00:00
build/ci: Update Go to v1.24, golangci-lint to v1.64.6 and fix issues (#1804)
* build/ci: Update Go to v1.24, golangci-lint to v1.64.5 and fix issues * Address shazbert's nitters * linter/config: Fix new linter issue and use versionSize const * Address gk's nitters and fix additional linter issue after rebase * Address glorious nits * staticcheck: Fix additional linter issues after upgrading to Go 1.24.1 and golangci-lint v1.64.6 Also addresses nits * Improve testing, assertify usage and use common.ErrParsingWSField * TestCreateNewStrategy: Replace must > should wording
This commit is contained in:
@@ -346,12 +346,17 @@ func durationToWord(in Interval) string {
|
||||
}
|
||||
|
||||
// TotalCandlesPerInterval returns the total number of candle intervals between the start and end date
|
||||
func TotalCandlesPerInterval(start, end time.Time, interval Interval) int64 {
|
||||
func TotalCandlesPerInterval(start, end time.Time, interval Interval) uint64 {
|
||||
if interval <= 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
if start.After(end) {
|
||||
return 0
|
||||
}
|
||||
|
||||
window := end.Sub(start)
|
||||
return int64(window) / int64(interval)
|
||||
return uint64(window) / uint64(interval) //nolint:gosec // No overflow risk
|
||||
}
|
||||
|
||||
// IntervalsPerYear helps determine the number of intervals in a year
|
||||
@@ -461,7 +466,7 @@ func (k *Item) ConvertToNewInterval(newInterval Interval) (*Item, error) {
|
||||
// CalculateCandleDateRanges will calculate the expected candle data in intervals in a date range
|
||||
// If an API is limited in the amount of candles it can make in a request, it will automatically separate
|
||||
// ranges into the limit
|
||||
func CalculateCandleDateRanges(start, end time.Time, interval Interval, limit uint32) (*IntervalRangeHolder, error) {
|
||||
func CalculateCandleDateRanges(start, end time.Time, interval Interval, limit uint64) (*IntervalRangeHolder, error) {
|
||||
if err := common.StartEndTimeCheck(start, end); err != nil && !errors.Is(err, common.ErrStartAfterTimeNow) {
|
||||
return nil, err
|
||||
}
|
||||
@@ -471,44 +476,39 @@ func CalculateCandleDateRanges(start, end time.Time, interval Interval, limit ui
|
||||
|
||||
start = start.Round(interval.Duration())
|
||||
end = end.Round(interval.Duration())
|
||||
window := end.Sub(start)
|
||||
count := int64(window) / int64(interval)
|
||||
requests := float64(count) / float64(limit)
|
||||
|
||||
switch {
|
||||
case requests <= 1:
|
||||
requests = 1
|
||||
case limit == 0:
|
||||
requests, limit = 1, uint32(count)
|
||||
case requests-float64(int64(requests)) > 0:
|
||||
requests++
|
||||
count := uint64(end.Sub(start) / interval.Duration()) //nolint:gosec // No overflow risk
|
||||
if count == 0 {
|
||||
return nil, common.ErrStartEqualsEnd
|
||||
}
|
||||
|
||||
potentialRequests := make([]IntervalRange, int(requests))
|
||||
requestStart := start
|
||||
for x := range potentialRequests {
|
||||
potentialRequests[x].Start = CreateIntervalTime(requestStart)
|
||||
|
||||
count -= int64(limit)
|
||||
if count < 0 {
|
||||
potentialRequests[x].Intervals = make([]IntervalData, count+int64(limit))
|
||||
} else {
|
||||
potentialRequests[x].Intervals = make([]IntervalData, limit)
|
||||
}
|
||||
|
||||
for y := range potentialRequests[x].Intervals {
|
||||
potentialRequests[x].Intervals[y].Start = CreateIntervalTime(requestStart)
|
||||
requestStart = requestStart.Add(interval.Duration())
|
||||
potentialRequests[x].Intervals[y].End = CreateIntervalTime(requestStart)
|
||||
}
|
||||
potentialRequests[x].End = CreateIntervalTime(requestStart)
|
||||
intervals := make([]IntervalData, 0, count)
|
||||
for iStart := start; iStart.Before(end); iStart = iStart.Add(interval.Duration()) {
|
||||
intervals = append(intervals, IntervalData{
|
||||
Start: CreateIntervalTime(iStart),
|
||||
End: CreateIntervalTime(iStart.Add(interval.Duration())),
|
||||
})
|
||||
}
|
||||
return &IntervalRangeHolder{
|
||||
Start: CreateIntervalTime(start),
|
||||
End: CreateIntervalTime(requestStart),
|
||||
Ranges: potentialRequests,
|
||||
Limit: int(limit),
|
||||
}, nil
|
||||
|
||||
if limit == 0 {
|
||||
limit = count
|
||||
}
|
||||
|
||||
h := &IntervalRangeHolder{
|
||||
Start: CreateIntervalTime(start),
|
||||
End: CreateIntervalTime(end),
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
for _, b := range common.Batch(intervals, int(limit)) { //nolint:gosec // Ignore this warning as Batch requires int
|
||||
h.Ranges = append(h.Ranges, IntervalRange{
|
||||
Start: b[0].Start,
|
||||
End: b[len(b)-1].End,
|
||||
Intervals: b,
|
||||
})
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// HasDataAtDate determines whether a there is any data at a set
|
||||
@@ -653,7 +653,7 @@ func (k *Item) EqualSource(i *Item) error {
|
||||
func DeployExchangeIntervals(enabled ...IntervalCapacity) ExchangeIntervals {
|
||||
sort.Slice(enabled, func(i, j int) bool { return enabled[i].Interval < enabled[j].Interval })
|
||||
|
||||
supported := make(map[Interval]int64)
|
||||
supported := make(map[Interval]uint64)
|
||||
for x := range enabled {
|
||||
supported[enabled[x].Interval] = enabled[x].Capacity
|
||||
}
|
||||
@@ -693,7 +693,7 @@ func (e *ExchangeIntervals) Construct(required Interval) (Interval, error) {
|
||||
// GetIntervalResultLimit returns the maximum amount of candles that can be
|
||||
// returned for a specific interval. If the individual interval limit is not set,
|
||||
// it will be ignored and the global result limit will be returned.
|
||||
func (e *ExchangeCapabilitiesEnabled) GetIntervalResultLimit(interval Interval) (int64, error) {
|
||||
func (e *ExchangeCapabilitiesEnabled) GetIntervalResultLimit(interval Interval) (uint64, error) {
|
||||
if e == nil {
|
||||
return 0, errExchangeCapabilitiesEnabledIsNil
|
||||
}
|
||||
@@ -711,5 +711,5 @@ func (e *ExchangeCapabilitiesEnabled) GetIntervalResultLimit(interval Interval)
|
||||
return 0, fmt.Errorf("%w there is no global result limit set", errCannotFetchIntervalLimit)
|
||||
}
|
||||
|
||||
return int64(e.GlobalResultLimit), nil
|
||||
return e.GlobalResultLimit, nil
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/database"
|
||||
@@ -282,13 +283,17 @@ func TestDurationToWord(t *testing.T) {
|
||||
|
||||
func TestTotalCandlesPerInterval(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tmNow := time.Now()
|
||||
assert.Equal(t, uint64(0), TotalCandlesPerInterval(tmNow.AddDate(0, 0, 1), tmNow, OneMin))
|
||||
|
||||
start := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
end := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
interval Interval
|
||||
expected int64
|
||||
expected uint64
|
||||
}{
|
||||
{
|
||||
"FifteenSecond",
|
||||
@@ -413,65 +418,41 @@ func TestCalculateCandleDateRanges(t *testing.T) {
|
||||
pt := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
ft := time.Date(2222, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
et := time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC)
|
||||
nt := time.Time{}
|
||||
|
||||
_, err := CalculateCandleDateRanges(nt, nt, OneMin, 300)
|
||||
if !errors.Is(err, common.ErrDateUnset) {
|
||||
t.Errorf("received %v expected %v", err, common.ErrDateUnset)
|
||||
}
|
||||
_, err := CalculateCandleDateRanges(time.Time{}, time.Time{}, OneMin, 300)
|
||||
assert.ErrorIs(t, err, common.ErrDateUnset)
|
||||
|
||||
_, err = CalculateCandleDateRanges(et, pt, OneMin, 300)
|
||||
if !errors.Is(err, common.ErrStartAfterEnd) {
|
||||
t.Errorf("received %v expected %v", err, common.ErrStartAfterEnd)
|
||||
}
|
||||
assert.ErrorIs(t, err, common.ErrStartAfterEnd)
|
||||
|
||||
_, err = CalculateCandleDateRanges(et, ft, 0, 300)
|
||||
if !errors.Is(err, ErrInvalidInterval) {
|
||||
t.Errorf("received %v expected %v", err, ErrInvalidInterval)
|
||||
}
|
||||
assert.ErrorIs(t, err, ErrInvalidInterval)
|
||||
|
||||
_, err = CalculateCandleDateRanges(et, et, OneMin, 300)
|
||||
if !errors.Is(err, common.ErrStartEqualsEnd) {
|
||||
t.Errorf("received %v expected %v", err, common.ErrStartEqualsEnd)
|
||||
}
|
||||
assert.ErrorIs(t, err, common.ErrStartEqualsEnd)
|
||||
|
||||
v, err := CalculateCandleDateRanges(pt, et, OneWeek, 300)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
|
||||
if !v.Ranges[0].Start.Time.Equal(time.Unix(1546214400, 0)) {
|
||||
t.Errorf("expected %v received %v", 1546214400, v.Ranges[0].Start.Ticks)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1546214400), v.Ranges[0].Start.Ticks)
|
||||
|
||||
v, err = CalculateCandleDateRanges(pt, et, OneWeek, 100)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
if len(v.Ranges) != 1 {
|
||||
t.Fatalf("expected %v received %v", 1, len(v.Ranges))
|
||||
}
|
||||
if len(v.Ranges[0].Intervals) != 52 {
|
||||
t.Errorf("expected %v received %v", 52, len(v.Ranges[0].Intervals))
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, len(v.Ranges))
|
||||
assert.Equal(t, 52, len(v.Ranges[0].Intervals))
|
||||
|
||||
v, err = CalculateCandleDateRanges(et, ft, OneWeek, 5)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
if len(v.Ranges) != 2108 {
|
||||
t.Errorf("expected %v received %v", 2108, len(v.Ranges))
|
||||
}
|
||||
if len(v.Ranges[0].Intervals) != 5 {
|
||||
t.Errorf("expected %v received %v", 5, len(v.Ranges[0].Intervals))
|
||||
}
|
||||
if len(v.Ranges[1].Intervals) != 5 {
|
||||
t.Errorf("expected %v received %v", 5, len(v.Ranges[1].Intervals))
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2108, len(v.Ranges))
|
||||
assert.Equal(t, 5, len(v.Ranges[0].Intervals))
|
||||
lenRanges := len(v.Ranges) - 1
|
||||
lenIntervals := len(v.Ranges[lenRanges].Intervals) - 1
|
||||
if !v.Ranges[lenRanges].Intervals[lenIntervals].End.Equal(ft.Round(OneWeek.Duration())) {
|
||||
t.Errorf("expected %v received %v", ft.Round(OneDay.Duration()), v.Ranges[lenRanges].Intervals[lenIntervals].End)
|
||||
}
|
||||
assert.True(t, v.Ranges[lenRanges].Intervals[lenIntervals].End.Equal(ft.Round(OneWeek.Duration())))
|
||||
|
||||
start := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
end := start.Add(24 * time.Hour)
|
||||
v, err = CalculateCandleDateRanges(start, end, OneDay, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, uint64(1), v.Limit)
|
||||
}
|
||||
|
||||
func TestItem_SortCandlesByTimestamp(t *testing.T) {
|
||||
@@ -901,7 +882,7 @@ func BenchmarkJustifyIntervalTimeStoringUnixValues1(b *testing.B) {
|
||||
tt1 := time.Now()
|
||||
tt2 := time.Now().Add(-time.Hour)
|
||||
tt3 := time.Now().Add(time.Hour)
|
||||
for i := 0; i < b.N; i++ {
|
||||
for b.Loop() {
|
||||
if tt1.Unix() == tt2.Unix() || (tt1.Unix() > tt2.Unix() && tt1.Unix() < tt3.Unix()) {
|
||||
continue
|
||||
}
|
||||
@@ -916,7 +897,7 @@ func BenchmarkJustifyIntervalTimeStoringUnixValues2(b *testing.B) {
|
||||
tt1 := time.Now().Unix()
|
||||
tt2 := time.Now().Add(-time.Hour).Unix()
|
||||
tt3 := time.Now().Add(time.Hour).Unix()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for b.Loop() {
|
||||
if tt1 >= tt2 && tt1 <= tt3 {
|
||||
continue
|
||||
}
|
||||
@@ -1371,7 +1352,7 @@ func TestGetIntervalResultLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
e.Intervals = ExchangeIntervals{
|
||||
supported: map[Interval]int64{
|
||||
supported: map[Interval]uint64{
|
||||
OneDay: 100000,
|
||||
OneMin: 0,
|
||||
},
|
||||
|
||||
@@ -161,13 +161,13 @@ type ExchangeCapabilitiesEnabled struct {
|
||||
// across all intervals. This is used to determine if a request will exceed
|
||||
// the exchange limits. Indivudal interval limits are stored in the
|
||||
// ExchangeIntervals struct. If this is set to 0, it will be ignored.
|
||||
GlobalResultLimit uint32
|
||||
GlobalResultLimit uint64
|
||||
}
|
||||
|
||||
// ExchangeIntervals stores the supported intervals in an optimized lookup table
|
||||
// with a supplementary aligned retrieval list
|
||||
type ExchangeIntervals struct {
|
||||
supported map[Interval]int64
|
||||
supported map[Interval]uint64
|
||||
aligned []IntervalCapacity
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ type IntervalRangeHolder struct {
|
||||
Start IntervalTime
|
||||
End IntervalTime
|
||||
Ranges []IntervalRange
|
||||
Limit int
|
||||
Limit uint64
|
||||
}
|
||||
|
||||
// IntervalRange is a subset of candles based on exchange API request limits
|
||||
@@ -209,5 +209,5 @@ type IntervalTime struct {
|
||||
// IntervalCapacity is used to store the interval and capacity for a candle return
|
||||
type IntervalCapacity struct {
|
||||
Interval Interval
|
||||
Capacity int64
|
||||
Capacity uint64
|
||||
}
|
||||
|
||||
@@ -58,12 +58,12 @@ type Request struct {
|
||||
ProcessedCandles []Candle
|
||||
// RequestLimit is the potential maximum amount of candles that can be
|
||||
// returned
|
||||
RequestLimit int64
|
||||
RequestLimit uint64
|
||||
}
|
||||
|
||||
// CreateKlineRequest generates a `Request` type for interval conversions
|
||||
// supported by an exchange.
|
||||
func CreateKlineRequest(name string, pair, formatted currency.Pair, a asset.Item, clientRequired, exchangeInterval Interval, start, end time.Time, specificEndpointLimit int64) (*Request, error) {
|
||||
func CreateKlineRequest(name string, pair, formatted currency.Pair, a asset.Item, clientRequired, exchangeInterval Interval, start, end time.Time, specificEndpointLimit uint64) (*Request, error) {
|
||||
if name == "" {
|
||||
return nil, ErrUnsetName
|
||||
}
|
||||
@@ -132,7 +132,7 @@ func CreateKlineRequest(name string, pair, formatted currency.Pair, a asset.Item
|
||||
|
||||
// GetRanges returns the date ranges for candle intervals broken up over
|
||||
// requests
|
||||
func (r *Request) GetRanges(limit uint32) (*IntervalRangeHolder, error) {
|
||||
func (r *Request) GetRanges(limit uint64) (*IntervalRangeHolder, error) {
|
||||
if r == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
@@ -193,12 +193,12 @@ func (r *Request) ProcessResponse(timeSeries []Candle) (*Item, error) {
|
||||
}
|
||||
|
||||
// Size returns the max length of return for pre-allocation.
|
||||
func (r *Request) Size() int {
|
||||
func (r *Request) Size() uint64 {
|
||||
if r == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(TotalCandlesPerInterval(r.Start, r.End, r.ExchangeInterval))
|
||||
return TotalCandlesPerInterval(r.Start, r.End, r.ExchangeInterval)
|
||||
}
|
||||
|
||||
// ExtendedRequest used in extended functionality for when candles requested
|
||||
@@ -236,12 +236,12 @@ func (r *ExtendedRequest) ProcessResponse(timeSeries []Candle) (*Item, error) {
|
||||
}
|
||||
|
||||
// Size returns the max length of return for pre-allocation.
|
||||
func (r *ExtendedRequest) Size() int {
|
||||
func (r *ExtendedRequest) Size() uint64 {
|
||||
if r == nil || r.RangeHolder == nil {
|
||||
return 0
|
||||
}
|
||||
if r.RangeHolder.Limit == 0 {
|
||||
log.Warnf(log.ExchangeSys, "%v candle request limit is zero while calling Size()", r.Exchange)
|
||||
}
|
||||
return r.RangeHolder.Limit * len(r.RangeHolder.Ranges)
|
||||
return r.RangeHolder.Limit * uint64(len(r.RangeHolder.Ranges))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user