Skip to content

Commit

Permalink
add valid method for all indicators
Browse files Browse the repository at this point in the history
  • Loading branch information
iamjinlei committed Jun 19, 2021
1 parent 18f5864 commit 0373d4b
Show file tree
Hide file tree
Showing 42 changed files with 217 additions and 15 deletions.
4 changes: 4 additions & 0 deletions ad.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func (a *Ad) InitPeriod() int64 {
return 0
}

func (a *Ad) Valid() bool {
return true
}

// Developed by Marc Chaikin, the Accumulation Distribution
// Line is a volume-based indicator designed to measure the
// cumulative flow of money into and out of a security.
Expand Down
5 changes: 5 additions & 0 deletions adosc.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func NewAdOsc(fastN, slowN int64) *AdOsc {

func (a *AdOsc) Update(h, l, c, v float64) float64 {
a.sz++

ad := a.ad.Update(h, l, c, v)
if a.sz == 1 {
a.fast = ad
Expand All @@ -67,6 +68,10 @@ func (a *AdOsc) InitPeriod() int64 {
return a.slowN - 1
}

func (a *AdOsc) Valid() bool {
return a.sz > a.InitPeriod()
}

// Developed by Marc Chaikin, the Chaikin Oscillator measures the
// momentum of the Accumulation Distribution Line using the MACD
// formula. (This makes it an indicator of an indicator.) The
Expand Down
5 changes: 5 additions & 0 deletions adx.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func NewAdx(n int64) *Adx {

func (a *Adx) Update(h, l, c float64) float64 {
a.sz++

dx := a.dx.Update(h, l, c)

if a.sz <= a.n {
Expand All @@ -61,6 +62,10 @@ func (a *Adx) InitPeriod() int64 {
return a.n
}

func (a *Adx) Valid() bool {
return a.sz > a.InitPeriod()
}

// The Average Directional Index (ADX), Minus Directional
// Indicator (-DI) and Plus Directional Indicator (+DI)
// represent a group of directional movement indicators
Expand Down
4 changes: 4 additions & 0 deletions adxr.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ func (a *AdxR) InitPeriod() int64 {
return 3*a.n - 2
}

func (a *AdxR) Valid() bool {
return a.hist.size() > a.InitPeriod()
}

// Average Directional Movement Index Rating (ADXR) is a simple
// average of today’s ADX value and the ADX from N periods ago.
// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/dmi
Expand Down
5 changes: 5 additions & 0 deletions apo.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func NewApo(t MaType, fastN, slowN int64) *Apo {

func (a *Apo) Update(v float64) float64 {
a.sz++

fast := a.fastMa.Update(v)
slow := a.slowMa.Update(v)

Expand All @@ -40,6 +41,10 @@ func (a *Apo) InitPeriod() int64 {
return a.slowN - 1
}

func (a *Apo) Valid() bool {
return a.sz > a.InitPeriod()
}

// The Absolute Price Oscillator displays the difference
// between two exponential moving averages of a security's
// price and is expressed as an absolute value.
Expand Down
7 changes: 6 additions & 1 deletion aroon.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ func (a *Aroon) aroonValue(idx int64) float64 {
}

func (a *Aroon) Update(h, l float64) (float64, float64) {
a.sz++

minIdx, _ := a.min.Update(l)
maxIdx, _ := a.max.Update(h)
a.sz++

if a.sz <= a.n {
return 0, 0
Expand All @@ -55,6 +56,10 @@ func (a *Aroon) InitPeriod() int64 {
return a.n
}

func (a *Aroon) Valid() bool {
return a.sz > a.InitPeriod()
}

// Developed by Tushar Chande in 1995, Aroon is an indicator
// system that determines whether a stock is trending or not
// and how strong the trend is. “Aroon” means “Dawn's Early Light”
Expand Down
4 changes: 4 additions & 0 deletions aroonosc.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func (a *AroonOsc) InitPeriod() int64 {
return a.aroon.InitPeriod()
}

func (a *AroonOsc) Valid() bool {
return a.aroon.Valid()
}

// The Aroon Oscillator is the difference between Aroon-Up
// and Aroon-Down. These two indicators are usually plotted
// together for easy comparison, but chartists can also view
Expand Down
8 changes: 7 additions & 1 deletion atr.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ func NewAtr(n int64) *Atr {
}

func (a *Atr) Update(h, l, c float64) float64 {
tr := a.tr.Update(h, l, c)
a.sz++

tr := a.tr.Update(h, l, c)

if a.sz == 1 {
return 0
}
Expand All @@ -51,6 +53,10 @@ func (a *Atr) InitPeriod() int64 {
return 1
}

func (a *Atr) Valid() bool {
return a.sz > 1
}

// Developed by J. Welles Wilder, the Average True Range (ATR)
// is an indicator that measures volatility. As with most of
// his indicators, Wilder designed ATR with commodities and
Expand Down
8 changes: 8 additions & 0 deletions bbands.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type BBands struct {
stdDev *StdDev
upNStdDev float64
dnNStdDev float64
sz int64
}

func NewBBands(t MaType, n int64, upNStdDev, dnNStdDev float64) *BBands {
Expand All @@ -37,11 +38,14 @@ func NewBBands(t MaType, n int64, upNStdDev, dnNStdDev float64) *BBands {
stdDev: stdDev,
upNStdDev: upNStdDev,
dnNStdDev: dnNStdDev,
sz: 0,
}
}

// upper, middle, lower
func (b *BBands) Update(v float64) (float64, float64, float64) {
b.sz++

m := b.ma.Update(v)
stddev := b.stdDev.Update(v)

Expand All @@ -52,6 +56,10 @@ func (b *BBands) InitPeriod() int64 {
return b.initPeriod
}

func (b *BBands) Valid() bool {
return b.sz > b.initPeriod
}

// Developed by John Bollinger, Bollinger Bands are volatility
// bands placed above and below a moving average. Volatility
// is based on the standard deviation, which changes as volatility
Expand Down
4 changes: 4 additions & 0 deletions bop.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func (b *Bop) InitPeriod() int64 {
return 0
}

func (b *Bop) Valid() bool {
return true
}

// Balance of Power (BOP) is an oscillator that measures the
// strength of buying and selling pressure. Introduced by Igor
// Levshin in the August 2001 issue of Technical Analysis of
Expand Down
8 changes: 8 additions & 0 deletions cci.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Cci struct {
initPeriod int64
avg *Sma
dev *Dev
sz int64
}

func NewCci(n int64) *Cci {
Expand All @@ -35,10 +36,13 @@ func NewCci(n int64) *Cci {
initPeriod: a,
avg: avg,
dev: dev,
sz: 0,
}
}

func (d *Cci) Update(h, l, c float64) float64 {
d.sz++

m := (h + l + c) / 3.0
avg := d.avg.Update(m)
dev := d.dev.Update(m)
Expand All @@ -54,6 +58,10 @@ func (d *Cci) InitPeriod() int64 {
return d.initPeriod
}

func (d *Cci) Valid() bool {
return d.sz > d.initPeriod
}

// Developed by Donald Lambert and featured in Commodities
// magazine in 1980, the Commodity Channel Index (CCI) is
// a versatile indicator that can be used to identify a new
Expand Down
7 changes: 6 additions & 1 deletion cmo.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ func NewCmo(n int64) *Cmo {
}

func (c *Cmo) Update(v float64) float64 {
c.sz++

d := v - c.prevC
c.prevC = v
c.sz++

if c.sz == 1 {
return 0
Expand All @@ -66,6 +67,10 @@ func (c *Cmo) InitPeriod() int64 {
return c.initPeriod
}

func (c *Cmo) Valid() bool {
return c.sz > c.initPeriod
}

// The Chande momentum oscillator is a technical momentum
// indicator introduced by Tushar Chande in his 1994 book
// The New Technical Trader. The formula calculates the
Expand Down
9 changes: 7 additions & 2 deletions dema.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,23 @@ package tart
// https://www.investopedia.com/terms/d/double-exponential-moving-average.asp
type Dema struct {
n int64
sz int64
ema1 *Ema
ema2 *Ema
sz int64
}

func NewDema(n int64, k float64) *Dema {
return &Dema{
n: n,
sz: 0,
ema1: NewEma(n, k),
ema2: NewEma(n, k),
sz: 0,
}
}

func (d *Dema) Update(v float64) float64 {
d.sz++

e1 := d.ema1.Update(v)

if d.sz > d.n-1 {
Expand All @@ -46,6 +47,10 @@ func (d *Dema) InitPeriod() int64 {
return d.n*2 - 2
}

func (d *Dema) Valid() bool {
return d.sz > d.InitPeriod()
}

// The Double Exponential Moving Average (DEMA) reduces the lag
// of traditional EMAs, making it more responsive and better-suited
// for short-term traders. DEMA was developed by Patrick Mulloy,
Expand Down
5 changes: 5 additions & 0 deletions diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func NewDiff(n int64) *Diff {

func (d *Diff) Update(v float64) float64 {
d.sz++

old := d.hist.append(v)

if d.sz <= d.n {
Expand All @@ -36,6 +37,10 @@ func (d *Diff) InitPeriod() int64 {
return d.n
}

func (d *Diff) Valid() bool {
return d.sz > d.InitPeriod()
}

// This is also known as Momentum (MOM).
// The Momentum (MOM) indicator compares the current price with
// the previous price from a selected number of periods ago.
Expand Down
7 changes: 6 additions & 1 deletion dx.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ func NewDx(n int64) *Dx {
}

func (d *Dx) Update(h, l, c float64) float64 {
d.sz++

tr := d.tr.Update(h, l, c)
plusDm := h - d.prevH
minusDm := d.prevL - l
d.prevH = h
d.prevL = l

d.sz++
if d.sz == 1 {
return 0
}
Expand Down Expand Up @@ -73,6 +74,10 @@ func (d *Dx) InitPeriod() int64 {
return d.n
}

func (d *Dx) Valid() bool {
return d.sz > d.InitPeriod()
}

// Refer to ADX.
// https://school.stockcharts.com/doku.php?id=technical_indicators:average_directional_index_adx
func DxArr(h, l, c []float64, n int64) []float64 {
Expand Down
5 changes: 5 additions & 0 deletions ema.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func NewEma(n int64, k float64) *Ema {

func (e *Ema) Update(v float64) float64 {
e.sz++

if e.sz <= e.n {
e.ma += v / float64(e.n)
if e.sz < e.n {
Expand All @@ -45,6 +46,10 @@ func (e *Ema) InitPeriod() int64 {
return e.n - 1
}

func (e *Ema) Valid() bool {
return e.sz > e.InitPeriod()
}

// Exponential moving averages (EMAs) reduce the lag by
// applying more weight to recent prices. The weighting
// applied to the most recent price depends on the number
Expand Down
7 changes: 6 additions & 1 deletion exmaple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
func main() {
sma := tart.NewSma(5)
for i := 0; i < 20; i++ {
fmt.Printf("sma[%v] = %.4f\n", i, sma.Update(float64(i%7)))
val := sma.Update(float64(i % 7))
if sma.Valid() {
fmt.Printf("sma[%v] = %.4f\n", i, val)
} else {
fmt.Printf("sma[%v] = unavail.\n", i)
}
}
}
4 changes: 4 additions & 0 deletions kama.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ func (k *Kama) InitPeriod() int64 {
return k.n
}

func (k *Kama) Valid() bool {
return k.sz > k.InitPeriod()
}

// Developed by Perry Kaufman, Kaufman's Adaptive Moving
// Average (KAMA) is a moving average designed to account
// for market noise or volatility. KAMA will closely follow
Expand Down
5 changes: 5 additions & 0 deletions ma.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ func (m *Ma) InitPeriod() int64 {
return m.mu.InitPeriod()
}

func (m *Ma) Valid() bool {
return m.mu.Valid()
}

// Convenient wrapper for different moving average types
func MaArr(t MaType, in []float64, n int64) []float64 {
out := make([]float64, len(in))
Expand All @@ -68,4 +72,5 @@ func MaArr(t MaType, in []float64, n int64) []float64 {
type maUpdater interface {
Update(v float64) float64
InitPeriod() int64
Valid() bool
}
5 changes: 5 additions & 0 deletions macdext.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func NewMacdExt(fastT MaType, fastN int64, slowT MaType, slowN int64, signalT Ma

func (m *MacdExt) Update(v float64) (float64, float64, float64) {
m.sz++

slow := m.slow.Update(v)

if m.sz <= m.slowN-m.fastN {
Expand Down Expand Up @@ -60,6 +61,10 @@ func (m *MacdExt) InitPeriod() int64 {
return m.n - 1
}

func (m *MacdExt) Valid() bool {
return m.sz > m.InitPeriod()
}

// Refer to MACD.
// This is a general version of MACD with moving average types
// for fast, slow, and signal lines as paremters.
Expand Down
Loading

0 comments on commit 0373d4b

Please sign in to comment.