Merge pull request #895 from c9s/refactor/floats

refactor: move float slice/map to a single package
This commit is contained in:
Yo-An Lin 2022-08-25 18:44:03 +08:00 committed by GitHub
commit f05e1d1da6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 (
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types"
)
@ -16,7 +17,7 @@ Accumulation/Distribution Indicator (A/D)
type AD struct {
types.SeriesBase
types.IntervalWindow
Values types.Float64Slice
Values floats.Slice
PrePrice float64
EndTime time.Time

View File

@ -3,6 +3,7 @@ package indicator
import (
"math"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types"
)
@ -19,9 +20,9 @@ type ALMA struct {
Sigma int // required: recommend to be 5
weight []float64
sum float64
input []float64
Values types.Float64Slice
UpdateCallbacks []func(value float64)
input []float64
Values floats.Slice
UpdateCallbacks []func(value float64)
}
const MaxNumOfALMA = 5_000

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
@ -30,7 +31,7 @@ func Test_calculateOBV(t *testing.T) {
name string
kLines []types.KLine
window int
want types.Float64Slice
want floats.Slice
}{
{
name: "trivial_case",
@ -38,13 +39,13 @@ func Test_calculateOBV(t *testing.T) {
[]fixedpoint.Value{fixedpoint.Zero}, []fixedpoint.Value{fixedpoint.One},
),
window: 0,
want: types.Float64Slice{1.0},
want: floats.Slice{1.0},
},
{
name: "easy_case",
kLines: buildKLines(input1, input2),
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"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types"
)
@ -15,8 +16,8 @@ type Pivot struct {
types.IntervalWindow
// Values
Lows types.Float64Slice // higher low
Highs types.Float64Slice // lower high
Lows floats.Slice // higher low
Highs floats.Slice // lower high
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)
}
var lows types.Float64Slice
var highs types.Float64Slice
var lows floats.Slice
var highs floats.Slice
for _, k := range klines {
lows.Push(valLow(k))
highs.Push(valHigh(k))

View File

@ -3,6 +3,7 @@ package indicator
import (
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/types"
)
@ -12,8 +13,8 @@ type PivotLow struct {
types.IntervalWindow
Lows types.Float64Slice
Values types.Float64Slice
Lows floats.Slice
Values floats.Slice
EndTime time.Time
updateCallbacks []func(value float64)
@ -62,7 +63,7 @@ func (inc *PivotLow) PushK(k types.KLine) {
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)
if right == 0 {
@ -91,13 +92,13 @@ func calculatePivotF(values types.Float64Slice, left, right int, f func(a, pivot
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 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 a > pivot
})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ import (
"github.com/wcharczuk/go-chart/v2"
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/indicator"
"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)
}
profit := types.Float64Slice{1., 1.}
profit := floats.Slice{1., 1.}
price, _ := s.Session.LastPrice(s.Symbol)
initAsset := s.CalcAssetValue(price).Float64()
cumProfit := types.Float64Slice{initAsset, initAsset}
cumProfit := floats.Slice{initAsset, initAsset}
modify := func(p float64) float64 {
return p
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/indicator"
"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
// (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.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],
@ -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], ...]
// 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
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 y []types.Series

View File

@ -2,9 +2,11 @@ package fmaker
import (
"fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"time"
)
//go:generate callbackgen -type A18
@ -12,7 +14,7 @@ type A18 struct {
types.IntervalWindow
// Values
Values types.Float64Slice
Values floats.Slice
EndTime time.Time
@ -76,7 +78,7 @@ func calculateA18(klines []types.KLine, valClose KLineValueMapper) (float64, err
if length == 0 || length < 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 {
closes.Push(valClose(k))

View File

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

View File

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

View File

@ -2,9 +2,11 @@ package fmaker
import (
"fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"time"
)
//go:generate callbackgen -type A34
@ -12,7 +14,7 @@ type A34 struct {
types.IntervalWindow
// Values
Values types.Float64Slice
Values floats.Slice
EndTime time.Time
@ -75,7 +77,7 @@ func calculateA34(klines []types.KLine, valClose KLineValueMapper) (float64, err
if length == 0 || length < 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 {
closes.Push(valClose(k))

View File

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

View File

@ -2,9 +2,11 @@ package fmaker
import (
"fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"time"
)
//go:generate callbackgen -type S0
@ -12,7 +14,7 @@ type S0 struct {
types.IntervalWindow
// Values
Values types.Float64Slice
Values floats.Slice
EndTime time.Time
@ -75,13 +77,13 @@ func calculateS0(klines []types.KLine, valClose KLineValueMapper) (float64, erro
if length == 0 || length < 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 {
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()
return alpha, nil

View File

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

View File

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

View File

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

View File

@ -2,9 +2,11 @@ package fmaker
import (
"fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"time"
)
//go:generate callbackgen -type S4
@ -12,7 +14,7 @@ type S4 struct {
types.IntervalWindow
// Values
Values types.Float64Slice
Values floats.Slice
EndTime time.Time
@ -75,7 +77,7 @@ func calculateS4(klines []types.KLine, valClose KLineValueMapper) (float64, erro
if length == 0 || length < 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 {
closes.Push(valClose(k))

View File

@ -2,9 +2,11 @@ package fmaker
import (
"fmt"
"time"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/indicator"
"github.com/c9s/bbgo/pkg/types"
"time"
)
//go:generate callbackgen -type S5
@ -12,7 +14,7 @@ type S5 struct {
types.IntervalWindow
// Values
Values types.Float64Slice
Values floats.Slice
EndTime time.Time
@ -75,7 +77,7 @@ func calculateS5(klines []types.KLine, valVolume KLineValueMapper) (float64, err
if length == 0 || length < 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 {
volumes.Push(valVolume(k))

View File

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

View File

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

View File

@ -10,6 +10,7 @@ import (
"gonum.org/v1/gonum/floats"
"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/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]
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-- {
// 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.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)
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]
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-- {
// 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])
// 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{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)
// if float64(s.Position.GetBase().Sign())*er < 0 {
// 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/datasource/glassnode"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
"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 {
m := types.FloatMap{}
m := floats.Map{}
// get market cap values
for _, currency := range s.TargetCurrencies {

View File

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

View File

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

View File

@ -1,42 +1,5 @@
package types
type FloatMap map[string]float64
import "github.com/c9s/bbgo/pkg/datatype/floats"
func (m FloatMap) Sum() float64 {
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
}
var _ Series = floats.Slice([]float64{}).Addr()

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"
"gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
)
// Super basic Series type that simply holds the float64 data
@ -94,7 +96,7 @@ type SeriesExtend interface {
Mul(b interface{}) SeriesExtend
Dot(b interface{}, limit ...int) float64
Array(limit ...int) (result []float64)
Reverse(limit ...int) (result Float64Slice)
Reverse(limit ...int) (result floats.Slice)
Change(offset ...int) SeriesExtend
PercentageChange(offset ...int) SeriesExtend
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)
//
// 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()
if len(limit) > 0 && l > limit[0] {
l = limit[0]

View File

@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/wcharczuk/go-chart/v2"
"gonum.org/v1/gonum/stat"
"github.com/c9s/bbgo/pkg/datatype/floats"
)
func TestFloat(t *testing.T) {
@ -19,7 +21,7 @@ func TestFloat(t *testing.T) {
func TestNextCross(t *testing.T) {
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
// predicted 40 20 0
// offset 1 2 3
@ -31,8 +33,8 @@ func TestNextCross(t *testing.T) {
}
func TestFloat64Slice(t *testing.T) {
var a = Float64Slice{1.0, 2.0, 3.0}
var b = Float64Slice{1.0, 2.0, 3.0}
var a = floats.Slice{1.0, 2.0, 3.0}
var b = floats.Slice{1.0, 2.0, 3.0}
var c Series = Minus(&a, &b)
a = append(a, 4.0)
b = append(b, 3.0)
@ -51,8 +53,8 @@ print(s1.corr(s2, method='kendall'))
print(s1.rank())
*/
func TestCorr(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1}
var a = floats.Slice{.2, .0, .6, .2}
var b = floats.Slice{.3, .6, .0, .1}
corr := Correlation(&a, &b, 4, Pearson)
assert.InDelta(t, corr, -0.8510644, 0.001)
out := Rank(&a, 4)
@ -71,8 +73,8 @@ s2 = pd.Series([.3, .6, .0, .1])
print(s1.cov(s2, ddof=0))
*/
func TestCov(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1}
var a = floats.Slice{.2, .0, .6, .2}
var b = floats.Slice{.3, .6, .0, .1}
cov := Covariance(&a, &b, 4)
assert.InDelta(t, cov, -0.042499, 0.001)
}
@ -85,37 +87,37 @@ s1 = pd.Series([.2, 0., .6, .2, .2])
print(s1.skew())
*/
func TestSkew(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2}
var a = floats.Slice{.2, .0, .6, .2}
sk := Skew(&a, 4)
assert.InDelta(t, sk, 1.129338, 0.001)
}
func TestEntropy(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2}
var a = floats.Slice{.2, .0, .6, .2}
e := stat.Entropy(a)
assert.InDelta(t, e, Entropy(&a, a.Length()), 0.0001)
}
func TestCrossEntropy(t *testing.T) {
var a = Float64Slice{.2, .0, .6, .2}
var b = Float64Slice{.3, .6, .0, .1}
var a = floats.Slice{.2, .0, .6, .2}
var b = floats.Slice{.3, .6, .0, .1}
e := stat.CrossEntropy(a, b)
assert.InDelta(t, e, CrossEntropy(&a, &b, a.Length()), 0.0001)
}
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())
r := Float64Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916}
r := floats.Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916}
for i := 0; i < out.Length(); i++ {
assert.InDelta(t, r.Index(i), out.Index(i), 0.001)
}
}
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)
r := Float64Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871}
r := floats.Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871}
for i := 0; i < out.Length(); i++ {
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
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}}
b := Float64Slice{0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1}
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 := 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
x = append(x, &a[0])
@ -139,8 +141,8 @@ func TestLogisticRegression(t *testing.T) {
}
func TestDot(t *testing.T) {
a := Float64Slice{7, 6, 5, 4, 3, 2, 1, 0}
b := Float64Slice{200., 201., 203., 204., 203., 199.}
a := floats.Slice{7, 6, 5, 4, 3, 2, 1, 0}
b := floats.Slice{200., 201., 203., 204., 203., 199.}
out1 := Dot(&a, &b, 3)
assert.InDelta(t, out1, 611., 0.001)
out2 := Dot(&a, 3., 2)
@ -160,7 +162,7 @@ func TestClone(t *testing.T) {
func TestPlot(t *testing.T) {
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)
assert.Equal(t, ct.Interval, Interval5m)
assert.Equal(t, ct.Series[0].(chart.TimeSeries).Len(), 4)

View File

@ -1,12 +1,15 @@
package types
import (
"github.com/stretchr/testify/assert"
"testing"
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/datatype/floats"
)
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)
assert.InDelta(t, output, 1, 0.0001)
}

View File

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

View File

@ -1,8 +1,11 @@
package types
import (
"github.com/stretchr/testify/assert"
"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))
*/
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)
assert.InDelta(t, output, 0.67586, 0.0001)
output = Sharpe(a, 252, false, false)

View File

@ -1,8 +1,11 @@
package types
import (
"github.com/stretchr/testify/assert"
"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))
*/
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)
assert.InDelta(t, output, 0.75661, 0.0001)
output = Sortino(a, 0.03, 252, false, false)

View File

@ -8,18 +8,19 @@ import (
"gopkg.in/yaml.v3"
"github.com/c9s/bbgo/pkg/datatype/floats"
"github.com/c9s/bbgo/pkg/fixedpoint"
)
type IntervalProfitCollector struct {
Interval Interval `json:"interval"`
Profits *Float64Slice `json:"profits"`
Timestamp *Float64Slice `json:"timestamp"`
Profits *floats.Slice `json:"profits"`
Timestamp *floats.Slice `json:"timestamp"`
tmpTime time.Time `json:"tmpTime"`
}
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