Skip to content

Commit

Permalink
ATR calculation to use the previous closing value.
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar committed Jul 18, 2024
1 parent f956792 commit 24351a9
Show file tree
Hide file tree
Showing 9 changed files with 944 additions and 929 deletions.
44 changes: 22 additions & 22 deletions strategy/volatility/testdata/super_trend_strategy.csv
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Action
0
0
0
1
0
1
0
0
0
Expand All @@ -30,8 +30,8 @@ Action
1
0
0
-1
0
-1
0
1
0
Expand All @@ -43,17 +43,16 @@ Action
0
0
0
-1
0
1
0
0
0
-1
0
0
0
0
0
1
-1
1
-1
Expand All @@ -66,6 +65,7 @@ Action
0
0
0
0
-1
0
0
Expand All @@ -88,8 +88,8 @@ Action
1
-1
1
0
0
-1
1
0
0
0
Expand All @@ -100,8 +100,8 @@ Action
0
-1
1
0
0
-1
1
0
0
-1
Expand All @@ -117,8 +117,8 @@ Action
-1
1
-1
0
0
1
-1
0
0
0
Expand All @@ -133,18 +133,18 @@ Action
0
0
0
0
0
-1
1
0
0
0
0
0
-1
0
0
1
-1
1
0
0
0
0
Expand Down Expand Up @@ -177,8 +177,8 @@ Action
0
0
0
-1
0
-1
1
-1
1
Expand All @@ -197,8 +197,8 @@ Action
0
0
0
-1
1
0
0
0
-1
0
Expand Down Expand Up @@ -245,8 +245,8 @@ Action
1
-1
1
0
0
-1
0
0
1
-1
1
-1
8 changes: 4 additions & 4 deletions volatility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ IdlePeriod is the initial period that Acceleration Bands won't yield any results
Atr represents the configuration parameters for calculating the Average True Range \(ATR\). It is a technical analysis indicator that measures market volatility by decomposing the entire range of stock prices for that period.

```
TR = Max((High - Low), (High - Closing), (Closing - Low))
TR = Max((High - Low), (High - Previous Closing), (Previous Closing - Low))
ATR = MA TR
```

Expand Down Expand Up @@ -283,7 +283,7 @@ func (a *Atr[T]) Compute(highs, lows, closings <-chan T) <-chan T
Compute function takes a channel of numbers and computes the ATR over the specified period.

<a name="Atr[T].IdlePeriod"></a>
### func \(\*Atr\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/atr.go#L66>)
### func \(\*Atr\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/atr.go#L70>)

```go
func (a *Atr[T]) IdlePeriod() int
Expand Down Expand Up @@ -441,7 +441,7 @@ func (c *ChandelierExit[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <
Compute function takes a channel of numbers and computes the Chandelier Exit over the specified period.

<a name="ChandelierExit[T].IdlePeriod"></a>
### func \(\*ChandelierExit\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/chandelier_exit.go#L74>)
### func \(\*ChandelierExit\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/chandelier_exit.go#L81>)

```go
func (c *ChandelierExit[T]) IdlePeriod() int
Expand Down Expand Up @@ -569,7 +569,7 @@ func (k *KeltnerChannel[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <
Compute function takes a channel of numbers and computes the Keltner Channel over the specified period.

<a name="KeltnerChannel[T].IdlePeriod"></a>
### func \(\*KeltnerChannel\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/keltner_channel.go#L79>)
### func \(\*KeltnerChannel\[T\]\) [IdlePeriod](<https://github.com/cinar/indicator/blob/master/volatility/keltner_channel.go#L82>)

```go
func (k *KeltnerChannel[T]) IdlePeriod() int
Expand Down
11 changes: 8 additions & 3 deletions volatility/atr.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const (
// It is a technical analysis indicator that measures market volatility by decomposing the
// entire range of stock prices for that period.
//
// TR = Max((High - Low), (High - Closing), (Closing - Low))
// TR = Max((High - Low), (High - Previous Closing), (Previous Closing - Low))
// ATR = MA TR
//
// By default, SMA is used as the MA.
Expand All @@ -41,7 +41,7 @@ func NewAtr[T helper.Number]() *Atr[T] {

// NewAtrWithPeriod function initializes a new ATR instance with the given period.
func NewAtrWithPeriod[T helper.Number](period int) *Atr[T] {
return NewAtrWithMa[T](trend.NewSmaWithPeriod[T](period))
return NewAtrWithMa(trend.NewSmaWithPeriod[T](period))
}

// NewAtrWithMa function initializes a new ATR instance with the given moving average instance.
Expand All @@ -53,6 +53,10 @@ func NewAtrWithMa[T helper.Number](ma trend.Ma[T]) *Atr[T] {

// Compute function takes a channel of numbers and computes the ATR over the specified period.
func (a *Atr[T]) Compute(highs, lows, closings <-chan T) <-chan T {
// Use previous closing by skipping highs and lows by one.
highs = helper.Skip(highs, 1)
lows = helper.Skip(lows, 1)

tr := helper.Operate3(highs, lows, closings, func(high, low, closing T) T {
return T(math.Max(float64(high-low), math.Max(float64(high-closing), float64(closing-low))))
})
Expand All @@ -64,5 +68,6 @@ func (a *Atr[T]) Compute(highs, lows, closings <-chan T) <-chan T {

// IdlePeriod is the initial period that Acceleration Bands won't yield any results.
func (a *Atr[T]) IdlePeriod() int {
return a.Ma.IdlePeriod()
// Ma idle period and for using the previous closing.
return a.Ma.IdlePeriod() + 1
}
13 changes: 10 additions & 3 deletions volatility/chandelier_exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ func (c *ChandelierExit[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <

atr := NewAtrWithPeriod[T](c.Period)

maxHighs := max.Compute(highsSplice[0])
minLows := min.Compute(lowsSplice[0])
maxHighs := helper.Skip(
max.Compute(highsSplice[0]),
atr.IdlePeriod()-max.IdlePeriod(),
)

minLows := helper.Skip(
min.Compute(lowsSplice[0]),
atr.IdlePeriod()-min.IdlePeriod(),
)

atr3Splice := helper.Duplicate(
helper.MultiplyBy(
Expand All @@ -72,5 +79,5 @@ func (c *ChandelierExit[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <

// IdlePeriod is the initial period that Chandelier Exit won't yield any results.
func (c *ChandelierExit[T]) IdlePeriod() int {
return c.Period - 1
return c.Period
}
5 changes: 4 additions & 1 deletion volatility/keltner_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ func (k *KeltnerChannel[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <

// Middle Line = EMA(period, closings)
middles := helper.Duplicate(
k.Ema.Compute(closingsSplice[1]),
helper.Skip(
k.Ema.Compute(closingsSplice[1]),
k.Atr.IdlePeriod()-k.Ema.IdlePeriod(),
),
3,
)

Expand Down
Loading

0 comments on commit 24351a9

Please sign in to comment.