mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 01:01:56 +00:00
all: refactor and rename indicator.MACD to indicator.MACDLegacy
This commit is contained in:
parent
171e0678b6
commit
648e99f52a
|
@ -29,7 +29,7 @@ type StandardIndicatorSet struct {
|
||||||
// interval -> window
|
// interval -> window
|
||||||
iwbIndicators map[types.IntervalWindowBandWidth]*indicator.BOLL
|
iwbIndicators map[types.IntervalWindowBandWidth]*indicator.BOLL
|
||||||
iwIndicators map[indicatorKey]indicator.KLinePusher
|
iwIndicators map[indicatorKey]indicator.KLinePusher
|
||||||
macdIndicators map[indicator.MACDConfig]*indicator.MACD
|
macdIndicators map[indicator.MACDConfig]*indicator.MACDLegacy
|
||||||
|
|
||||||
stream types.Stream
|
stream types.Stream
|
||||||
store *MarketDataStore
|
store *MarketDataStore
|
||||||
|
@ -47,7 +47,7 @@ func NewStandardIndicatorSet(symbol string, stream types.Stream, store *MarketDa
|
||||||
stream: stream,
|
stream: stream,
|
||||||
iwIndicators: make(map[indicatorKey]indicator.KLinePusher),
|
iwIndicators: make(map[indicatorKey]indicator.KLinePusher),
|
||||||
iwbIndicators: make(map[types.IntervalWindowBandWidth]*indicator.BOLL),
|
iwbIndicators: make(map[types.IntervalWindowBandWidth]*indicator.BOLL),
|
||||||
macdIndicators: make(map[indicator.MACDConfig]*indicator.MACD),
|
macdIndicators: make(map[indicator.MACDConfig]*indicator.MACDLegacy),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,14 +154,14 @@ func (s *StandardIndicatorSet) BOLL(iw types.IntervalWindow, bandWidth float64)
|
||||||
return inc
|
return inc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StandardIndicatorSet) MACD(iw types.IntervalWindow, shortPeriod, longPeriod int) *indicator.MACD {
|
func (s *StandardIndicatorSet) MACD(iw types.IntervalWindow, shortPeriod, longPeriod int) *indicator.MACDLegacy {
|
||||||
config := indicator.MACDConfig{IntervalWindow: iw, ShortPeriod: shortPeriod, LongPeriod: longPeriod}
|
config := indicator.MACDConfig{IntervalWindow: iw, ShortPeriod: shortPeriod, LongPeriod: longPeriod}
|
||||||
|
|
||||||
inc, ok := s.macdIndicators[config]
|
inc, ok := s.macdIndicators[config]
|
||||||
if ok {
|
if ok {
|
||||||
return inc
|
return inc
|
||||||
}
|
}
|
||||||
inc = &indicator.MACD{MACDConfig: config}
|
inc = &indicator.MACDLegacy{MACDConfig: config}
|
||||||
s.macdIndicators[config] = inc
|
s.macdIndicators[config] = inc
|
||||||
s.initAndBind(inc, config.IntervalWindow.Interval)
|
s.initAndBind(inc, config.IntervalWindow.Interval)
|
||||||
return inc
|
return inc
|
||||||
|
|
6
pkg/indicator/float64updater.go
Normal file
6
pkg/indicator/float64updater.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package indicator
|
||||||
|
|
||||||
|
//go:generate callbackgen -type Float64Updater
|
||||||
|
type Float64Updater struct {
|
||||||
|
updateCallbacks []func(v float64)
|
||||||
|
}
|
37
pkg/indicator/klinestream.go
Normal file
37
pkg/indicator/klinestream.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package indicator
|
||||||
|
|
||||||
|
import "github.com/c9s/bbgo/pkg/types"
|
||||||
|
|
||||||
|
const MaxNumOfKLines = 4_000
|
||||||
|
|
||||||
|
//go:generate callbackgen -type KLineStream
|
||||||
|
type KLineStream struct {
|
||||||
|
updateCallbacks []func(k types.KLine)
|
||||||
|
|
||||||
|
kLines []types.KLine
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSubscriber adds the subscriber function and push histrical data to the subscriber
|
||||||
|
func (s *KLineStream) AddSubscriber(f func(k types.KLine)) {
|
||||||
|
if len(s.kLines) > 0 {
|
||||||
|
// push historical klines to the subscriber
|
||||||
|
}
|
||||||
|
|
||||||
|
s.OnUpdate(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KLines creates a KLine stream that pushes the klines to the subscribers
|
||||||
|
func KLines(source types.Stream) *KLineStream {
|
||||||
|
s := &KLineStream{}
|
||||||
|
|
||||||
|
source.OnKLineClosed(func(k types.KLine) {
|
||||||
|
s.kLines = append(s.kLines, k)
|
||||||
|
|
||||||
|
if len(s.kLines) > MaxNumOfKLines {
|
||||||
|
s.kLines = s.kLines[len(s.kLines)-1-MaxNumOfKLines:]
|
||||||
|
}
|
||||||
|
s.EmitUpdate(k)
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
|
@ -6,12 +6,12 @@ import (
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (K *KLineStream) OnUpdate(cb func(k types.KLine)) {
|
func (s *KLineStream) OnUpdate(cb func(k types.KLine)) {
|
||||||
K.updateCallbacks = append(K.updateCallbacks, cb)
|
s.updateCallbacks = append(s.updateCallbacks, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (K *KLineStream) EmitUpdate(k types.KLine) {
|
func (s *KLineStream) EmitUpdate(k types.KLine) {
|
||||||
for _, cb := range K.updateCallbacks {
|
for _, cb := range s.updateCallbacks {
|
||||||
cb(k)
|
cb(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,50 +23,6 @@ signal := EMA(macd, 16)
|
||||||
histogram := Subtract(macd, signal)
|
histogram := Subtract(macd, signal)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//go:generate callbackgen -type KLineStream
|
|
||||||
type KLineStream struct {
|
|
||||||
updateCallbacks []func(k types.KLine)
|
|
||||||
}
|
|
||||||
|
|
||||||
func KLines(source types.Stream) *KLineStream {
|
|
||||||
stream := &KLineStream{}
|
|
||||||
source.OnKLineClosed(stream.EmitUpdate)
|
|
||||||
return stream
|
|
||||||
}
|
|
||||||
|
|
||||||
type KLineSource interface {
|
|
||||||
OnUpdate(f func(k types.KLine))
|
|
||||||
}
|
|
||||||
|
|
||||||
type PriceStream struct {
|
|
||||||
types.SeriesBase
|
|
||||||
Float64Updater
|
|
||||||
|
|
||||||
slice floats.Slice
|
|
||||||
mapper KLineValueMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
func Price(source KLineSource, mapper KLineValueMapper) *PriceStream {
|
|
||||||
s := &PriceStream{
|
|
||||||
mapper: mapper,
|
|
||||||
}
|
|
||||||
s.SeriesBase.Series = s.slice
|
|
||||||
source.OnUpdate(func(k types.KLine) {
|
|
||||||
v := s.mapper(k)
|
|
||||||
s.slice.Push(v)
|
|
||||||
s.EmitUpdate(v)
|
|
||||||
})
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func ClosePrices(source KLineSource) *PriceStream {
|
|
||||||
return Price(source, KLineClosePriceMapper)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OpenPrices(source KLineSource) *PriceStream {
|
|
||||||
return Price(source, KLineOpenPriceMapper)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Float64Source interface {
|
type Float64Source interface {
|
||||||
types.Series
|
types.Series
|
||||||
OnUpdate(f func(v float64))
|
OnUpdate(f func(v float64))
|
||||||
|
@ -104,11 +60,6 @@ func (s *EWMAStream) calculate(v float64) float64 {
|
||||||
return (1.0-m)*last + m*v
|
return (1.0-m)*last + m*v
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate callbackgen -type Float64Updater
|
|
||||||
type Float64Updater struct {
|
|
||||||
updateCallbacks []func(v float64)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SubtractStream struct {
|
type SubtractStream struct {
|
||||||
Float64Updater
|
Float64Updater
|
||||||
types.SeriesBase
|
types.SeriesBase
|
||||||
|
|
|
@ -26,9 +26,5 @@ func TestSubtract(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, len(subtract.a), len(subtract.b))
|
assert.Equal(t, len(subtract.a), len(subtract.b))
|
||||||
assert.Equal(t, len(subtract.a), len(subtract.c))
|
assert.Equal(t, len(subtract.a), len(subtract.c))
|
||||||
assert.Equal(t, subtract.c[0], subtract.a[0]-subtract.b[0])
|
assert.InDelta(t, subtract.c[0], subtract.a[0]-subtract.b[0], 0.0001)
|
||||||
|
|
||||||
t.Logf("subtract.a: %+v", subtract.a)
|
|
||||||
t.Logf("subtract.b: %+v", subtract.b)
|
|
||||||
t.Logf("subtract.c: %+v", subtract.c)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// Code generated by "callbackgen -type MACD"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package indicator
|
|
||||||
|
|
||||||
import ()
|
|
||||||
|
|
||||||
func (inc *MACD) OnUpdate(cb func(macd float64, signal float64, histogram float64)) {
|
|
||||||
inc.updateCallbacks = append(inc.updateCallbacks, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (inc *MACD) EmitUpdate(macd float64, signal float64, histogram float64) {
|
|
||||||
for _, cb := range inc.updateCallbacks {
|
|
||||||
cb(macd, signal, histogram)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,20 +27,19 @@ type MACDConfig struct {
|
||||||
LongPeriod int `json:"long"`
|
LongPeriod int `json:"long"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate callbackgen -type MACD
|
//go:generate callbackgen -type MACDLegacy
|
||||||
type MACD struct {
|
type MACDLegacy struct {
|
||||||
MACDConfig
|
MACDConfig
|
||||||
|
|
||||||
Values floats.Slice `json:"-"`
|
Values floats.Slice `json:"-"`
|
||||||
fastEWMA, slowEWMA, signalLine *EWMA
|
fastEWMA, slowEWMA, signalLine *EWMA
|
||||||
Histogram floats.Slice `json:"-"`
|
Histogram floats.Slice `json:"-"`
|
||||||
|
|
||||||
EndTime time.Time
|
|
||||||
|
|
||||||
updateCallbacks []func(macd, signal, histogram float64)
|
updateCallbacks []func(macd, signal, histogram float64)
|
||||||
|
EndTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) Update(x float64) {
|
func (inc *MACDLegacy) Update(x float64) {
|
||||||
if len(inc.Values) == 0 {
|
if len(inc.Values) == 0 {
|
||||||
// apply default values
|
// apply default values
|
||||||
inc.fastEWMA = &EWMA{IntervalWindow: types.IntervalWindow{Window: inc.ShortPeriod}}
|
inc.fastEWMA = &EWMA{IntervalWindow: types.IntervalWindow{Window: inc.ShortPeriod}}
|
||||||
|
@ -76,7 +75,7 @@ func (inc *MACD) Update(x float64) {
|
||||||
inc.EmitUpdate(macd, signal, histogram)
|
inc.EmitUpdate(macd, signal, histogram)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) Last() float64 {
|
func (inc *MACDLegacy) Last() float64 {
|
||||||
if len(inc.Values) == 0 {
|
if len(inc.Values) == 0 {
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
@ -84,27 +83,27 @@ func (inc *MACD) Last() float64 {
|
||||||
return inc.Values[len(inc.Values)-1]
|
return inc.Values[len(inc.Values)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) Length() int {
|
func (inc *MACDLegacy) Length() int {
|
||||||
return len(inc.Values)
|
return len(inc.Values)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) PushK(k types.KLine) {
|
func (inc *MACDLegacy) PushK(k types.KLine) {
|
||||||
inc.Update(k.Close.Float64())
|
inc.Update(k.Close.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) MACD() types.SeriesExtend {
|
func (inc *MACDLegacy) MACD() types.SeriesExtend {
|
||||||
out := &MACDValues{MACD: inc}
|
out := &MACDValues{MACDLegacy: inc}
|
||||||
out.SeriesBase.Series = out
|
out.SeriesBase.Series = out
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) Singals() types.SeriesExtend {
|
func (inc *MACDLegacy) Singals() types.SeriesExtend {
|
||||||
return inc.signalLine
|
return inc.signalLine
|
||||||
}
|
}
|
||||||
|
|
||||||
type MACDValues struct {
|
type MACDValues struct {
|
||||||
types.SeriesBase
|
types.SeriesBase
|
||||||
*MACD
|
*MACDLegacy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACDValues) Last() float64 {
|
func (inc *MACDValues) Last() float64 {
|
15
pkg/indicator/macdlegacy_callbacks.go
Normal file
15
pkg/indicator/macdlegacy_callbacks.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Code generated by "callbackgen -type MACDLegacy"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package indicator
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
func (inc *MACDLegacy) OnUpdate(cb func(macd float64, signal float64, histogram float64)) {
|
||||||
|
inc.updateCallbacks = append(inc.updateCallbacks, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inc *MACDLegacy) EmitUpdate(macd float64, signal float64, histogram float64) {
|
||||||
|
for _, cb := range inc.updateCallbacks {
|
||||||
|
cb(macd, signal, histogram)
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ func Test_calculateMACD(t *testing.T) {
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
iw := types.IntervalWindow{Window: 9}
|
iw := types.IntervalWindow{Window: 9}
|
||||||
macd := MACD{MACDConfig: MACDConfig{IntervalWindow: iw, ShortPeriod: 12, LongPeriod: 26}}
|
macd := MACDLegacy{MACDConfig: MACDConfig{IntervalWindow: iw, ShortPeriod: 12, LongPeriod: 26}}
|
||||||
for _, k := range tt.kLines {
|
for _, k := range tt.kLines {
|
||||||
macd.PushK(k)
|
macd.PushK(k)
|
||||||
}
|
}
|
47
pkg/indicator/price.go
Normal file
47
pkg/indicator/price.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package indicator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/c9s/bbgo/pkg/datatype/floats"
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KLineSource interface {
|
||||||
|
OnUpdate(f func(k types.KLine))
|
||||||
|
}
|
||||||
|
|
||||||
|
type PriceStream struct {
|
||||||
|
types.SeriesBase
|
||||||
|
Float64Updater
|
||||||
|
|
||||||
|
slice floats.Slice
|
||||||
|
mapper KLineValueMapper
|
||||||
|
}
|
||||||
|
|
||||||
|
func Price(source KLineSource, mapper KLineValueMapper) *PriceStream {
|
||||||
|
s := &PriceStream{
|
||||||
|
mapper: mapper,
|
||||||
|
}
|
||||||
|
s.SeriesBase.Series = s.slice
|
||||||
|
source.OnUpdate(func(k types.KLine) {
|
||||||
|
v := s.mapper(k)
|
||||||
|
s.slice.Push(v)
|
||||||
|
s.EmitUpdate(v)
|
||||||
|
})
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClosePrices(source KLineSource) *PriceStream {
|
||||||
|
return Price(source, KLineClosePriceMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LowPrices(source KLineSource) *PriceStream {
|
||||||
|
return Price(source, KLineLowPriceMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HighPrices(source KLineSource) *PriceStream {
|
||||||
|
return Price(source, KLineHighPriceMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
func OpenPrices(source KLineSource) *PriceStream {
|
||||||
|
return Price(source, KLineOpenPriceMapper)
|
||||||
|
}
|
|
@ -47,7 +47,7 @@ type FailedBreakHigh struct {
|
||||||
|
|
||||||
MACDDivergence *MACDDivergence `json:"macdDivergence"`
|
MACDDivergence *MACDDivergence `json:"macdDivergence"`
|
||||||
|
|
||||||
macd *indicator.MACD
|
macd *indicator.MACDLegacy
|
||||||
|
|
||||||
macdTopDivergence bool
|
macdTopDivergence bool
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user