mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 00:05:15 +00:00
all: move float slice/map to a single package
This commit is contained in:
parent
de4f3721a2
commit
5953fe49d1
42
pkg/datatype/floats/map.go
Normal file
42
pkg/datatype/floats/map.go
Normal 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
|
||||||
|
}
|
151
pkg/datatype/floats/slice.go
Normal file
151
pkg/datatype/floats/slice.go
Normal 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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,9 +20,9 @@ type ALMA struct {
|
||||||
Sigma int // required: recommend to be 5
|
Sigma int // required: recommend to be 5
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
const MaxNumOfALMA = 5_000
|
const MaxNumOfALMA = 5_000
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,9 +10,9 @@ import (
|
||||||
//go:generate callbackgen -type CA
|
//go:generate callbackgen -type CA
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,9 +14,9 @@ import (
|
||||||
type Drift struct {
|
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
|
||||||
|
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) +
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,9 +14,9 @@ import (
|
||||||
type WeightedDrift struct {
|
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
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,8 +19,8 @@ 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
|
||||||
|
|
||||||
updateCallbacks []func(value float64)
|
updateCallbacks []func(value float64)
|
||||||
|
|
|
@ -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,8 +23,8 @@ 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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,8 +13,8 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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()
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user