Skip to content

Commit

Permalink
indicator: make parameters of update method consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
narumiruna committed Apr 19, 2022
1 parent b9c40b6 commit 167f9d3
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 72 deletions.
9 changes: 2 additions & 7 deletions pkg/indicator/ad.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ type AD struct {
UpdateCallbacks []func(value float64)
}

func (inc *AD) Update(kLine types.KLine) {
cloze := kLine.Close.Float64()
high := kLine.High.Float64()
low := kLine.Low.Float64()
volume := kLine.Volume.Float64()

func (inc *AD) Update(high, low, cloze, volume float64) {
var moneyFlowVolume float64
if high == low {
moneyFlowVolume = 0
Expand Down Expand Up @@ -65,7 +60,7 @@ func (inc *AD) calculateAndUpdate(kLines []types.KLine) {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k)
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64(), k.Volume.Float64())
}

inc.EmitUpdate(inc.Last())
Expand Down
10 changes: 3 additions & 7 deletions pkg/indicator/atr.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@ type ATR struct {
UpdateCallbacks []func(value float64)
}

func (inc *ATR) Update(kLine types.KLine) {
func (inc *ATR) Update(high, low, cloze float64) {
if inc.Window <= 0 {
panic("window must be greater than 0")
}

cloze := kLine.Close.Float64()
high := kLine.High.Float64()
low := kLine.Low.Float64()

if inc.PriviousClose == 0 {
inc.PriviousClose = kLine.Close.Float64()
inc.PriviousClose = cloze
return
}

Expand Down Expand Up @@ -87,7 +83,7 @@ func (inc *ATR) calculateAndUpdate(kLines []types.KLine) {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k)
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64())
}

inc.EmitUpdate(inc.Last())
Expand Down
26 changes: 11 additions & 15 deletions pkg/indicator/macd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,16 @@ type MACD struct {
UpdateCallbacks []func(value float64)
}

func (inc *MACD) calculateMACD(kLines []types.KLine, priceF KLinePriceMapper) 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) {
func (inc *MACD) Update(x float64) {
if len(inc.Values) == 0 {
inc.FastEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.ShortPeriod}}
inc.SlowEWMA = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.LongPeriod}}
inc.SignalLine = EWMA{IntervalWindow: types.IntervalWindow{Window: inc.Window}}
}

price := priceF(kLine)

// update fast and slow ema
inc.FastEWMA.Update(price)
inc.SlowEWMA.Update(price)
inc.FastEWMA.Update(x)
inc.SlowEWMA.Update(x)

// update macd
macd := inc.FastEWMA.Last() - inc.SlowEWMA.Last()
Expand All @@ -60,18 +51,23 @@ func (inc *MACD) Update(kLine types.KLine, priceF KLinePriceMapper) {
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) {
if len(kLines) == 0 {
return
}

var priceF = KLineClosePriceMapper

for _, k := range kLines {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k, priceF)
inc.Update(k.Close.Float64())
}

inc.EmitUpdate(inc.Values[len(inc.Values)-1])
Expand Down
10 changes: 3 additions & 7 deletions pkg/indicator/obv.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ type OBV struct {
UpdateCallbacks []func(value float64)
}

func (inc *OBV) Update(kLine types.KLine, priceF KLinePriceMapper) {
price := priceF(kLine)
volume := kLine.Volume.Float64()

func (inc *OBV) Update(price, volume float64) {
if len(inc.Values) == 0 {
inc.PrePrice = price
inc.Values.Push(volume)
Expand All @@ -47,17 +44,16 @@ func (inc *OBV) Last() float64 {
}

func (inc *OBV) calculateAndUpdate(kLines []types.KLine) {
var priceF = KLineClosePriceMapper

for _, k := range kLines {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k, priceF)
inc.Update(k.Close.Float64(), k.Volume.Float64())
}
inc.EmitUpdate(inc.Last())
inc.EndTime = kLines[len(kLines)-1].EndTime.Time()
}

func (inc *OBV) handleKLineWindowUpdate(interval types.Interval, window types.KLineWindow) {
if inc.Interval != interval {
return
Expand Down
7 changes: 2 additions & 5 deletions pkg/indicator/rsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ type RSI struct {
UpdateCallbacks []func(value float64)
}

func (inc *RSI) Update(kline types.KLine, priceF KLinePriceMapper) {
price := priceF(kline)
func (inc *RSI) Update(price float64) {
inc.Prices.Push(price)

if len(inc.Prices) < inc.Window+1 {
Expand Down Expand Up @@ -78,13 +77,11 @@ func (inc *RSI) Length() int {
var _ types.Series = &RSI{}

func (inc *RSI) calculateAndUpdate(kLines []types.KLine) {
var priceF = KLineClosePriceMapper

for _, k := range kLines {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k, priceF)
inc.Update(k.Close.Float64())
}

inc.EmitUpdate(inc.Last())
Expand Down
18 changes: 9 additions & 9 deletions pkg/indicator/stoch.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ type STOCH struct {
K types.Float64Slice
D types.Float64Slice

KLineWindow types.KLineWindow
HighValues types.Float64Slice
LowValues types.Float64Slice

EndTime time.Time
UpdateCallbacks []func(k float64, d float64)
}

func (inc *STOCH) update(kLine types.KLine) {
inc.KLineWindow.Add(kLine)
inc.KLineWindow.Truncate(inc.Window)
func (inc *STOCH) Update(high, low, cloze float64) {
inc.HighValues.Push(high)
inc.LowValues.Push(low)

lowest := inc.KLineWindow.GetLow().Float64()
highest := inc.KLineWindow.GetHigh().Float64()
clos := kLine.Close.Float64()
lowest := inc.LowValues.Tail(inc.Window).Min()
highest := inc.HighValues.Tail(inc.Window).Max()

k := 100.0 * (clos - lowest) / (highest - lowest)
k := 100.0 * (cloze - lowest) / (highest - lowest)
inc.K.Push(k)

d := inc.K.Tail(DPeriod).Mean()
Expand Down Expand Up @@ -64,7 +64,7 @@ func (inc *STOCH) calculateAndUpdate(kLines []types.KLine) {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.update(k)
inc.Update(k.High.Float64(), k.Low.Float64(), k.Close.Float64())
}

inc.EmitUpdate(inc.LastK(), inc.LastD())
Expand Down
41 changes: 19 additions & 22 deletions pkg/indicator/vwap.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ type VWAP struct {
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 {
if len(inc.Values) == 0 {
return 0.0
Expand All @@ -50,34 +67,14 @@ func (inc *VWAP) Length() int {

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) {
var priceF = KLineTypicalPriceMapper

for _, k := range kLines {
if inc.EndTime != zeroTime && !k.EndTime.After(inc.EndTime) {
continue
}
inc.Update(k, priceF)
inc.Update(priceF(k), k.Volume.Float64())
}

inc.EmitUpdate(inc.Last())
Expand All @@ -99,7 +96,7 @@ func (inc *VWAP) Bind(updater KLineWindowUpdater) {
func CalculateVWAP(klines []types.KLine, priceF KLinePriceMapper, window int) float64 {
vwap := VWAP{IntervalWindow: types.IntervalWindow{Window: window}}
for _, k := range klines {
vwap.Update(k, priceF)
vwap.Update(priceF(k), k.Volume.Float64())
}
return vwap.Last()
}

0 comments on commit 167f9d3

Please sign in to comment.