all: move float slice/map to a single package

This commit is contained in:
c9s 2022-08-25 17:31:42 +08:00
parent de4f3721a2
commit 5953fe49d1
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
68 changed files with 458 additions and 362 deletions

View File

@ -0,0 +1,42 @@
package floats
type Map map[string]float64
func (m Map) Sum() float64 {
sum := 0.0
for _, v := range m {
sum += v
}
return sum
}
func (m Map) MulScalar(x float64) Map {
o := Map{}
for k, v := range m {
o[k] = v * x
}
return o
}
func (m Map) DivScalar(x float64) Map {
o := Map{}
for k, v := range m {
o[k] = v / x
}
return o
}
func (m Map) Normalize() Map {
sum := m.Sum()
if sum == 0 {
panic("zero sum")
}
o := Map{}
for k, v := range m {
o[k] = v / sum
}
return o
}

View File

@ -0,0 +1,151 @@
package floats
import (
"math"
"gonum.org/v1/gonum/floats"
)
type Slice []float64
func New(a ...float64) Slice {
return Slice(a)
}
func (s *Slice) Push(v float64) {
*s = append(*s, v)
}
func (s *Slice) Update(v float64) {
*s = append(*s, v)
}
func (s *Slice) Pop(i int64) (v float64) {
v = (*s)[i]
*s = append((*s)[:i], (*s)[i+1:]...)
return v
}
func (s Slice) Max() float64 {
return floats.Max(s)
}
func (s Slice) Min() float64 {
return floats.Min(s)
}
func (s Slice) Sum() (sum float64) {
return floats.Sum(s)
}
func (s Slice) Mean() (mean float64) {
length := len(s)
if length == 0 {
panic("zero length slice")
}
return s.Sum() / float64(length)
}
func (s Slice) Tail(size int) Slice {
length := len(s)
if length <= size {
win := make(Slice, length)
copy(win, s)
return win
}
win := make(Slice, size)
copy(win, s[length-size:])
return win
}
func (s Slice) Diff() (values Slice) {
for i, v := range s {
if i == 0 {
values.Push(0)
continue
}
values.Push(v - s[i-1])
}
return values
}
func (s Slice) PositiveValuesOrZero() (values Slice) {
for _, v := range s {
values.Push(math.Max(v, 0))
}
return values
}
func (s Slice) NegativeValuesOrZero() (values Slice) {
for _, v := range s {
values.Push(math.Min(v, 0))
}
return values
}
func (s Slice) Abs() (values Slice) {
for _, v := range s {
values.Push(math.Abs(v))
}
return values
}
func (s Slice) MulScalar(x float64) (values Slice) {
for _, v := range s {
values.Push(v * x)
}
return values
}
func (s Slice) DivScalar(x float64) (values Slice) {
for _, v := range s {
values.Push(v / x)
}
return values
}
func (s Slice) Mul(other Slice) (values Slice) {
if len(s) != len(other) {
panic("slice lengths do not match")
}
for i, v := range s {
values.Push(v * other[i])
}
return values
}
func (s Slice) Dot(other Slice) float64 {
return floats.Dot(s, other)
}
func (s Slice) Normalize() Slice {
return s.DivScalar(s.Sum())
}
func (s *Slice) Last() float64 {
length := len(*s)
if length > 0 {
return (*s)[length-1]
}
return 0.0
}
func (s *Slice) Index(i int) float64 {
length := len(*s)
if length-i <= 0 || i < 0 {
return 0.0
}
return (*s)[length-i-1]
}
func (s *Slice) Length() int {
return len(*s)
}
func (s Slice) Addr() *Slice {
return &s
}

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -16,7 +17,7 @@ Accumulation/Distribution Indicator (A/D)
type AD struct { type AD struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
PrePrice float64 PrePrice float64
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -20,7 +21,7 @@ type ALMA struct {
weight []float64 weight []float64
sum float64 sum float64
input []float64 input []float64
Values types.Float64Slice Values floats.Slice
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }

View File

@ -4,6 +4,7 @@ import (
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -11,7 +12,7 @@ import (
type ATR struct { type ATR struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
PercentageVolatility types.Float64Slice PercentageVolatility floats.Slice
PreviousClose float64 PreviousClose float64
RMA *RMA RMA *RMA

View File

@ -4,6 +4,7 @@ import (
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -18,7 +19,7 @@ import (
type ATRP struct { type ATRP struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
PercentageVolatility types.Float64Slice PercentageVolatility floats.Slice
PreviousClose float64 PreviousClose float64
RMA *RMA RMA *RMA

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -29,8 +30,8 @@ type BOLL struct {
SMA *SMA SMA *SMA
StdDev *StdDev StdDev *StdDev
UpBand types.Float64Slice UpBand floats.Slice
DownBand types.Float64Slice DownBand floats.Slice
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -13,10 +14,10 @@ import (
type CCI struct { type CCI struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Input types.Float64Slice Input floats.Slice
TypicalPrice types.Float64Slice TypicalPrice floats.Slice
MA types.Float64Slice MA floats.Slice
Values types.Float64Slice Values floats.Slice
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }

View File

@ -1,6 +1,7 @@
package indicator package indicator
import ( import (
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -10,7 +11,7 @@ import (
type CA struct { type CA struct {
types.SeriesBase types.SeriesBase
Interval types.Interval Interval types.Interval
Values types.Float64Slice Values floats.Slice
length float64 length float64
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }

View File

@ -1,6 +1,7 @@
package indicator package indicator
import ( import (
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -11,7 +12,7 @@ import (
type DEMA struct { type DEMA struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values types.Float64Slice Values floats.Slice
a1 *EWMA a1 *EWMA
a2 *EWMA a2 *EWMA

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -14,7 +15,7 @@ type Drift struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
chng *types.Queue chng *types.Queue
Values types.Float64Slice Values floats.Slice
MA types.UpdatableSeriesExtend MA types.UpdatableSeriesExtend
LastValue float64 LastValue float64

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -15,7 +16,7 @@ type EWMA struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
updateCallbacks []func(value float64) updateCallbacks []func(value float64)

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -11,7 +12,7 @@ type FisherTransform struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
prices *types.Queue prices *types.Queue
Values types.Float64Slice Values floats.Slice
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -11,7 +12,7 @@ type Low struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
updateCallbacks []func(value float64) updateCallbacks []func(value float64)

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -19,11 +20,11 @@ type MACD struct {
types.IntervalWindow // 9 types.IntervalWindow // 9
ShortPeriod int // 12 ShortPeriod int // 12
LongPeriod int // 26 LongPeriod int // 26
Values types.Float64Slice Values floats.Slice
FastEWMA *EWMA FastEWMA *EWMA
SlowEWMA *EWMA SlowEWMA *EWMA
SignalLine *EWMA SignalLine *EWMA
Histogram types.Float64Slice Histogram floats.Slice
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -16,7 +17,7 @@ On-Balance Volume (OBV) Definition
type OBV struct { type OBV struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
PrePrice float64 PrePrice float64
EndTime time.Time EndTime time.Time

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -30,7 +31,7 @@ func Test_calculateOBV(t *testing.T) {
name string name string
kLines []types.KLine kLines []types.KLine
window int window int
want types.Float64Slice want floats.Slice
}{ }{
{ {
name: "trivial_case", name: "trivial_case",
@ -38,13 +39,13 @@ func Test_calculateOBV(t *testing.T) {
[]fixedpoint.Value{fixedpoint.Zero}, []fixedpoint.Value{fixedpoint.One}, []fixedpoint.Value{fixedpoint.Zero}, []fixedpoint.Value{fixedpoint.One},
), ),
window: 0, window: 0,
want: types.Float64Slice{1.0}, want: floats.Slice{1.0},
}, },
{ {
name: "easy_case", name: "easy_case",
kLines: buildKLines(input1, input2), kLines: buildKLines(input1, input2),
window: 0, window: 0,
want: types.Float64Slice{3, 1, -1, 5}, want: floats.Slice{3, 1, -1, 5},
}, },
} }

View File

@ -6,6 +6,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -15,8 +16,8 @@ type Pivot struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Lows types.Float64Slice // higher low Lows floats.Slice // higher low
Highs types.Float64Slice // lower high Highs floats.Slice // lower high
EndTime time.Time EndTime time.Time
@ -96,8 +97,8 @@ func calculatePivot(klines []types.KLine, window int, valLow KLineValueMapper, v
return 0., 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var lows types.Float64Slice var lows floats.Slice
var highs types.Float64Slice var highs floats.Slice
for _, k := range klines { for _, k := range klines {
lows.Push(valLow(k)) lows.Push(valLow(k))
highs.Push(valHigh(k)) highs.Push(valHigh(k))

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -12,8 +13,8 @@ type PivotLow struct {
types.IntervalWindow types.IntervalWindow
Lows types.Float64Slice Lows floats.Slice
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
updateCallbacks []func(value float64) updateCallbacks []func(value float64)
@ -62,7 +63,7 @@ func (inc *PivotLow) PushK(k types.KLine) {
inc.EmitUpdate(inc.Last()) inc.EmitUpdate(inc.Last())
} }
func calculatePivotF(values types.Float64Slice, left, right int, f func(a, pivot float64) bool) (float64, bool) { func calculatePivotF(values floats.Slice, left, right int, f func(a, pivot float64) bool) (float64, bool) {
length := len(values) length := len(values)
if right == 0 { if right == 0 {
@ -91,13 +92,13 @@ func calculatePivotF(values types.Float64Slice, left, right int, f func(a, pivot
return val, true return val, true
} }
func calculatePivotHigh(highs types.Float64Slice, left, right int) (float64, bool) { func calculatePivotHigh(highs floats.Slice, left, right int) (float64, bool) {
return calculatePivotF(highs, left, right, func(a, pivot float64) bool { return calculatePivotF(highs, left, right, func(a, pivot float64) bool {
return a < pivot return a < pivot
}) })
} }
func calculatePivotLow(lows types.Float64Slice, left, right int) (float64, bool) { func calculatePivotLow(lows floats.Slice, left, right int) (float64, bool) {
return calculatePivotF(lows, left, right, func(a, pivot float64) bool { return calculatePivotF(lows, left, right, func(a, pivot float64) bool {
return a > pivot return a > pivot
}) })

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -14,7 +15,7 @@ type RMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
counter int counter int

View File

@ -4,6 +4,7 @@ import (
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -16,8 +17,8 @@ https://www.investopedia.com/terms/r/rsi.asp
type RSI struct { type RSI struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
Prices types.Float64Slice Prices floats.Slice
PreviousAvgLoss float64 PreviousAvgLoss float64
PreviousAvgGain float64 PreviousAvgGain float64

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -26,13 +27,13 @@ func Test_calculateRSI(t *testing.T) {
name string name string
kLines []types.KLine kLines []types.KLine
window int window int
want types.Float64Slice want floats.Slice
}{ }{
{ {
name: "RSI", name: "RSI",
kLines: buildKLines(values), kLines: buildKLines(values),
window: 14, window: 14,
want: types.Float64Slice{ want: floats.Slice{
70.46413502109704, 70.46413502109704,
66.24961855355505, 66.24961855355505,
66.48094183471265, 66.48094183471265,

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -14,7 +15,7 @@ const MaxNumOfSMATruncateSize = 100
type SMA struct { type SMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
rawValues *types.Queue rawValues *types.Queue
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -27,7 +28,7 @@ type SSF struct {
c2 float64 c2 float64
c3 float64 c3 float64
c4 float64 c4 float64
Values types.Float64Slice Values floats.Slice
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }
@ -45,7 +46,7 @@ func (inc *SSF) Update(value float64) {
inc.c3 = -c0 * (1. + b0) inc.c3 = -c0 * (1. + b0)
inc.c2 = c0 + b0 inc.c2 = c0 + b0
inc.c1 = 1. - inc.c2 - inc.c3 - inc.c4 inc.c1 = 1. - inc.c2 - inc.c3 - inc.c4
inc.Values = types.Float64Slice{} inc.Values = floats.Slice{}
} }
result := inc.c1*value + result := inc.c1*value +
@ -61,7 +62,7 @@ func (inc *SSF) Update(value float64) {
inc.c3 = -a0 * a0 inc.c3 = -a0 * a0
inc.c2 = 2. * a0 * math.Cos(x) inc.c2 = 2. * a0 * math.Cos(x)
inc.c1 = 1. - inc.c2 - inc.c3 inc.c1 = 1. - inc.c2 - inc.c3
inc.Values = types.Float64Slice{} inc.Values = floats.Slice{}
} }
result := inc.c1*value + result := inc.c1*value +
inc.c2*inc.Values.Index(0) + inc.c2*inc.Values.Index(0) +

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -10,7 +11,7 @@ import (
type StdDev struct { type StdDev struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
rawValues *types.Queue rawValues *types.Queue
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -17,11 +18,11 @@ Stochastic Oscillator
//go:generate callbackgen -type STOCH //go:generate callbackgen -type STOCH
type STOCH struct { type STOCH struct {
types.IntervalWindow types.IntervalWindow
K types.Float64Slice K floats.Slice
D types.Float64Slice D floats.Slice
HighValues types.Float64Slice HighValues floats.Slice
LowValues types.Float64Slice LowValues floats.Slice
EndTime time.Time EndTime time.Time
UpdateCallbacks []func(k float64, d float64) UpdateCallbacks []func(k float64, d float64)

View File

@ -6,6 +6,7 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -19,7 +20,7 @@ type Supertrend struct {
AverageTrueRange *ATR AverageTrueRange *ATR
trendPrices types.Float64Slice trendPrices floats.Slice
closePrice float64 closePrice float64
previousClosePrice float64 previousClosePrice float64

View File

@ -1,6 +1,7 @@
package indicator package indicator
import ( import (
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -11,7 +12,7 @@ import (
type TEMA struct { type TEMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
A1 *EWMA A1 *EWMA
A2 *EWMA A2 *EWMA
A3 *EWMA A3 *EWMA

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -12,8 +13,8 @@ import (
type VIDYA struct { type VIDYA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
input types.Float64Slice input floats.Slice
updateCallbacks []func(value float64) updateCallbacks []func(value float64)
} }

View File

@ -7,6 +7,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -19,7 +20,7 @@ const MaxNumOfVOLTruncateSize = 100
type Volatility struct { type Volatility struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -19,9 +20,9 @@ Volume-Weighted Average Price (VWAP) Explained
type VWAP struct { type VWAP struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
Prices types.Float64Slice Prices floats.Slice
Volumes types.Float64Slice Volumes floats.Slice
WeightedSum float64 WeightedSum float64
VolumeSum float64 VolumeSum float64

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -21,7 +22,7 @@ type VWMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
PriceVolumeSMA *SMA PriceVolumeSMA *SMA
VolumeSMA *SMA VolumeSMA *SMA

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"math" "math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -14,7 +15,7 @@ type WeightedDrift struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
chng *types.Queue chng *types.Queue
Values types.Float64Slice Values floats.Slice
MA types.UpdatableSeriesExtend MA types.UpdatableSeriesExtend
Weight *types.Queue Weight *types.Queue
LastValue float64 LastValue float64

View File

@ -3,6 +3,7 @@ package indicator
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -17,7 +18,7 @@ const MaxNumOfWWMATruncateSize = 100
type WWMA struct { type WWMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
LastOpenTime time.Time LastOpenTime time.Time
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)

View File

@ -1,6 +1,7 @@
package indicator package indicator
import ( import (
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -12,7 +13,7 @@ type ZLEMA struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
data types.Float64Slice data floats.Slice
zlema *EWMA zlema *EWMA
lag int lag int

View File

@ -15,6 +15,7 @@ import (
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/interact" "github.com/c9s/bbgo/pkg/interact"
@ -647,10 +648,10 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
method.Bind(session, s.GeneralOrderExecutor) method.Bind(session, s.GeneralOrderExecutor)
} }
profit := types.Float64Slice{1., 1.} profit := floats.Slice{1., 1.}
price, _ := s.Session.LastPrice(s.Symbol) price, _ := s.Session.LastPrice(s.Symbol)
initAsset := s.CalcAssetValue(price).Float64() initAsset := s.CalcAssetValue(price).Float64()
cumProfit := types.Float64Slice{initAsset, initAsset} cumProfit := floats.Slice{initAsset, initAsset}
modify := func(p float64) float64 { modify := func(p float64) float64 {
return p return p
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -18,7 +19,7 @@ type MOM struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
LastValue float64 LastValue float64
opens *types.Queue opens *types.Queue

View File

@ -3,9 +3,11 @@ package factorzoo
import ( import (
"time" "time"
"gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"gonum.org/v1/gonum/stat"
) )
// price mean reversion // price mean reversion
@ -17,7 +19,7 @@ type PMR struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values types.Float64Slice Values floats.Slice
SMA *indicator.SMA SMA *indicator.SMA
EndTime time.Time EndTime time.Time

View File

@ -3,9 +3,11 @@ package factorzoo
import ( import (
"time" "time"
"gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"gonum.org/v1/gonum/stat"
) )
// price volume divergence // price volume divergence
@ -21,7 +23,7 @@ type PVD struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values types.Float64Slice Values floats.Slice
Prices *types.Queue Prices *types.Queue
Volumes *types.Queue Volumes *types.Queue
EndTime time.Time EndTime time.Time

View File

@ -3,6 +3,7 @@ package factorzoo
import ( import (
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -15,7 +16,7 @@ type RR struct {
types.SeriesBase types.SeriesBase
prices *types.Queue prices *types.Queue
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
updateCallbacks []func(value float64) updateCallbacks []func(value float64)

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -18,7 +19,7 @@ type VMOM struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
LastValue float64 LastValue float64
volumes *types.Queue volumes *types.Queue

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/strategy/factorzoo/factors" "github.com/c9s/bbgo/pkg/strategy/factorzoo/factors"
@ -76,7 +77,7 @@ func (s *Linear) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.General
// take past window days' values to predict future return // take past window days' values to predict future return
// (e.g., 5 here in default configuration file) // (e.g., 5 here in default configuration file)
a := []types.Float64Slice{ a := []floats.Slice{
s.divergence.Values[len(s.divergence.Values)-s.Window-2 : len(s.divergence.Values)-2], s.divergence.Values[len(s.divergence.Values)-s.Window-2 : len(s.divergence.Values)-2],
s.reversion.Values[len(s.reversion.Values)-s.Window-2 : len(s.reversion.Values)-2], s.reversion.Values[len(s.reversion.Values)-s.Window-2 : len(s.reversion.Values)-2],
s.drift.Values[len(s.drift.Values)-s.Window-2 : len(s.drift.Values)-2], s.drift.Values[len(s.drift.Values)-s.Window-2 : len(s.drift.Values)-2],
@ -87,7 +88,7 @@ func (s *Linear) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.General
// factors array from day -4 to day 0, [[0.1, 0.2, 0.35, 0.3 , 0.25], [1.1, -0.2, 1.35, -0.3 , -0.25], ...] // factors array from day -4 to day 0, [[0.1, 0.2, 0.35, 0.3 , 0.25], [1.1, -0.2, 1.35, -0.3 , -0.25], ...]
// the binary(+/-) daily return rate from day -3 to day 1, [0, 1, 1, 0, 0] // the binary(+/-) daily return rate from day -3 to day 1, [0, 1, 1, 0, 0]
// then we take the latest available factors array into linear regression model // then we take the latest available factors array into linear regression model
b := []types.Float64Slice{filter(s.irr.Values[len(s.irr.Values)-s.Window-1:len(s.irr.Values)-1], binary)} b := []floats.Slice{filter(s.irr.Values[len(s.irr.Values)-s.Window-1:len(s.irr.Values)-1], binary)}
var x []types.Series var x []types.Series
var y []types.Series var y []types.Series

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type A18 //go:generate callbackgen -type A18
@ -12,7 +14,7 @@ type A18 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -76,7 +78,7 @@ func calculateA18(klines []types.KLine, valClose KLineValueMapper) (float64, err
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
closes.Push(valClose(k)) closes.Push(valClose(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type A2 //go:generate callbackgen -type A2
@ -12,7 +14,7 @@ type A2 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -76,9 +78,9 @@ func calculateA2(klines []types.KLine, valLow KLineValueMapper, valHigh KLineVal
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var lows types.Float64Slice var lows floats.Slice
var highs types.Float64Slice var highs floats.Slice
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
lows.Push(valLow(k)) lows.Push(valLow(k))

View File

@ -2,10 +2,12 @@ package fmaker
import ( import (
"fmt" "fmt"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
) )
//go:generate callbackgen -type A3 //go:generate callbackgen -type A3
@ -13,7 +15,7 @@ type A3 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -77,9 +79,9 @@ func calculateA3(klines []types.KLine, valLow KLineValueMapper, valHigh KLineVal
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var lows types.Float64Slice var lows floats.Slice
var highs types.Float64Slice var highs floats.Slice
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
lows.Push(valLow(k)) lows.Push(valLow(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type A34 //go:generate callbackgen -type A34
@ -12,7 +14,7 @@ type A34 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,7 +77,7 @@ func calculateA34(klines []types.KLine, valClose KLineValueMapper) (float64, err
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
closes.Push(valClose(k)) closes.Push(valClose(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
var zeroTime time.Time var zeroTime time.Time
@ -16,7 +18,7 @@ type R struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -79,8 +81,8 @@ func calculateR(klines []types.KLine, valOpen KLineValueMapper, valClose KLineVa
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var opens types.Float64Slice var opens floats.Slice
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
opens.Push(valOpen(k)) opens.Push(valOpen(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S0 //go:generate callbackgen -type S0
@ -12,7 +14,7 @@ type S0 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,13 +77,13 @@ func calculateS0(klines []types.KLine, valClose KLineValueMapper) (float64, erro
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
closes.Push(valClose(k)) closes.Push(valClose(k))
} }
sma := types.Float64Slice.Sum(closes[len(closes)-window:len(closes)-1]) / float64(window) sma := floats.Slice.Sum(closes[len(closes)-window:len(closes)-1]) / float64(window)
alpha := sma / closes.Last() alpha := sma / closes.Last()
return alpha, nil return alpha, nil

View File

@ -5,6 +5,7 @@ import (
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -12,7 +13,7 @@ import (
//go:generate callbackgen -type S1 //go:generate callbackgen -type S1
type S1 struct { type S1 struct {
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)

View File

@ -5,6 +5,7 @@ import (
"math" "math"
"time" "time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -12,7 +13,7 @@ import (
//go:generate callbackgen -type S2 //go:generate callbackgen -type S2
type S2 struct { type S2 struct {
types.IntervalWindow types.IntervalWindow
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S3 //go:generate callbackgen -type S3
@ -12,7 +14,7 @@ type S3 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,8 +77,8 @@ func calculateS3(klines []types.KLine, valClose KLineValueMapper, valOpen KLineV
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var closes types.Float64Slice var closes floats.Slice
var opens types.Float64Slice var opens floats.Slice
for _, k := range klines { for _, k := range klines {
closes.Push(valClose(k)) closes.Push(valClose(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S4 //go:generate callbackgen -type S4
@ -12,7 +14,7 @@ type S4 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,7 +77,7 @@ func calculateS4(klines []types.KLine, valClose KLineValueMapper) (float64, erro
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
closes.Push(valClose(k)) closes.Push(valClose(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S5 //go:generate callbackgen -type S5
@ -12,7 +14,7 @@ type S5 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,7 +77,7 @@ func calculateS5(klines []types.KLine, valVolume KLineValueMapper) (float64, err
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var volumes types.Float64Slice var volumes floats.Slice
for _, k := range klines { for _, k := range klines {
volumes.Push(valVolume(k)) volumes.Push(valVolume(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S6 //go:generate callbackgen -type S6
@ -12,7 +14,7 @@ type S6 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,10 +77,10 @@ func calculateS6(klines []types.KLine, valHigh KLineValueMapper, valLow KLineVal
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var highs types.Float64Slice var highs floats.Slice
var lows types.Float64Slice var lows floats.Slice
var closes types.Float64Slice var closes floats.Slice
var volumes types.Float64Slice var volumes floats.Slice
for _, k := range klines { for _, k := range klines {
highs.Push(valHigh(k)) highs.Push(valHigh(k))

View File

@ -2,9 +2,11 @@ package fmaker
import ( import (
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
//go:generate callbackgen -type S7 //go:generate callbackgen -type S7
@ -12,7 +14,7 @@ type S7 struct {
types.IntervalWindow types.IntervalWindow
// Values // Values
Values types.Float64Slice Values floats.Slice
EndTime time.Time EndTime time.Time
@ -75,8 +77,8 @@ func calculateS7(klines []types.KLine, valOpen KLineValueMapper, valClose KLineV
if length == 0 || length < window { if length == 0 || length < window {
return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window)
} }
var opens types.Float64Slice var opens floats.Slice
var closes types.Float64Slice var closes floats.Slice
for _, k := range klines { for _, k := range klines {
opens.Push(valOpen(k)) opens.Push(valOpen(k))

View File

@ -10,6 +10,7 @@ import (
"gonum.org/v1/gonum/floats" "gonum.org/v1/gonum/floats"
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
floats2 "github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -322,7 +323,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
a34 := s.A34.Values[len(s.A34.Values)-i-outlook] a34 := s.A34.Values[len(s.A34.Values)-i-outlook]
ret := s.R.Values[len(s.R.Values)-i] ret := s.R.Values[len(s.R.Values)-i]
rdps = append(rdps, regression.DataPoint(ret, types.Float64Slice{s0, s1, s2, s4, s5, s6, s7, a2, a3, a18, a34})) rdps = append(rdps, regression.DataPoint(ret, floats2.Slice{s0, s1, s2, s4, s5, s6, s7, a2, a3, a18, a34}))
} }
// for i := 40; i > 20; i-- { // for i := 40; i > 20; i-- {
// s0 := preprocessing(s.S0.Values[len(s.S0.Values)-i : len(s.S0.Values)-i+20-outlook]) // s0 := preprocessing(s.S0.Values[len(s.S0.Values)-i : len(s.S0.Values)-i+20-outlook])
@ -341,7 +342,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
// } // }
r.Train(rdps...) r.Train(rdps...)
r.Run() r.Run()
er, _ := r.Predict(types.Float64Slice{s.S0.Last(), s.S1.Last(), s.S2.Last(), s.S4.Last(), s.S5.Last(), s.S6.Last(), s.S7.Last(), s.A2.Last(), s.A3.Last(), s.A18.Last(), s.A34.Last()}) er, _ := r.Predict(floats2.Slice{s.S0.Last(), s.S1.Last(), s.S2.Last(), s.S4.Last(), s.S5.Last(), s.S6.Last(), s.S7.Last(), s.A2.Last(), s.A3.Last(), s.A18.Last(), s.A34.Last()})
log.Infof("Expected Return Rate: %f", er) log.Infof("Expected Return Rate: %f", er)
q := new(regression.Regression) q := new(regression.Regression)
@ -377,7 +378,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
ret := s.R.Values[len(s.R.Values)-i] ret := s.R.Values[len(s.R.Values)-i]
qty := math.Abs(ret) qty := math.Abs(ret)
qdps = append(qdps, regression.DataPoint(qty, types.Float64Slice{s0, s1, s2, s4, s5, s6, s7, a2, a3, a18, a34})) qdps = append(qdps, regression.DataPoint(qty, floats2.Slice{s0, s1, s2, s4, s5, s6, s7, a2, a3, a18, a34}))
} }
// for i := 40; i > 20; i-- { // for i := 40; i > 20; i-- {
// s0 := preprocessing(s.S0.Values[len(s.S0.Values)-i : len(s.S0.Values)-i+20-outlook]) // s0 := preprocessing(s.S0.Values[len(s.S0.Values)-i : len(s.S0.Values)-i+20-outlook])
@ -416,7 +417,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
// a34 := preprocessing(s.A18.Values[len(s.A18.Values)-20 : len(s.A18.Values)-1-outlook]) // a34 := preprocessing(s.A18.Values[len(s.A18.Values)-20 : len(s.A18.Values)-1-outlook])
// er, _ := r.Predict(types.Float64Slice{s0, s1, s2, s4, s5, a2, a3, a18, a34}) // er, _ := r.Predict(types.Float64Slice{s0, s1, s2, s4, s5, a2, a3, a18, a34})
// eq, _ := q.Predict(types.Float64Slice{s0, s1, s2, s4, s5, a2, a3, a18, a34}) // eq, _ := q.Predict(types.Float64Slice{s0, s1, s2, s4, s5, a2, a3, a18, a34})
eq, _ := q.Predict(types.Float64Slice{s.S0.Last(), s.S1.Last(), s.S2.Last(), s.S4.Last(), s.S5.Last(), s.S6.Last(), s.S7.Last(), s.A2.Last(), s.A3.Last(), s.A18.Last(), s.A34.Last(), er}) eq, _ := q.Predict(floats2.Slice{s.S0.Last(), s.S1.Last(), s.S2.Last(), s.S4.Last(), s.S5.Last(), s.S6.Last(), s.S7.Last(), s.A2.Last(), s.A3.Last(), s.A18.Last(), s.A34.Last(), er})
log.Infof("Expected Order Quantity: %f", eq) log.Infof("Expected Order Quantity: %f", eq)
// if float64(s.Position.GetBase().Sign())*er < 0 { // if float64(s.Position.GetBase().Sign())*er < 0 {
// s.ClosePosition(ctx, fixedpoint.One, kline.Close) // s.ClosePosition(ctx, fixedpoint.One, kline.Close)

View File

@ -9,6 +9,7 @@ import (
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datasource/glassnode" "github.com/c9s/bbgo/pkg/datasource/glassnode"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -171,7 +172,7 @@ func (s *Strategy) generateSubmitOrders(ctx context.Context, session *bbgo.Excha
} }
func (s *Strategy) getTargetWeights(ctx context.Context) types.ValueMap { func (s *Strategy) getTargetWeights(ctx context.Context) types.ValueMap {
m := types.FloatMap{} m := floats.Map{}
// get market cap values // get market cap values
for _, currency := range s.TargetCurrencies { for _, currency := range s.TargetCurrencies {

View File

@ -1,9 +1,11 @@
package supertrend package supertrend
import ( import (
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator" "github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
"time"
) )
// LinReg is Linear Regression baseline // LinReg is Linear Regression baseline
@ -11,7 +13,7 @@ type LinReg struct {
types.SeriesBase types.SeriesBase
types.IntervalWindow types.IntervalWindow
// Values are the slopes of linear regression baseline // Values are the slopes of linear regression baseline
Values types.Float64Slice Values floats.Slice
klines types.KLineWindow klines types.KLineWindow
EndTime time.Time EndTime time.Time
} }

View File

@ -3,11 +3,13 @@ package supertrend
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/c9s/bbgo/pkg/data/tsv"
"github.com/c9s/bbgo/pkg/risk"
"os" "os"
"sync" "sync"
"github.com/c9s/bbgo/pkg/data/tsv"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/risk"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -48,25 +50,25 @@ type AccumulatedProfitReport struct {
// Accumulated profit // Accumulated profit
accumulatedProfit fixedpoint.Value accumulatedProfit fixedpoint.Value
accumulatedProfitPerDay types.Float64Slice accumulatedProfitPerDay floats.Slice
previousAccumulatedProfit fixedpoint.Value previousAccumulatedProfit fixedpoint.Value
// Accumulated profit MA // Accumulated profit MA
accumulatedProfitMA *indicator.SMA accumulatedProfitMA *indicator.SMA
accumulatedProfitMAPerDay types.Float64Slice accumulatedProfitMAPerDay floats.Slice
// Daily profit // Daily profit
dailyProfit types.Float64Slice dailyProfit floats.Slice
// Accumulated fee // Accumulated fee
accumulatedFee fixedpoint.Value accumulatedFee fixedpoint.Value
accumulatedFeePerDay types.Float64Slice accumulatedFeePerDay floats.Slice
// Win ratio // Win ratio
winRatioPerDay types.Float64Slice winRatioPerDay floats.Slice
// Profit factor // Profit factor
profitFactorPerDay types.Float64Slice profitFactorPerDay floats.Slice
} }
func (r *AccumulatedProfitReport) Initialize() { func (r *AccumulatedProfitReport) Initialize() {

View File

@ -1,42 +1,5 @@
package types package types
type FloatMap map[string]float64 import "github.com/c9s/bbgo/pkg/datatype/floats"
func (m FloatMap) Sum() float64 { var _ Series = floats.Slice([]float64{}).Addr()
sum := 0.0
for _, v := range m {
sum += v
}
return sum
}
func (m FloatMap) MulScalar(x float64) FloatMap {
o := FloatMap{}
for k, v := range m {
o[k] = v * x
}
return o
}
func (m FloatMap) DivScalar(x float64) FloatMap {
o := FloatMap{}
for k, v := range m {
o[k] = v / x
}
return o
}
func (m FloatMap) Normalize() FloatMap {
sum := m.Sum()
if sum == 0 {
panic("zero sum")
}
o := FloatMap{}
for k, v := range m {
o[k] = v / sum
}
return o
}

View File

@ -1,148 +0,0 @@
package types
import (
"math"
"gonum.org/v1/gonum/floats"
)
type Float64Slice []float64
func (s *Float64Slice) Push(v float64) {
*s = append(*s, v)
}
func (s *Float64Slice) Update(v float64) {
*s = append(*s, v)
}
func (s *Float64Slice) Pop(i int64) (v float64) {
v = (*s)[i]
*s = append((*s)[:i], (*s)[i+1:]...)
return v
}
func (s Float64Slice) Max() float64 {
return floats.Max(s)
}
func (s Float64Slice) Min() float64 {
return floats.Min(s)
}
func (s Float64Slice) Sum() (sum float64) {
return floats.Sum(s)
}
func (s Float64Slice) Mean() (mean float64) {
length := len(s)
if length == 0 {
panic("zero length slice")
}
return s.Sum() / float64(length)
}
func (s Float64Slice) Tail(size int) Float64Slice {
length := len(s)
if length <= size {
win := make(Float64Slice, length)
copy(win, s)
return win
}
win := make(Float64Slice, size)
copy(win, s[length-size:])
return win
}
func (s Float64Slice) Diff() (values Float64Slice) {
for i, v := range s {
if i == 0 {
values.Push(0)
continue
}
values.Push(v - s[i-1])
}
return values
}
func (s Float64Slice) PositiveValuesOrZero() (values Float64Slice) {
for _, v := range s {
values.Push(math.Max(v, 0))
}
return values
}
func (s Float64Slice) NegativeValuesOrZero() (values Float64Slice) {
for _, v := range s {
values.Push(math.Min(v, 0))
}
return values
}
func (s Float64Slice) Abs() (values Float64Slice) {
for _, v := range s {
values.Push(math.Abs(v))
}
return values
}
func (s Float64Slice) MulScalar(x float64) (values Float64Slice) {
for _, v := range s {
values.Push(v * x)
}
return values
}
func (s Float64Slice) DivScalar(x float64) (values Float64Slice) {
for _, v := range s {
values.Push(v / x)
}
return values
}
func (s Float64Slice) Mul(other Float64Slice) (values Float64Slice) {
if len(s) != len(other) {
panic("slice lengths do not match")
}
for i, v := range s {
values.Push(v * other[i])
}
return values
}
func (s Float64Slice) Dot(other Float64Slice) float64 {
return floats.Dot(s, other)
}
func (s Float64Slice) Normalize() Float64Slice {
return s.DivScalar(s.Sum())
}
func (a *Float64Slice) Last() float64 {
length := len(*a)
if length > 0 {
return (*a)[length-1]
}
return 0.0
}
func (a *Float64Slice) Index(i int) float64 {
length := len(*a)
if length-i <= 0 || i < 0 {
return 0.0
}
return (*a)[length-i-1]
}
func (a *Float64Slice) Length() int {
return len(*a)
}
func (a Float64Slice) Addr() *Float64Slice {
return &a
}
var _ Series = Float64Slice([]float64{}).Addr()

View File

@ -8,6 +8,8 @@ import (
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
"gonum.org/v1/gonum/stat" "gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
) )
// Super basic Series type that simply holds the float64 data // Super basic Series type that simply holds the float64 data
@ -94,7 +96,7 @@ type SeriesExtend interface {
Mul(b interface{}) SeriesExtend Mul(b interface{}) SeriesExtend
Dot(b interface{}, limit ...int) float64 Dot(b interface{}, limit ...int) float64
Array(limit ...int) (result []float64) Array(limit ...int) (result []float64)
Reverse(limit ...int) (result Float64Slice) Reverse(limit ...int) (result floats.Slice)
Change(offset ...int) SeriesExtend Change(offset ...int) SeriesExtend
PercentageChange(offset ...int) SeriesExtend PercentageChange(offset ...int) SeriesExtend
Stdev(params ...int) float64 Stdev(params ...int) float64
@ -649,7 +651,7 @@ func Array(a Series, limit ...int) (result []float64) {
// the then reuse the result in multiple places (so that no recalculation will be triggered) // the then reuse the result in multiple places (so that no recalculation will be triggered)
// //
// notice that the return type is a Float64Slice, which implements the Series interface // notice that the return type is a Float64Slice, which implements the Series interface
func Reverse(a Series, limit ...int) (result Float64Slice) { func Reverse(a Series, limit ...int) (result floats.Slice) {
l := a.Length() l := a.Length()
if len(limit) > 0 && l > limit[0] { if len(limit) > 0 && l > limit[0] {
l = limit[0] l = limit[0]

View File

@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
"gonum.org/v1/gonum/stat" "gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
) )
func TestFloat(t *testing.T) { func TestFloat(t *testing.T) {
@ -19,7 +21,7 @@ func TestFloat(t *testing.T) {
func TestNextCross(t *testing.T) { func TestNextCross(t *testing.T) {
var a Series = NumberSeries(1.2) var a Series = NumberSeries(1.2)
var b Series = &Float64Slice{100., 80., 60.} var b Series = &floats.Slice{100., 80., 60.}
// index 2 1 0 // index 2 1 0
// predicted 40 20 0 // predicted 40 20 0
// offset 1 2 3 // offset 1 2 3
@ -31,8 +33,8 @@ func TestNextCross(t *testing.T) {
} }
func TestFloat64Slice(t *testing.T) { func TestFloat64Slice(t *testing.T) {
var a = Float64Slice{1.0, 2.0, 3.0} var a = floats.Slice{1.0, 2.0, 3.0}
var b = Float64Slice{1.0, 2.0, 3.0} var b = floats.Slice{1.0, 2.0, 3.0}
var c Series = Minus(&a, &b) var c Series = Minus(&a, &b)
a = append(a, 4.0) a = append(a, 4.0)
b = append(b, 3.0) b = append(b, 3.0)
@ -51,8 +53,8 @@ print(s1.corr(s2, method='kendall'))
print(s1.rank()) print(s1.rank())
*/ */
func TestCorr(t *testing.T) { func TestCorr(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2} var a = floats.Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1} var b = floats.Slice{.3, .6, .0, .1}
corr := Correlation(&a, &b, 4, Pearson) corr := Correlation(&a, &b, 4, Pearson)
assert.InDelta(t, corr, -0.8510644, 0.001) assert.InDelta(t, corr, -0.8510644, 0.001)
out := Rank(&a, 4) out := Rank(&a, 4)
@ -71,8 +73,8 @@ s2 = pd.Series([.3, .6, .0, .1])
print(s1.cov(s2, ddof=0)) print(s1.cov(s2, ddof=0))
*/ */
func TestCov(t *testing.T) { func TestCov(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2} var a = floats.Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1} var b = floats.Slice{.3, .6, .0, .1}
cov := Covariance(&a, &b, 4) cov := Covariance(&a, &b, 4)
assert.InDelta(t, cov, -0.042499, 0.001) assert.InDelta(t, cov, -0.042499, 0.001)
} }
@ -85,37 +87,37 @@ s1 = pd.Series([.2, 0., .6, .2, .2])
print(s1.skew()) print(s1.skew())
*/ */
func TestSkew(t *testing.T) { func TestSkew(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2} var a = floats.Slice{.2, .0, .6, .2}
sk := Skew(&a, 4) sk := Skew(&a, 4)
assert.InDelta(t, sk, 1.129338, 0.001) assert.InDelta(t, sk, 1.129338, 0.001)
} }
func TestEntropy(t *testing.T) { func TestEntropy(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2} var a = floats.Slice{.2, .0, .6, .2}
e := stat.Entropy(a) e := stat.Entropy(a)
assert.InDelta(t, e, Entropy(&a, a.Length()), 0.0001) assert.InDelta(t, e, Entropy(&a, a.Length()), 0.0001)
} }
func TestCrossEntropy(t *testing.T) { func TestCrossEntropy(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2} var a = floats.Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1} var b = floats.Slice{.3, .6, .0, .1}
e := stat.CrossEntropy(a, b) e := stat.CrossEntropy(a, b)
assert.InDelta(t, e, CrossEntropy(&a, &b, a.Length()), 0.0001) assert.InDelta(t, e, CrossEntropy(&a, &b, a.Length()), 0.0001)
} }
func TestSoftmax(t *testing.T) { func TestSoftmax(t *testing.T) {
var a = Float64Slice{3.0, 1.0, 0.2} var a = floats.Slice{3.0, 1.0, 0.2}
out := Softmax(&a, a.Length()) out := Softmax(&a, a.Length())
r := Float64Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916} r := floats.Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916}
for i := 0; i < out.Length(); i++ { for i := 0; i < out.Length(); i++ {
assert.InDelta(t, r.Index(i), out.Index(i), 0.001) assert.InDelta(t, r.Index(i), out.Index(i), 0.001)
} }
} }
func TestSigmoid(t *testing.T) { func TestSigmoid(t *testing.T) {
a := Float64Slice{3.0, 1.0, 2.1} a := floats.Slice{3.0, 1.0, 2.1}
out := Sigmoid(&a) out := Sigmoid(&a)
r := Float64Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871} r := floats.Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871}
for i := 0; i < out.Length(); i++ { for i := 0; i < out.Length(); i++ {
assert.InDelta(t, r.Index(i), out.Index(i), 0.001) assert.InDelta(t, r.Index(i), out.Index(i), 0.001)
} }
@ -123,8 +125,8 @@ func TestSigmoid(t *testing.T) {
// from https://en.wikipedia.org/wiki/Logistic_regression // from https://en.wikipedia.org/wiki/Logistic_regression
func TestLogisticRegression(t *testing.T) { func TestLogisticRegression(t *testing.T) {
a := []Float64Slice{{0.5, 0.75, 1., 1.25, 1.5, 1.75, 1.75, 2.0, 2.25, 2.5, 2.75, 3., 3.25, 3.5, 4., 4.25, 4.5, 4.75, 5., 5.5}} a := []floats.Slice{{0.5, 0.75, 1., 1.25, 1.5, 1.75, 1.75, 2.0, 2.25, 2.5, 2.75, 3., 3.25, 3.5, 4., 4.25, 4.5, 4.75, 5., 5.5}}
b := Float64Slice{0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1} b := floats.Slice{0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1}
var x []Series var x []Series
x = append(x, &a[0]) x = append(x, &a[0])
@ -139,8 +141,8 @@ func TestLogisticRegression(t *testing.T) {
} }
func TestDot(t *testing.T) { func TestDot(t *testing.T) {
a := Float64Slice{7, 6, 5, 4, 3, 2, 1, 0} a := floats.Slice{7, 6, 5, 4, 3, 2, 1, 0}
b := Float64Slice{200., 201., 203., 204., 203., 199.} b := floats.Slice{200., 201., 203., 204., 203., 199.}
out1 := Dot(&a, &b, 3) out1 := Dot(&a, &b, 3)
assert.InDelta(t, out1, 611., 0.001) assert.InDelta(t, out1, 611., 0.001)
out2 := Dot(&a, 3., 2) out2 := Dot(&a, 3., 2)
@ -160,7 +162,7 @@ func TestClone(t *testing.T) {
func TestPlot(t *testing.T) { func TestPlot(t *testing.T) {
ct := NewCanvas("test", Interval5m) ct := NewCanvas("test", Interval5m)
a := Float64Slice{200., 205., 230., 236} a := floats.Slice{200., 205., 230., 236}
ct.Plot("test", &a, Time(time.Now()), 4) ct.Plot("test", &a, Time(time.Now()), 4)
assert.Equal(t, ct.Interval, Interval5m) assert.Equal(t, ct.Interval, Interval5m)
assert.Equal(t, ct.Series[0].(chart.TimeSeries).Len(), 4) assert.Equal(t, ct.Series[0].(chart.TimeSeries).Len(), 4)

View File

@ -1,12 +1,15 @@
package types package types
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
) )
func TestOmega(t *testing.T) { func TestOmega(t *testing.T) {
var a Series = &Float64Slice{0.08, 0.09, 0.07, 0.15, 0.02, 0.03, 0.04, 0.05, 0.06, 0.01} var a Series = &floats.Slice{0.08, 0.09, 0.07, 0.15, 0.02, 0.03, 0.04, 0.05, 0.06, 0.01}
output := Omega(a) output := Omega(a)
assert.InDelta(t, output, 1, 0.0001) assert.InDelta(t, output, 1, 0.0001)
} }

View File

@ -1,5 +1,7 @@
package types package types
import "github.com/c9s/bbgo/pkg/datatype/floats"
func (s *SeriesBase) Index(i int) float64 { func (s *SeriesBase) Index(i int) float64 {
if s.Series == nil { if s.Series == nil {
return 0 return 0
@ -81,7 +83,7 @@ func (s *SeriesBase) Array(limit ...int) (result []float64) {
return Array(s, limit...) return Array(s, limit...)
} }
func (s *SeriesBase) Reverse(limit ...int) (result Float64Slice) { func (s *SeriesBase) Reverse(limit ...int) (result floats.Slice) {
return Reverse(s, limit...) return Reverse(s, limit...)
} }

View File

@ -1,8 +1,11 @@
package types package types
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
) )
/* /*
@ -16,7 +19,7 @@ print(qx.stats.sharpe(pd.Series([0.01, 0.1, 0.001]), 0, 252, False, False))
print(qx.stats.sharpe(pd.Series([0.01, 0.1, 0.001]), 0, 252, True, False)) print(qx.stats.sharpe(pd.Series([0.01, 0.1, 0.001]), 0, 252, True, False))
*/ */
func TestSharpe(t *testing.T) { func TestSharpe(t *testing.T) {
var a Series = &Float64Slice{0.01, 0.1, 0.001} var a Series = &floats.Slice{0.01, 0.1, 0.001}
output := Sharpe(a, 0, false, false) output := Sharpe(a, 0, false, false)
assert.InDelta(t, output, 0.67586, 0.0001) assert.InDelta(t, output, 0.67586, 0.0001)
output = Sharpe(a, 252, false, false) output = Sharpe(a, 252, false, false)

View File

@ -1,8 +1,11 @@
package types package types
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
) )
/* /*
@ -16,7 +19,7 @@ print(qx.stats.sortino(pd.Series([0.01, -0.03, 0.1, -0.02, 0.001]), 0.03, 252, F
print(qx.stats.sortino(pd.Series([0.01, -0.03, 0.1, -0.02, 0.001]), 0.03, 252, True, False)) print(qx.stats.sortino(pd.Series([0.01, -0.03, 0.1, -0.02, 0.001]), 0.03, 252, True, False))
*/ */
func TestSortino(t *testing.T) { func TestSortino(t *testing.T) {
var a Series = &Float64Slice{0.01, -0.03, 0.1, -0.02, 0.001} var a Series = &floats.Slice{0.01, -0.03, 0.1, -0.02, 0.001}
output := Sortino(a, 0.03, 0, false, false) output := Sortino(a, 0.03, 0, false, false)
assert.InDelta(t, output, 0.75661, 0.0001) assert.InDelta(t, output, 0.75661, 0.0001)
output = Sortino(a, 0.03, 252, false, false) output = Sortino(a, 0.03, 252, false, false)

View File

@ -8,18 +8,19 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
) )
type IntervalProfitCollector struct { type IntervalProfitCollector struct {
Interval Interval `json:"interval"` Interval Interval `json:"interval"`
Profits *Float64Slice `json:"profits"` Profits *floats.Slice `json:"profits"`
Timestamp *Float64Slice `json:"timestamp"` Timestamp *floats.Slice `json:"timestamp"`
tmpTime time.Time `json:"tmpTime"` tmpTime time.Time `json:"tmpTime"`
} }
func NewIntervalProfitCollector(i Interval, startTime time.Time) *IntervalProfitCollector { func NewIntervalProfitCollector(i Interval, startTime time.Time) *IntervalProfitCollector {
return &IntervalProfitCollector{Interval: i, tmpTime: startTime, Profits: &Float64Slice{1.}, Timestamp: &Float64Slice{float64(startTime.Unix())}} return &IntervalProfitCollector{Interval: i, tmpTime: startTime, Profits: &floats.Slice{1.}, Timestamp: &floats.Slice{float64(startTime.Unix())}}
} }
// Update the collector by every traded profit // Update the collector by every traded profit