mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-14 02:53:50 +00:00
Merge pull request #778 from zenixls2/feature/series_extend
feature: add seriesExtend
This commit is contained in:
commit
6b6686caa8
|
@ -266,7 +266,7 @@ func (s *Strategy) SetupIndicators(store *bbgo.MarketDataStore) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ema5.Length() == 0 {
|
if ema5.Length() == 0 {
|
||||||
closes := types.ToReverseArray(getSource(window))
|
closes := types.Reverse(getSource(window))
|
||||||
for _, cloze := range closes {
|
for _, cloze := range closes {
|
||||||
ema5.Update(cloze)
|
ema5.Update(cloze)
|
||||||
ema34.Update(cloze)
|
ema34.Update(cloze)
|
||||||
|
@ -289,7 +289,7 @@ func (s *Strategy) SetupIndicators(store *bbgo.MarketDataStore) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if sma5.Length() == 0 {
|
if sma5.Length() == 0 {
|
||||||
closes := types.ToReverseArray(getSource(window))
|
closes := types.Reverse(getSource(window))
|
||||||
for _, cloze := range closes {
|
for _, cloze := range closes {
|
||||||
sma5.Update(cloze)
|
sma5.Update(cloze)
|
||||||
sma34.Update(cloze)
|
sma34.Update(cloze)
|
||||||
|
@ -347,7 +347,7 @@ func (s *Strategy) SetupIndicators(store *bbgo.MarketDataStore) {
|
||||||
|
|
||||||
if sig.Length() == 0 {
|
if sig.Length() == 0 {
|
||||||
// lazy init
|
// lazy init
|
||||||
ewoVals := types.ToReverseArray(s.ewo)
|
ewoVals := types.Reverse(s.ewo)
|
||||||
for _, ewoValue := range ewoVals {
|
for _, ewoValue := range ewoVals {
|
||||||
sig.Update(ewoValue)
|
sig.Update(ewoValue)
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ func (s *Strategy) SetupIndicators(store *bbgo.MarketDataStore) {
|
||||||
|
|
||||||
if sig.Length() == 0 {
|
if sig.Length() == 0 {
|
||||||
// lazy init
|
// lazy init
|
||||||
ewoVals := types.ToReverseArray(s.ewo)
|
ewoVals := types.Reverse(s.ewo)
|
||||||
for _, ewoValue := range ewoVals {
|
for _, ewoValue := range ewoVals {
|
||||||
sig.Update(ewoValue)
|
sig.Update(ewoValue)
|
||||||
}
|
}
|
||||||
|
@ -385,7 +385,7 @@ func (s *Strategy) SetupIndicators(store *bbgo.MarketDataStore) {
|
||||||
}
|
}
|
||||||
if sig.Length() == 0 {
|
if sig.Length() == 0 {
|
||||||
// lazy init
|
// lazy init
|
||||||
ewoVals := types.ToReverseArray(s.ewo)
|
ewoVals := types.Reverse(s.ewo)
|
||||||
for i, ewoValue := range ewoVals {
|
for i, ewoValue := range ewoVals {
|
||||||
vol := window.Volume().Index(i)
|
vol := window.Volume().Index(i)
|
||||||
sig.PV.Update(ewoValue * vol)
|
sig.PV.Update(ewoValue * vol)
|
||||||
|
|
|
@ -63,6 +63,46 @@ type Series interface {
|
||||||
Length() int
|
Length() int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SeriesExtend interface {
|
||||||
|
Series
|
||||||
|
Sum(limit ...int) float64
|
||||||
|
Mean(limit ...int) float64
|
||||||
|
Abs() SeriesExtend
|
||||||
|
Predict(lookback int, offset ...int) float64
|
||||||
|
NextCross(b Series, lookback int) (int, float64, bool)
|
||||||
|
CrossOver(b Series) BoolSeries
|
||||||
|
CrossUnder(b Series) BoolSeries
|
||||||
|
Highest(lookback int) float64
|
||||||
|
Lowest(lookback int) float64
|
||||||
|
Add(b interface{}) SeriesExtend
|
||||||
|
Minus(b interface{}) SeriesExtend
|
||||||
|
Div(b interface{}) SeriesExtend
|
||||||
|
Mul(b interface{}) SeriesExtend
|
||||||
|
Dot(b interface{}, limit ...int) float64
|
||||||
|
Array(limit ...int) (result []float64)
|
||||||
|
Reverse(limit ...int) (result Float64Slice)
|
||||||
|
Change(offset ...int) SeriesExtend
|
||||||
|
Stdev(length int) float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexFuncType func(int) float64
|
||||||
|
type LastFuncType func() float64
|
||||||
|
type LengthFuncType func() int
|
||||||
|
|
||||||
|
type SeriesBase struct {
|
||||||
|
index IndexFuncType
|
||||||
|
last LastFuncType
|
||||||
|
length LengthFuncType
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSeries(a Series) SeriesExtend {
|
||||||
|
return &SeriesBase{
|
||||||
|
index: a.Index,
|
||||||
|
last: a.Last,
|
||||||
|
length: a.Length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type UpdatableSeries interface {
|
type UpdatableSeries interface {
|
||||||
Series
|
Series
|
||||||
Update(float64)
|
Update(float64)
|
||||||
|
@ -125,8 +165,8 @@ func (a *AbsResult) Length() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return series that having all the elements positive
|
// Return series that having all the elements positive
|
||||||
func Abs(a Series) Series {
|
func Abs(a Series) SeriesExtend {
|
||||||
return &AbsResult{a}
|
return NewSeries(&AbsResult{a})
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Series = &AbsResult{}
|
var _ Series = &AbsResult{}
|
||||||
|
@ -291,7 +331,7 @@ type AddSeriesResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add two series, result[i] = a[i] + b[i]
|
// Add two series, result[i] = a[i] + b[i]
|
||||||
func Add(a interface{}, b interface{}) Series {
|
func Add(a interface{}, b interface{}) SeriesExtend {
|
||||||
var aa Series
|
var aa Series
|
||||||
var bb Series
|
var bb Series
|
||||||
|
|
||||||
|
@ -313,7 +353,7 @@ func Add(a interface{}, b interface{}) Series {
|
||||||
panic("input should be either *Series or float64")
|
panic("input should be either *Series or float64")
|
||||||
|
|
||||||
}
|
}
|
||||||
return &AddSeriesResult{aa, bb}
|
return NewSeries(&AddSeriesResult{aa, bb})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AddSeriesResult) Last() float64 {
|
func (a *AddSeriesResult) Last() float64 {
|
||||||
|
@ -341,10 +381,10 @@ type MinusSeriesResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minus two series, result[i] = a[i] - b[i]
|
// Minus two series, result[i] = a[i] - b[i]
|
||||||
func Minus(a interface{}, b interface{}) Series {
|
func Minus(a interface{}, b interface{}) SeriesExtend {
|
||||||
aa := switchIface(a)
|
aa := switchIface(a)
|
||||||
bb := switchIface(b)
|
bb := switchIface(b)
|
||||||
return &MinusSeriesResult{aa, bb}
|
return NewSeries(&MinusSeriesResult{aa, bb})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *MinusSeriesResult) Last() float64 {
|
func (a *MinusSeriesResult) Last() float64 {
|
||||||
|
@ -388,13 +428,13 @@ func switchIface(b interface{}) Series {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divid two series, result[i] = a[i] / b[i]
|
// Divid two series, result[i] = a[i] / b[i]
|
||||||
func Div(a interface{}, b interface{}) Series {
|
func Div(a interface{}, b interface{}) SeriesExtend {
|
||||||
aa := switchIface(a)
|
aa := switchIface(a)
|
||||||
if 0 == b {
|
if 0 == b {
|
||||||
panic("Divid by zero exception")
|
panic("Divid by zero exception")
|
||||||
}
|
}
|
||||||
bb := switchIface(b)
|
bb := switchIface(b)
|
||||||
return &DivSeriesResult{aa, bb}
|
return NewSeries(&DivSeriesResult{aa, bb})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +463,7 @@ func (a *DivSeriesResult) Length() int {
|
||||||
var _ Series = &DivSeriesResult{}
|
var _ Series = &DivSeriesResult{}
|
||||||
|
|
||||||
// Multiple two series, result[i] = a[i] * b[i]
|
// Multiple two series, result[i] = a[i] * b[i]
|
||||||
func Mul(a interface{}, b interface{}) Series {
|
func Mul(a interface{}, b interface{}) SeriesExtend {
|
||||||
var aa Series
|
var aa Series
|
||||||
var bb Series
|
var bb Series
|
||||||
|
|
||||||
|
@ -444,7 +484,7 @@ func Mul(a interface{}, b interface{}) Series {
|
||||||
panic("input should be either Series or float64")
|
panic("input should be either Series or float64")
|
||||||
|
|
||||||
}
|
}
|
||||||
return &MulSeriesResult{aa, bb}
|
return NewSeries(&MulSeriesResult{aa, bb})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +522,7 @@ func Dot(a interface{}, b interface{}, limit ...int) float64 {
|
||||||
// Extract elements from the Series to a float64 array, following the order of Index(0..limit)
|
// Extract elements from the Series to a float64 array, following the order of Index(0..limit)
|
||||||
// if limit is given, will only take the first limit numbers (a.Index[0..limit])
|
// if limit is given, will only take the first limit numbers (a.Index[0..limit])
|
||||||
// otherwise will operate on all elements
|
// otherwise will operate on all elements
|
||||||
func ToArray(a Series, limit ...int) (result []float64) {
|
func Array(a Series, limit ...int) (result []float64) {
|
||||||
l := -1
|
l := -1
|
||||||
if len(limit) > 0 {
|
if len(limit) > 0 {
|
||||||
l = limit[0]
|
l = limit[0]
|
||||||
|
@ -497,12 +537,12 @@ func ToArray(a Series, limit ...int) (result []float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to ToArray but in reverse order.
|
// Similar to Array but in reverse order.
|
||||||
// Useful when you want to cache series' calculated result as float64 array
|
// Useful when you want to cache series' calculated result as float64 array
|
||||||
// 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 ToReverseArray(a Series, limit ...int) (result Float64Slice) {
|
func Reverse(a Series, limit ...int) (result Float64Slice) {
|
||||||
l := -1
|
l := -1
|
||||||
if len(limit) > 0 {
|
if len(limit) > 0 {
|
||||||
l = limit[0]
|
l = limit[0]
|
||||||
|
@ -546,13 +586,13 @@ func (c *ChangeResult) Length() int {
|
||||||
|
|
||||||
// Difference between current value and previous, a - a[offset]
|
// Difference between current value and previous, a - a[offset]
|
||||||
// offset: if not given, offset is 1.
|
// offset: if not given, offset is 1.
|
||||||
func Change(a Series, offset ...int) Series {
|
func Change(a Series, offset ...int) SeriesExtend {
|
||||||
o := 1
|
o := 1
|
||||||
if len(offset) > 0 {
|
if len(offset) > 0 {
|
||||||
o = offset[0]
|
o = offset[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ChangeResult{a, o}
|
return NewSeries(&ChangeResult{a, o})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stdev(a Series, length int) float64 {
|
func Stdev(a Series, length int) float64 {
|
||||||
|
|
85
pkg/types/seriesbase_imp.go
Normal file
85
pkg/types/seriesbase_imp.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
func (s *SeriesBase) Index(i int) float64 {
|
||||||
|
return s.index(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Last() float64 {
|
||||||
|
return s.last()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Length() int {
|
||||||
|
return s.length()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Sum(limit ...int) float64 {
|
||||||
|
return Sum(s, limit...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Mean(limit ...int) float64 {
|
||||||
|
return Mean(s, limit...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Abs() SeriesExtend {
|
||||||
|
return Abs(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Predict(lookback int, offset ...int) float64 {
|
||||||
|
return Predict(s, lookback, offset...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) NextCross(b Series, lookback int) (int, float64, bool) {
|
||||||
|
return NextCross(s, b, lookback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) CrossOver(b Series) BoolSeries {
|
||||||
|
return CrossOver(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) CrossUnder(b Series) BoolSeries {
|
||||||
|
return CrossUnder(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Highest(lookback int) float64 {
|
||||||
|
return Highest(s, lookback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Lowest(lookback int) float64 {
|
||||||
|
return Lowest(s, lookback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Add(b interface{}) SeriesExtend {
|
||||||
|
return Add(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Minus(b interface{}) SeriesExtend {
|
||||||
|
return Minus(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Div(b interface{}) SeriesExtend {
|
||||||
|
return Div(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Mul(b interface{}) SeriesExtend {
|
||||||
|
return Mul(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Dot(b interface{}, limit ...int) float64 {
|
||||||
|
return Dot(s, b, limit...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Array(limit ...int) (result []float64) {
|
||||||
|
return Array(s, limit...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Reverse(limit ...int) (result Float64Slice) {
|
||||||
|
return Reverse(s, limit...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Change(offset ...int) SeriesExtend {
|
||||||
|
return Change(s, offset...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SeriesBase) Stdev(length int) float64 {
|
||||||
|
return Stdev(s, length)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user