mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-27 15:10:30 +00:00
Backtester: USD tracking (#818)
* Initial concept for creating price tracking pairs * Completes coverage, even with a slow test * I dont know what point to hook this stuff up * Bit of a broken way of handling tracking pairs * Correctly calculates USD rates against all currencies * Removes dependency on GCT config * Failed currency statistics redesign * initial Update chart to use highcharts * Minor changes to stats * Creats funding stats to handle the stat calculations. Needs more work * tracks USD snapshots and BREAKS THINGS FURTHER * Fixed! * Adds ratio calculations and such, but its WRONG. do it at totals level dummy * End of day basic lint * Remaining lints * USD totals statistics * Minor panic fixes * Printing of funding stats, but its bad * Properly calculates overall benchmark, moves funding stat output * Adds some template charge, removes duplicate fields * New charts! * Darkcharts. funding protection when disabled * Now works with usd tracking/funding disabled! * Attempting to only show working stats based on settings. * Spruces up the goose/reporting * Completes report HTML rendering * lint and test fixes * funding statistics testing * slightly more test coverage * Test coverage * Initial documentation * Fixes tests * Database testing and rendering improvements and breakages * report and cmd rendering, linting. fix comma output. rm gct cfg * PR mode 🎉 Path field, config builder support,testing,linting,docs * minor calculation improvement * Secret lint that did not show up locally * Disable USD tracking for example configs * ShazNitNoScope * Forgotten errors * "" * literally Logarithmically logically renders the date 👀 * Fixes typos, fixes parallel test, fixes chart gui and exporting
This commit is contained in:
@@ -327,6 +327,9 @@ func TotalCandlesPerInterval(start, end time.Time, interval Interval) (out float
|
||||
// IntervalsPerYear helps determine the number of intervals in a year
|
||||
// used in CAGR calculation to know the amount of time of an interval in a year
|
||||
func (i *Interval) IntervalsPerYear() float64 {
|
||||
if i.Duration() == 0 {
|
||||
return 0
|
||||
}
|
||||
return float64(OneYear.Duration().Nanoseconds()) / float64(i.Duration().Nanoseconds())
|
||||
}
|
||||
|
||||
@@ -471,6 +474,17 @@ func (h *IntervalRangeHolder) HasDataAtDate(t time.Time) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetClosePriceAtTime returns the close price of a candle
|
||||
// at a given time
|
||||
func (k *Item) GetClosePriceAtTime(t time.Time) (float64, error) {
|
||||
for i := range k.Candles {
|
||||
if k.Candles[i].Time.Equal(t) {
|
||||
return k.Candles[i].Close, nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("%w at %v", ErrNotFoundAtTime, t)
|
||||
}
|
||||
|
||||
// SetHasDataFromCandles will calculate whether there is data in each candle
|
||||
// allowing any missing data from an API request to be highlighted
|
||||
func (h *IntervalRangeHolder) SetHasDataFromCandles(c []Candle) {
|
||||
|
||||
@@ -844,7 +844,11 @@ func TestHasDataAtDate(t *testing.T) {
|
||||
|
||||
func TestIntervalsPerYear(t *testing.T) {
|
||||
t.Parallel()
|
||||
i := OneYear
|
||||
var i Interval
|
||||
if i.IntervalsPerYear() != 0 {
|
||||
t.Error("expected 0")
|
||||
}
|
||||
i = OneYear
|
||||
if i.IntervalsPerYear() != 1.0 {
|
||||
t.Error("expected 1")
|
||||
}
|
||||
@@ -898,7 +902,7 @@ func BenchmarkJustifyIntervalTimeStoringUnixValues2(b *testing.B) {
|
||||
func TestConvertToNewInterval(t *testing.T) {
|
||||
_, err := ConvertToNewInterval(nil, OneMin)
|
||||
if !errors.Is(err, errNilKline) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, errNilKline)
|
||||
t.Errorf("received '%v' expected '%v'", err, errNilKline)
|
||||
}
|
||||
|
||||
old := &Item{
|
||||
@@ -936,23 +940,23 @@ func TestConvertToNewInterval(t *testing.T) {
|
||||
|
||||
_, err = ConvertToNewInterval(old, 0)
|
||||
if !errors.Is(err, ErrUnsetInterval) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, ErrUnsetInterval)
|
||||
t.Errorf("received '%v' expected '%v'", err, ErrUnsetInterval)
|
||||
}
|
||||
_, err = ConvertToNewInterval(old, OneMin)
|
||||
if !errors.Is(err, ErrCanOnlyDownscaleCandles) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, ErrCanOnlyDownscaleCandles)
|
||||
t.Errorf("received '%v' expected '%v'", err, ErrCanOnlyDownscaleCandles)
|
||||
}
|
||||
old.Interval = ThreeDay
|
||||
_, err = ConvertToNewInterval(old, OneWeek)
|
||||
if !errors.Is(err, ErrWholeNumberScaling) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, ErrWholeNumberScaling)
|
||||
t.Errorf("received '%v' expected '%v'", err, ErrWholeNumberScaling)
|
||||
}
|
||||
|
||||
old.Interval = OneDay
|
||||
newInterval := ThreeDay
|
||||
newCandle, err := ConvertToNewInterval(old, newInterval)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, nil)
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
if len(newCandle.Candles) != 1 {
|
||||
t.Error("expected one candle")
|
||||
@@ -975,9 +979,36 @@ func TestConvertToNewInterval(t *testing.T) {
|
||||
})
|
||||
newCandle, err = ConvertToNewInterval(old, newInterval)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expectec '%v'", err, nil)
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
if len(newCandle.Candles) != 1 {
|
||||
t.Error("expected one candle")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetClosePriceAtTime(t *testing.T) {
|
||||
tt := time.Now()
|
||||
k := Item{
|
||||
Candles: []Candle{
|
||||
{
|
||||
Time: tt,
|
||||
Close: 1337,
|
||||
},
|
||||
{
|
||||
Time: tt.Add(time.Hour),
|
||||
Close: 1338,
|
||||
},
|
||||
},
|
||||
}
|
||||
price, err := k.GetClosePriceAtTime(tt)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
if price != 1337 {
|
||||
t.Errorf("received '%v' expected '%v'", price, 1337)
|
||||
}
|
||||
_, err = k.GetClosePriceAtTime(tt.Add(time.Minute))
|
||||
if !errors.Is(err, ErrNotFoundAtTime) {
|
||||
t.Errorf("received '%v' expected '%v'", err, ErrNotFoundAtTime)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ var (
|
||||
// ErrWholeNumberScaling returns when old interval data cannot neatly fit into new interval size
|
||||
ErrWholeNumberScaling = errors.New("new interval must scale properly into new candle")
|
||||
errNilKline = errors.New("kline item is nil")
|
||||
// ErrNotFoundAtTime returned when looking up a candle at a specific time
|
||||
ErrNotFoundAtTime = errors.New("candle not found at time")
|
||||
|
||||
// SupportedIntervals is a list of all supported intervals
|
||||
SupportedIntervals = []Interval{
|
||||
|
||||
Reference in New Issue
Block a user