mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 14:55:16 +00:00
indicator: make parameters of update method consistent
This commit is contained in:
parent
b9c40b63ac
commit
167f9d3eaf
|
@ -22,12 +22,7 @@ type AD struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *AD) Update(kLine types.KLine) {
|
func (inc *AD) Update(high, low, cloze, volume float64) {
|
||||||
cloze := kLine.Close.Float64()
|
|
||||||
high := kLine.High.Float64()
|
|
||||||
low := kLine.Low.Float64()
|
|
||||||
volume := kLine.Volume.Float64()
|
|
||||||
|
|
||||||
var moneyFlowVolume float64
|
var moneyFlowVolume float64
|
||||||
if high == low {
|
if high == low {
|
||||||
moneyFlowVolume = 0
|
moneyFlowVolume = 0
|
||||||
|
@ -65,7 +60,7 @@ func (inc *AD) calculateAndUpdate(kLines []types.KLine) {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k)
|
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64(), k.Volume.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.Last())
|
inc.EmitUpdate(inc.Last())
|
||||||
|
|
|
@ -19,17 +19,13 @@ type ATR struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *ATR) Update(kLine types.KLine) {
|
func (inc *ATR) Update(high, low, cloze float64) {
|
||||||
if inc.Window <= 0 {
|
if inc.Window <= 0 {
|
||||||
panic("window must be greater than 0")
|
panic("window must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
cloze := kLine.Close.Float64()
|
|
||||||
high := kLine.High.Float64()
|
|
||||||
low := kLine.Low.Float64()
|
|
||||||
|
|
||||||
if inc.PriviousClose == 0 {
|
if inc.PriviousClose == 0 {
|
||||||
inc.PriviousClose = kLine.Close.Float64()
|
inc.PriviousClose = cloze
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +83,7 @@ func (inc *ATR) calculateAndUpdate(kLines []types.KLine) {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k)
|
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.Last())
|
inc.EmitUpdate(inc.Last())
|
||||||
|
|
|
@ -29,25 +29,16 @@ type MACD struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *MACD) calculateMACD(kLines []types.KLine, priceF KLinePriceMapper) float64 {
|
func (inc *MACD) Update(x float64) {
|
||||||
for _, kline := range kLines {
|
|
||||||
inc.Update(kline, priceF)
|
|
||||||
}
|
|
||||||
return inc.Values[len(inc.Values)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (inc *MACD) Update(kLine types.KLine, priceF KLinePriceMapper) {
|
|
||||||
if len(inc.Values) == 0 {
|
if len(inc.Values) == 0 {
|
||||||
inc.FastEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.ShortPeriod}}
|
inc.FastEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.ShortPeriod}}
|
||||||
inc.SlowEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.LongPeriod}}
|
inc.SlowEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.LongPeriod}}
|
||||||
inc.SignalLine = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.Window}}
|
inc.SignalLine = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.Window}}
|
||||||
}
|
}
|
||||||
|
|
||||||
price := priceF(kLine)
|
|
||||||
|
|
||||||
// update fast and slow ema
|
// update fast and slow ema
|
||||||
inc.FastEWMA.Update(price)
|
inc.FastEWMA.Update(x)
|
||||||
inc.SlowEWMA.Update(price)
|
inc.SlowEWMA.Update(x)
|
||||||
|
|
||||||
// update macd
|
// update macd
|
||||||
macd := inc.FastEWMA.Last() - inc.SlowEWMA.Last()
|
macd := inc.FastEWMA.Last() - inc.SlowEWMA.Last()
|
||||||
|
@ -60,18 +51,23 @@ func (inc *MACD) Update(kLine types.KLine, priceF KLinePriceMapper) {
|
||||||
inc.Histogram.Push(macd - inc.SignalLine.Last())
|
inc.Histogram.Push(macd - inc.SignalLine.Last())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (inc *MACD) calculateMACD(kLines []types.KLine, priceF KLinePriceMapper) float64 {
|
||||||
|
for _, kline := range kLines {
|
||||||
|
inc.Update(kline.Close.Float64())
|
||||||
|
}
|
||||||
|
return inc.Values[len(inc.Values)-1]
|
||||||
|
}
|
||||||
|
|
||||||
func (inc *MACD) calculateAndUpdate(kLines []types.KLine) {
|
func (inc *MACD) calculateAndUpdate(kLines []types.KLine) {
|
||||||
if len(kLines) == 0 {
|
if len(kLines) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var priceF = KLineClosePriceMapper
|
|
||||||
|
|
||||||
for _, k := range kLines {
|
for _, k := range kLines {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k, priceF)
|
inc.Update(k.Close.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.Values[len(inc.Values)-1])
|
inc.EmitUpdate(inc.Values[len(inc.Values)-1])
|
||||||
|
|
|
@ -22,10 +22,7 @@ type OBV struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *OBV) Update(kLine types.KLine, priceF KLinePriceMapper) {
|
func (inc *OBV) Update(price, volume float64) {
|
||||||
price := priceF(kLine)
|
|
||||||
volume := kLine.Volume.Float64()
|
|
||||||
|
|
||||||
if len(inc.Values) == 0 {
|
if len(inc.Values) == 0 {
|
||||||
inc.PrePrice = price
|
inc.PrePrice = price
|
||||||
inc.Values.Push(volume)
|
inc.Values.Push(volume)
|
||||||
|
@ -47,17 +44,16 @@ func (inc *OBV) Last() float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *OBV) calculateAndUpdate(kLines []types.KLine) {
|
func (inc *OBV) calculateAndUpdate(kLines []types.KLine) {
|
||||||
var priceF = KLineClosePriceMapper
|
|
||||||
|
|
||||||
for _, k := range kLines {
|
for _, k := range kLines {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k, priceF)
|
inc.Update(k.Close.Float64(), k.Volume.Float64())
|
||||||
}
|
}
|
||||||
inc.EmitUpdate(inc.Last())
|
inc.EmitUpdate(inc.Last())
|
||||||
inc.EndTime = kLines[len(kLines)-1].EndTime.Time()
|
inc.EndTime = kLines[len(kLines)-1].EndTime.Time()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *OBV) handleKLineWindowUpdate(interval types.Interval, window types.KLineWindow) {
|
func (inc *OBV) handleKLineWindowUpdate(interval types.Interval, window types.KLineWindow) {
|
||||||
if inc.Interval != interval {
|
if inc.Interval != interval {
|
||||||
return
|
return
|
||||||
|
|
|
@ -24,8 +24,7 @@ type RSI struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *RSI) Update(kline types.KLine, priceF KLinePriceMapper) {
|
func (inc *RSI) Update(price float64) {
|
||||||
price := priceF(kline)
|
|
||||||
inc.Prices.Push(price)
|
inc.Prices.Push(price)
|
||||||
|
|
||||||
if len(inc.Prices) < inc.Window+1 {
|
if len(inc.Prices) < inc.Window+1 {
|
||||||
|
@ -78,13 +77,11 @@ func (inc *RSI) Length() int {
|
||||||
var _ types.Series = &RSI{}
|
var _ types.Series = &RSI{}
|
||||||
|
|
||||||
func (inc *RSI) calculateAndUpdate(kLines []types.KLine) {
|
func (inc *RSI) calculateAndUpdate(kLines []types.KLine) {
|
||||||
var priceF = KLineClosePriceMapper
|
|
||||||
|
|
||||||
for _, k := range kLines {
|
for _, k := range kLines {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k, priceF)
|
inc.Update(k.Close.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.Last())
|
inc.EmitUpdate(inc.Last())
|
||||||
|
|
|
@ -20,21 +20,21 @@ type STOCH struct {
|
||||||
K types.Float64Slice
|
K types.Float64Slice
|
||||||
D types.Float64Slice
|
D types.Float64Slice
|
||||||
|
|
||||||
KLineWindow types.KLineWindow
|
HighValues types.Float64Slice
|
||||||
|
LowValues types.Float64Slice
|
||||||
|
|
||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
UpdateCallbacks []func(k float64, d float64)
|
UpdateCallbacks []func(k float64, d float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inc *STOCH) update(kLine types.KLine) {
|
func (inc *STOCH) Update(high, low, cloze float64) {
|
||||||
inc.KLineWindow.Add(kLine)
|
inc.HighValues.Push(high)
|
||||||
inc.KLineWindow.Truncate(inc.Window)
|
inc.LowValues.Push(low)
|
||||||
|
|
||||||
lowest := inc.KLineWindow.GetLow().Float64()
|
lowest := inc.LowValues.Tail(inc.Window).Min()
|
||||||
highest := inc.KLineWindow.GetHigh().Float64()
|
highest := inc.HighValues.Tail(inc.Window).Max()
|
||||||
clos := kLine.Close.Float64()
|
|
||||||
|
|
||||||
k := 100.0 * (clos - lowest) / (highest - lowest)
|
k := 100.0 * (cloze - lowest) / (highest - lowest)
|
||||||
inc.K.Push(k)
|
inc.K.Push(k)
|
||||||
|
|
||||||
d := inc.K.Tail(DPeriod).Mean()
|
d := inc.K.Tail(DPeriod).Mean()
|
||||||
|
@ -64,7 +64,7 @@ func (inc *STOCH) calculateAndUpdate(kLines []types.KLine) {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.update(k)
|
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.LastK(), inc.LastD())
|
inc.EmitUpdate(inc.LastK(), inc.LastD())
|
||||||
|
|
|
@ -28,6 +28,23 @@ type VWAP struct {
|
||||||
UpdateCallbacks []func(value float64)
|
UpdateCallbacks []func(value float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (inc *VWAP) Update(price, volume float64) {
|
||||||
|
inc.Prices.Push(price)
|
||||||
|
inc.Volumes.Push(volume)
|
||||||
|
|
||||||
|
if inc.Window != 0 && len(inc.Prices) > inc.Window {
|
||||||
|
popIndex := len(inc.Prices) - inc.Window - 1
|
||||||
|
inc.WeightedSum -= inc.Prices[popIndex] * inc.Volumes[popIndex]
|
||||||
|
inc.VolumeSum -= inc.Volumes[popIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
inc.WeightedSum += price * volume
|
||||||
|
inc.VolumeSum += volume
|
||||||
|
|
||||||
|
vwap := inc.WeightedSum / inc.VolumeSum
|
||||||
|
inc.Values.Push(vwap)
|
||||||
|
}
|
||||||
|
|
||||||
func (inc *VWAP) Last() float64 {
|
func (inc *VWAP) Last() float64 {
|
||||||
if len(inc.Values) == 0 {
|
if len(inc.Values) == 0 {
|
||||||
return 0.0
|
return 0.0
|
||||||
|
@ -50,26 +67,6 @@ func (inc *VWAP) Length() int {
|
||||||
|
|
||||||
var _ types.Series = &VWAP{}
|
var _ types.Series = &VWAP{}
|
||||||
|
|
||||||
func (inc *VWAP) Update(kLine types.KLine, priceF KLinePriceMapper) {
|
|
||||||
price := priceF(kLine)
|
|
||||||
volume := kLine.Volume.Float64()
|
|
||||||
|
|
||||||
inc.Prices.Push(price)
|
|
||||||
inc.Volumes.Push(volume)
|
|
||||||
|
|
||||||
if inc.Window != 0 && len(inc.Prices) > inc.Window {
|
|
||||||
popIndex := len(inc.Prices) - inc.Window - 1
|
|
||||||
inc.WeightedSum -= inc.Prices[popIndex] * inc.Volumes[popIndex]
|
|
||||||
inc.VolumeSum -= inc.Volumes[popIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
inc.WeightedSum += price * volume
|
|
||||||
inc.VolumeSum += volume
|
|
||||||
|
|
||||||
vwap := inc.WeightedSum / inc.VolumeSum
|
|
||||||
inc.Values.Push(vwap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (inc *VWAP) calculateAndUpdate(kLines []types.KLine) {
|
func (inc *VWAP) calculateAndUpdate(kLines []types.KLine) {
|
||||||
var priceF = KLineTypicalPriceMapper
|
var priceF = KLineTypicalPriceMapper
|
||||||
|
|
||||||
|
@ -77,7 +74,7 @@ func (inc *VWAP) calculateAndUpdate(kLines []types.KLine) {
|
||||||
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inc.Update(k, priceF)
|
inc.Update(priceF(k), k.Volume.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.EmitUpdate(inc.Last())
|
inc.EmitUpdate(inc.Last())
|
||||||
|
@ -99,7 +96,7 @@ func (inc *VWAP) Bind(updater KLineWindowUpdater) {
|
||||||
func CalculateVWAP(klines []types.KLine, priceF KLinePriceMapper, window int) float64 {
|
func CalculateVWAP(klines []types.KLine, priceF KLinePriceMapper, window int) float64 {
|
||||||
vwap := VWAP{IntervalWindow: types.IntervalWindow{Window: window}}
|
vwap := VWAP{IntervalWindow: types.IntervalWindow{Window: window}}
|
||||||
for _, k := range klines {
|
for _, k := range klines {
|
||||||
vwap.Update(k, priceF)
|
vwap.Update(priceF(k), k.Volume.Float64())
|
||||||
}
|
}
|
||||||
return vwap.Last()
|
return vwap.Last()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user