-
-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Describe Request Stochastic RSI is added. Fixed #54 # Change Type Momentum indicator and strategy.
- Loading branch information
Showing
10 changed files
with
966 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// StochasticRsipyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package momentum | ||
|
||
import ( | ||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/trend" | ||
) | ||
|
||
const ( | ||
// DefaultStochasticRsiPeriod is the default period for the Stochastic Relative Strength Index (RSI). | ||
DefaultStochasticRsiPeriod = 14 | ||
) | ||
|
||
// StochasticRsi represents the configuration parameter for calculating the Stochastic Relative Strength Index (RSI). | ||
// It is a momentum indicator that focuses on the historical performance to evaluate overbought and | ||
// oversold conditions. | ||
// | ||
// RSI - Min(RSI) | ||
// Stochastic RSI = ------------------------- | ||
// Max(RSI) - Min(RSI) | ||
// | ||
// Example: | ||
// | ||
// stochasticRsi := momentum.NewStochasticRsi[float64]() | ||
// result := stochasticRsi.Compute(closings) | ||
type StochasticRsi[T helper.Number] struct { | ||
// Rsi is that RSI instance. | ||
Rsi *Rsi[T] | ||
|
||
// Min is the Moving Min instance. | ||
Min *trend.MovingMin[T] | ||
|
||
// Max is the Moving Max instance. | ||
Max *trend.MovingMax[T] | ||
} | ||
|
||
// NewStochasticRsi function initializes a new Storchastic RSI instance with the default parameters. | ||
func NewStochasticRsi[T helper.Number]() *StochasticRsi[T] { | ||
return NewStochasticRsiWithPeriod[T](DefaultStochasticRsiPeriod) | ||
} | ||
|
||
// NewStochasticRsiWithPeriod function initializes a new Stochastic RSI instance with the given period. | ||
func NewStochasticRsiWithPeriod[T helper.Number](period int) *StochasticRsi[T] { | ||
return &StochasticRsi[T]{ | ||
Rsi: NewRsiWithPeriod[T](period), | ||
Min: trend.NewMovingMinWithPeriod[T](period), | ||
Max: trend.NewMovingMaxWithPeriod[T](period), | ||
} | ||
} | ||
|
||
// Compute function takes a channel of closings numbers and computes the Stochastic RSI. | ||
func (s *StochasticRsi[T]) Compute(closings <-chan T) <-chan T { | ||
rsisSplice := helper.Duplicate( | ||
s.Rsi.Compute(closings), | ||
3, | ||
) | ||
|
||
rsisSplice[0] = helper.Skip(rsisSplice[0], s.Max.IdlePeriod()) | ||
|
||
minRsisSplice := helper.Duplicate( | ||
s.Min.Compute(rsisSplice[1]), | ||
2, | ||
) | ||
|
||
maxRsis := s.Max.Compute(rsisSplice[2]) | ||
|
||
result := helper.Divide( | ||
helper.Subtract( | ||
rsisSplice[0], | ||
minRsisSplice[0], | ||
), | ||
helper.Subtract( | ||
maxRsis, | ||
minRsisSplice[1], | ||
), | ||
) | ||
|
||
return result | ||
} | ||
|
||
// IdlePeriod is the initial period that Stochasic RSI won't yield any results. | ||
func (s *StochasticRsi[T]) IdlePeriod() int { | ||
return s.Rsi.IdlePeriod() + s.Min.IdlePeriod() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// StochasticRsipyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package momentum_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/momentum" | ||
) | ||
|
||
func TestStochasticRsi(t *testing.T) { | ||
type Data struct { | ||
Close float64 | ||
StochasticRsi float64 | ||
} | ||
|
||
input, err := helper.ReadFromCsvFile[Data]("testdata/stochastic_rsi.csv", true) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
inputs := helper.Duplicate(input, 2) | ||
closings := helper.Map(inputs[0], func(d *Data) float64 { return d.Close }) | ||
expected := helper.Map(inputs[1], func(d *Data) float64 { return d.StochasticRsi }) | ||
|
||
stochasticRsi := momentum.NewStochasticRsi[float64]() | ||
actual := stochasticRsi.Compute(closings) | ||
actual = helper.RoundDigits(actual, 2) | ||
|
||
expected = helper.Skip(expected, stochasticRsi.IdlePeriod()) | ||
|
||
err = helper.CheckEquals(actual, expected) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
Oops, something went wrong.