diff --git a/.gitignore b/.gitignore
index ee09abe..9575016 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,7 @@ indicator-sync
# Go workspace file
go.work
+
+# GoLand project
+.idea
+
diff --git a/asset/README.md b/asset/README.md
index 54e3e50..da73b35 100644
--- a/asset/README.md
+++ b/asset/README.md
@@ -125,7 +125,7 @@ RegisterRepositoryBuilder registers the given builder.
func SnapshotsAsClosings(snapshots <-chan *Snapshot) <-chan float64
```
-SnapshotsAsClosings extracts the close field from each snapshot in the provided channel and returns a new channel containing only those close values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsClosings extracts the close field from each snapshot in the provided channel and returns a new channel containing only those close values.The original snapshots channel can no longer be directly used afterward.
## func [SnapshotsAsDates]()
@@ -134,7 +134,7 @@ SnapshotsAsClosings extracts the close field from each snapshot in the provided
func SnapshotsAsDates(snapshots <-chan *Snapshot) <-chan time.Time
```
-SnapshotsAsDates extracts the date field from each snapshot in the provided channel and returns a new channel containing only those date values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsDates extracts the date field from each snapshot in the provided channel and returns a new channel containing only those date values.The original snapshots channel can no longer be directly used afterward.
## func [SnapshotsAsHighs]()
@@ -143,7 +143,7 @@ SnapshotsAsDates extracts the date field from each snapshot in the provided chan
func SnapshotsAsHighs(snapshots <-chan *Snapshot) <-chan float64
```
-SnapshotsAsHighs extracts the high field from each snapshot in the provided channel and returns a new channel containing only those high values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsHighs extracts the high field from each snapshot in the provided channel and returns a new channel containing only those high values.The original snapshots channel can no longer be directly used afterward.
## func [SnapshotsAsLows]()
@@ -152,7 +152,7 @@ SnapshotsAsHighs extracts the high field from each snapshot in the provided chan
func SnapshotsAsLows(snapshots <-chan *Snapshot) <-chan float64
```
-SnapshotsAsLows extracts the low field from each snapshot in the provided channel and returns a new channel containing only those low values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsLows extracts the low field from each snapshot in the provided channel and returns a new channel containing only those low values.The original snapshots channel can no longer be directly used afterward.
## func [SnapshotsAsOpenings]()
@@ -161,7 +161,7 @@ SnapshotsAsLows extracts the low field from each snapshot in the provided channe
func SnapshotsAsOpenings(snapshots <-chan *Snapshot) <-chan float64
```
-SnapshotsAsOpenings extracts the open field from each snapshot in the provided channel and returns a new channel containing only those open values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsOpenings extracts the open field from each snapshot in the provided channel and returns a new channel containing only those open values.The original snapshots channel can no longer be directly used afterward.
## func [SnapshotsAsVolumes]()
@@ -170,7 +170,7 @@ SnapshotsAsOpenings extracts the open field from each snapshot in the provided c
func SnapshotsAsVolumes(snapshots <-chan *Snapshot) <-chan float64
```
-SnapshotsAsVolumes extracts the volume field from each snapshot in the provided channel and returns a new channel containing only those volume values.The original snapshots channel can no longer be directly used afterwards.
+SnapshotsAsVolumes extracts the volume field from each snapshot in the provided channel and returns a new channel containing only those volume values.The original snapshots channel can no longer be directly used afterward.
## type [FileSystemRepository]()
diff --git a/asset/file_system_repository_test.go b/asset/file_system_repository_test.go
index af30e10..a8f5f5a 100644
--- a/asset/file_system_repository_test.go
+++ b/asset/file_system_repository_test.go
@@ -6,7 +6,6 @@ package asset_test
import (
"fmt"
- "os"
"path"
"reflect"
"testing"
@@ -133,7 +132,7 @@ func TestFileSystemRepositoryAppend(t *testing.T) {
}
name := "test_file_system_repository_append"
- defer os.Remove(path.Join(repositoryBase, fmt.Sprintf("%s.csv", name)))
+ defer helper.Remove(t, path.Join(repositoryBase, fmt.Sprintf("%s.csv", name)))
err = repository.Append(name, expected)
if err != nil {
diff --git a/asset/snapshot.go b/asset/snapshot.go
index 64cdcc4..30fa79e 100644
--- a/asset/snapshot.go
+++ b/asset/snapshot.go
@@ -39,7 +39,7 @@ type Snapshot struct {
// SnapshotsAsDates extracts the date field from each snapshot in the provided
// channel and returns a new channel containing only those date values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsDates(snapshots <-chan *Snapshot) <-chan time.Time {
return helper.Map(snapshots, func(snapshot *Snapshot) time.Time {
return snapshot.Date
@@ -48,7 +48,7 @@ func SnapshotsAsDates(snapshots <-chan *Snapshot) <-chan time.Time {
// SnapshotsAsOpenings extracts the open field from each snapshot in the provided
// channel and returns a new channel containing only those open values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsOpenings(snapshots <-chan *Snapshot) <-chan float64 {
return helper.Map(snapshots, func(snapshot *Snapshot) float64 {
return snapshot.Open
@@ -57,7 +57,7 @@ func SnapshotsAsOpenings(snapshots <-chan *Snapshot) <-chan float64 {
// SnapshotsAsHighs extracts the high field from each snapshot in the provided
// channel and returns a new channel containing only those high values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsHighs(snapshots <-chan *Snapshot) <-chan float64 {
return helper.Map(snapshots, func(snapshot *Snapshot) float64 {
return snapshot.High
@@ -66,7 +66,7 @@ func SnapshotsAsHighs(snapshots <-chan *Snapshot) <-chan float64 {
// SnapshotsAsLows extracts the low field from each snapshot in the provided
// channel and returns a new channel containing only those low values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsLows(snapshots <-chan *Snapshot) <-chan float64 {
return helper.Map(snapshots, func(snapshot *Snapshot) float64 {
return snapshot.Low
@@ -75,7 +75,7 @@ func SnapshotsAsLows(snapshots <-chan *Snapshot) <-chan float64 {
// SnapshotsAsClosings extracts the close field from each snapshot in the provided
// channel and returns a new channel containing only those close values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsClosings(snapshots <-chan *Snapshot) <-chan float64 {
return helper.Map(snapshots, func(snapshot *Snapshot) float64 {
return snapshot.Close
@@ -84,7 +84,7 @@ func SnapshotsAsClosings(snapshots <-chan *Snapshot) <-chan float64 {
// SnapshotsAsVolumes extracts the volume field from each snapshot in the provided
// channel and returns a new channel containing only those volume values.The
-// original snapshots channel can no longer be directly used afterwards.
+// original snapshots channel can no longer be directly used afterward.
func SnapshotsAsVolumes(snapshots <-chan *Snapshot) <-chan float64 {
return helper.Map(snapshots, func(snapshot *Snapshot) float64 {
return snapshot.Volume
diff --git a/asset/tiingo_repository_test.go b/asset/tiingo_repository_test.go
index 84cca1e..9694ce8 100644
--- a/asset/tiingo_repository_test.go
+++ b/asset/tiingo_repository_test.go
@@ -21,7 +21,7 @@ func TestTiingoRepositoryAssets(t *testing.T) {
repository := asset.NewTiingoRepository("1234")
_, err := repository.Assets()
- if err != errors.ErrUnsupported {
+ if !errors.Is(err, errors.ErrUnsupported) {
t.Fatal(err)
}
}
@@ -80,7 +80,10 @@ func TestTiingoRepositoryGetInvalid(t *testing.T) {
response := ""
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
- fmt.Fprint(w, response)
+ _, err := fmt.Fprint(w, response)
+ if err != nil {
+ t.Fatal(err)
+ }
}))
repository := asset.NewTiingoRepository("1234")
@@ -175,7 +178,7 @@ func TestTiingoRepositoryAppend(t *testing.T) {
repository := asset.NewTiingoRepository("1234")
err := repository.Append("A", nil)
- if err != errors.ErrUnsupported {
+ if !errors.Is(err, errors.ErrUnsupported) {
t.Fatal(err)
}
}
diff --git a/backtest/backtest_test.go b/backtest/backtest_test.go
index 33ccd9b..f6316b6 100644
--- a/backtest/backtest_test.go
+++ b/backtest/backtest_test.go
@@ -5,6 +5,7 @@
package backtest_test
import (
+ "github.com/cinar/indicator/v2/helper"
"os"
"testing"
@@ -16,19 +17,19 @@ import (
func TestBacktest(t *testing.T) {
repository := asset.NewFileSystemRepository("testdata/repository")
- outputDir, err := os.MkdirTemp("", "backtest")
+ outputDir, err := os.MkdirTemp("", "bt")
if err != nil {
t.Fatal(err)
}
- defer os.RemoveAll(outputDir)
+ defer helper.RemoveAll(t, outputDir)
htmlReport := backtest.NewHTMLReport(outputDir)
- backtest := backtest.NewBacktest(repository, htmlReport)
- backtest.Names = append(backtest.Names, "brk-b")
- backtest.Strategies = append(backtest.Strategies, trend.NewApoStrategy())
+ bt := backtest.NewBacktest(repository, htmlReport)
+ bt.Names = append(bt.Names, "brk-b")
+ bt.Strategies = append(bt.Strategies, trend.NewApoStrategy())
- err = backtest.Run()
+ err = bt.Run()
if err != nil {
t.Fatal(err)
}
@@ -42,12 +43,12 @@ func TestBacktestAllAssetsAndStrategies(t *testing.T) {
t.Fatal(err)
}
- defer os.RemoveAll(outputDir)
+ defer helper.RemoveAll(t, outputDir)
htmlReport := backtest.NewHTMLReport(outputDir)
- backtest := backtest.NewBacktest(repository, htmlReport)
+ bt := backtest.NewBacktest(repository, htmlReport)
- err = backtest.Run()
+ err = bt.Run()
if err != nil {
t.Fatal(err)
}
@@ -61,13 +62,13 @@ func TestBacktestNonExistingAsset(t *testing.T) {
t.Fatal(err)
}
- defer os.RemoveAll(outputDir)
+ defer helper.RemoveAll(t, outputDir)
htmlReport := backtest.NewHTMLReport(outputDir)
- backtest := backtest.NewBacktest(repository, htmlReport)
- backtest.Names = append(backtest.Names, "non_existing")
+ bt := backtest.NewBacktest(repository, htmlReport)
+ bt.Names = append(bt.Names, "non_existing")
- err = backtest.Run()
+ err = bt.Run()
if err != nil {
t.Fatal(err)
}
diff --git a/cmd/indicator-backtest/main.go b/cmd/indicator-backtest/main.go
index 877385c..c9aa070 100644
--- a/cmd/indicator-backtest/main.go
+++ b/cmd/indicator-backtest/main.go
@@ -7,7 +7,7 @@ package main
import (
"flag"
- "fmt"
+ "log"
"log/slog"
"os"
@@ -31,11 +31,12 @@ func main() {
var addSplits bool
var addAnds bool
- fmt.Fprintln(os.Stderr, "Indicator Backtest")
- fmt.Fprintln(os.Stderr, "Copyright (c) 2021-2024 Onur Cinar.")
- fmt.Fprintln(os.Stderr, "The source code is provided under GNU AGPLv3 License.")
- fmt.Fprintln(os.Stderr, "https://github.com/cinar/indicator")
- fmt.Fprintln(os.Stderr)
+ stdErr := log.New(os.Stderr, "", 0)
+ stdErr.Println("Indicator Backtest")
+ stdErr.Println("Copyright (c) 2021-2024 Onur Cinar.")
+ stdErr.Println("The source code is provided under GNU AGPLv3 License.")
+ stdErr.Println("https://github.com/cinar/indicator")
+ stdErr.Println()
flag.StringVar(&repositoryName, "repository-name", "filesystem", "repository name")
flag.StringVar(&repositoryConfig, "repository-config", "", "repository config")
diff --git a/cmd/indicator-sync/main.go b/cmd/indicator-sync/main.go
index 0aa884e..d546c63 100644
--- a/cmd/indicator-sync/main.go
+++ b/cmd/indicator-sync/main.go
@@ -7,7 +7,7 @@ package main
import (
"flag"
- "fmt"
+ "log"
"log/slog"
"os"
"time"
@@ -24,11 +24,12 @@ func main() {
var workers int
var delay int
- fmt.Fprintln(os.Stderr, "Indicator Sync")
- fmt.Fprintln(os.Stderr, "Copyright (c) 2021-2024 Onur Cinar.")
- fmt.Fprintln(os.Stderr, "The source code is provided under GNU AGPLv3 License.")
- fmt.Fprintln(os.Stderr, "https://github.com/cinar/indicator")
- fmt.Fprintln(os.Stderr)
+ stdErr := log.New(os.Stderr, "", 0)
+ stdErr.Println("Indicator Sync")
+ stdErr.Println("Copyright (c) 2021-2024 Onur Cinar.")
+ stdErr.Println("The source code is provided under GNU AGPLv3 License.")
+ stdErr.Println("https://github.com/cinar/indicator")
+ stdErr.Println()
flag.StringVar(&sourceName, "source-name", "tiingo", "source repository type")
flag.StringVar(&sourceConfig, "source-config", "", "source repository config")
diff --git a/helper/README.md b/helper/README.md
index 15fd1ee..da34873 100644
--- a/helper/README.md
+++ b/helper/README.md
@@ -68,6 +68,8 @@ The information provided on this project is strictly for informational purposes
- [func Pipe\[T any\]\(f \<\-chan T, t chan\<\- T\)](<#Pipe>)
- [func Pow\[T Number\]\(c \<\-chan T, y T\) \<\-chan T](<#Pow>)
- [func ReadFromCsvFile\[T any\]\(fileName string, hasHeader bool\) \(\<\-chan \*T, error\)](<#ReadFromCsvFile>)
+- [func Remove\(t \*testing.T, name string\)](<#Remove>)
+- [func RemoveAll\(t \*testing.T, path string\)](<#RemoveAll>)
- [func RoundDigit\[T Number\]\(n T, d int\) T](<#RoundDigit>)
- [func RoundDigits\[T Number\]\(c \<\-chan T, d int\) \<\-chan T](<#RoundDigits>)
- [func Seq\[T Number\]\(from, to, increment T\) \<\-chan T](<#Seq>)
@@ -791,6 +793,24 @@ func ReadFromCsvFile[T any](fileName string, hasHeader bool) (<-chan *T, error)
ReadFromCsvFile creates a CSV instance, parses CSV data from the provided filename, maps the data to corresponding struct fields, and delivers it through the channel.
+
+## func [Remove]()
+
+```go
+func Remove(t *testing.T, name string)
+```
+
+Remove removes the file with the given name.
+
+
+## func [RemoveAll]()
+
+```go
+func RemoveAll(t *testing.T, path string)
+```
+
+RemoveAll removes the files with the given path.
+
## func [RoundDigit]()
@@ -1237,7 +1257,7 @@ type ReportColumn interface {
func NewAnnotationReportColumn(values <-chan string) ReportColumn
```
-NewAnnotationReportColumn returns a new instance of a annotation column for a report.
+NewAnnotationReportColumn returns a new instance of an annotation column for a report.
### func [NewNumericReportColumn]()
diff --git a/helper/annotation_report_column.go b/helper/annotation_report_column.go
index 36cc863..4d5152d 100644
--- a/helper/annotation_report_column.go
+++ b/helper/annotation_report_column.go
@@ -12,7 +12,7 @@ type annotationReportColumn struct {
values <-chan string
}
-// NewAnnotationReportColumn returns a new instance of a annotation column for a report.
+// NewAnnotationReportColumn returns a new instance of an annotation column for a report.
func NewAnnotationReportColumn(values <-chan string) ReportColumn {
return &annotationReportColumn{
values: values,
diff --git a/helper/bst.go b/helper/bst.go
index 7ba87e4..dfb4d78 100644
--- a/helper/bst.go
+++ b/helper/bst.go
@@ -77,7 +77,7 @@ func (b *Bst[T]) Min() T {
return T(0)
}
- node, _ := minNode(b.root)
+ node, _ := getMinNode(b.root)
return node.value
}
@@ -87,7 +87,7 @@ func (b *Bst[T]) Max() T {
return T(0)
}
- node, _ := maxNode(b.root)
+ node, _ := getMaxNode(b.root)
return node.value
}
@@ -118,13 +118,13 @@ func (b *Bst[T]) searchNode(value T) (*BstNode[T], *BstNode[T]) {
// and rebalances the tree.
func (b *Bst[T]) removeNode(node, parent *BstNode[T]) {
if node.left != nil && node.right != nil {
- min, minParent := minNode(node.right)
+ minNode, minParent := getMinNode(node.right)
if minParent == nil {
minParent = node
}
- b.removeNode(min, minParent)
- node.value = min.value
+ b.removeNode(minNode, minParent)
+ node.value = minNode.value
} else {
var child *BstNode[T]
@@ -144,8 +144,8 @@ func (b *Bst[T]) removeNode(node, parent *BstNode[T]) {
}
}
-// minNode functions returns the node with the minimum value and its parent node.
-func minNode[T Number](root *BstNode[T]) (*BstNode[T], *BstNode[T]) {
+// getMinNode functions returns the node with the minimum value and its parent node.
+func getMinNode[T Number](root *BstNode[T]) (*BstNode[T], *BstNode[T]) {
var parent *BstNode[T]
node := root
@@ -157,8 +157,8 @@ func minNode[T Number](root *BstNode[T]) (*BstNode[T], *BstNode[T]) {
return node, parent
}
-// maxNode functions returns the node with the maximum value and its parent node.
-func maxNode[T Number](root *BstNode[T]) (*BstNode[T], *BstNode[T]) {
+// getMaxNode functions returns the node with the maximum value and its parent node.
+func getMaxNode[T Number](root *BstNode[T]) (*BstNode[T], *BstNode[T]) {
var parent *BstNode[T]
node := root
diff --git a/helper/bst_test.go b/helper/bst_test.go
index dbf9bd7..2b42c6a 100644
--- a/helper/bst_test.go
+++ b/helper/bst_test.go
@@ -58,22 +58,22 @@ func TestRemoveNonExistentValue(t *testing.T) {
func TestMinAndMax(t *testing.T) {
input := []int{2, 1, 3, 4, 0, 6, 6, 10, -1, 9}
- mins := []int{2, 1, 1, 1, 0, 0, 0, 0, -1, -1}
- maxs := []int{2, 2, 3, 4, 4, 6, 6, 10, 10, 10}
+ minimums := []int{2, 1, 1, 1, 0, 0, 0, 0, -1, -1}
+ maximums := []int{2, 2, 3, 4, 4, 6, 6, 10, 10, 10}
bst := helper.NewBst[int]()
for i, n := range input {
bst.Insert(n)
- min := bst.Min()
- if min != mins[i] {
- t.Fatalf("actual min %v expeceted min %v", min, mins)
+ minimum := bst.Min()
+ if minimum != minimums[i] {
+ t.Fatalf("actual minimum %v expeceted minimum %v", minimum, minimums)
}
- max := bst.Max()
- if max != maxs[i] {
- t.Fatalf("actual min %v expeceted min %v", max, maxs)
+ maximum := bst.Max()
+ if maximum != maximums[i] {
+ t.Fatalf("actual maximum %v expeceted maximum %v", maximum, maximums)
}
}
}
@@ -81,17 +81,17 @@ func TestMinAndMax(t *testing.T) {
func TestEmptyMin(t *testing.T) {
bst := helper.NewBst[int]()
- min := bst.Min()
- if min != 0 {
- t.Fatalf("actual min %v expected min 0", min)
+ minValue := bst.Min()
+ if minValue != 0 {
+ t.Fatalf("actual min %v expected min 0", minValue)
}
}
func TestEmptyMax(t *testing.T) {
bst := helper.NewBst[int]()
- max := bst.Max()
- if max != 0 {
- t.Fatalf("actual max %v expected max 0", max)
+ maxValue := bst.Max()
+ if maxValue != 0 {
+ t.Fatalf("actual max %v expected max 0", maxValue)
}
}
diff --git a/helper/csv.go b/helper/csv.go
index 6d5e480..f37a181 100644
--- a/helper/csv.go
+++ b/helper/csv.go
@@ -276,12 +276,12 @@ func (c *Csv[T]) writeHeaderToCsvWriter(csvWriter *csv.Writer) error {
// ReadFromCsvFile creates a CSV instance, parses CSV data from the provided filename,
// maps the data to corresponding struct fields, and delivers it through the channel.
func ReadFromCsvFile[T any](fileName string, hasHeader bool) (<-chan *T, error) {
- csv, err := NewCsv[T](hasHeader)
+ c, err := NewCsv[T](hasHeader)
if err != nil {
return nil, err
}
- return csv.ReadFromFile(fileName)
+ return c.ReadFromFile(fileName)
}
// AppendOrWriteToCsvFile writes the provided rows of data to the specified file, appending to
@@ -289,7 +289,7 @@ func ReadFromCsvFile[T any](fileName string, hasHeader bool) (<-chan *T, error)
// function assumes that the existing file's column order matches the field order of the
// given row struct to ensure consistent data structure.
func AppendOrWriteToCsvFile[T any](fileName string, hasHeader bool, rows <-chan *T) error {
- csv, err := NewCsv[T](hasHeader)
+ c, err := NewCsv[T](hasHeader)
if err != nil {
return err
}
@@ -300,8 +300,8 @@ func AppendOrWriteToCsvFile[T any](fileName string, hasHeader bool, rows <-chan
return err
}
} else if stat.Size() > 0 {
- return csv.AppendToFile(fileName, rows)
+ return c.AppendToFile(fileName, rows)
}
- return csv.WriteToFile(fileName, rows)
+ return c.WriteToFile(fileName, rows)
}
diff --git a/helper/csv_test.go b/helper/csv_test.go
index 91cf49c..612c188 100644
--- a/helper/csv_test.go
+++ b/helper/csv_test.go
@@ -6,7 +6,6 @@ package helper_test
import (
"fmt"
- "os"
"strings"
"testing"
@@ -216,7 +215,7 @@ func TestCsvWriteToFile(t *testing.T) {
}
fileName := "test_csv_write_to_file.csv"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = csv.WriteToFile(fileName, helper.SliceToChan(input))
if err != nil {
@@ -258,7 +257,7 @@ func TestCsvAppendToFile(t *testing.T) {
}
fileName := "test_csv_append_to_file.csv"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = csv.WriteToFile(fileName, helper.SliceToChan(input[:1]))
if err != nil {
@@ -334,7 +333,7 @@ func TestCsvWriteToFileInvalidField(t *testing.T) {
}
fileName := "test_csv_write_to_file_invalid_field.csv"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = csv.WriteToFile(fileName, rows)
if err == nil {
@@ -354,7 +353,7 @@ func TestAppendOrWriteToCsvFile(t *testing.T) {
}
fileName := "test_append_or_write_to_csv_file.csv"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err := helper.AppendOrWriteToCsvFile(fileName, true, helper.SliceToChan(input[:1]))
if err != nil {
diff --git a/helper/reflect_test.go b/helper/reflect_test.go
index 355772f..c8f2c5a 100644
--- a/helper/reflect_test.go
+++ b/helper/reflect_test.go
@@ -328,7 +328,7 @@ func TestSetReflectValueFromNotFloat32(t *testing.T) {
func TestSetReflectValueFromFloat64(t *testing.T) {
actual := float64(0)
value := reflect.ValueOf(&actual).Elem()
- expected := float64(10.20)
+ expected := 10.20
err := setReflectValue(value, "10.20", "")
if err != nil {
@@ -427,7 +427,7 @@ func TestGetReflectValueFromBool(t *testing.T) {
}
func TestGetReflectValueFromInt(t *testing.T) {
- input := int(10)
+ input := 10
value := reflect.ValueOf(&input).Elem()
expected := "10"
@@ -592,7 +592,7 @@ func TestGetReflectValueFromFloat32(t *testing.T) {
}
func TestGetReflectValueFromFloat64(t *testing.T) {
- input := float64(10.20)
+ input := 10.20
value := reflect.ValueOf(&input).Elem()
expected := "10.2"
diff --git a/helper/remove.go b/helper/remove.go
new file mode 100644
index 0000000..6ef3d1e
--- /dev/null
+++ b/helper/remove.go
@@ -0,0 +1,26 @@
+// Copyright (c) 2021-2024 Onur Cinar.
+// The source code is provided under GNU AGPLv3 License.
+// https://github.com/cinar/indicator
+
+package helper
+
+import (
+ "os"
+ "testing"
+)
+
+// Remove removes the file with the given name.
+func Remove(t *testing.T, name string) {
+ err := os.Remove(name)
+ if err != nil {
+ t.Errorf("Error removing file: %v", err)
+ }
+}
+
+// RemoveAll removes the files with the given path.
+func RemoveAll(t *testing.T, path string) {
+ err := os.RemoveAll(path)
+ if err != nil {
+ t.Errorf("Error removing files: %v", err)
+ }
+}
diff --git a/helper/report_test.go b/helper/report_test.go
index 4f2a1c9..fc255fe 100644
--- a/helper/report_test.go
+++ b/helper/report_test.go
@@ -5,7 +5,6 @@
package helper_test
import (
- "os"
"testing"
"time"
@@ -42,7 +41,7 @@ func TestReportWriteToFile(t *testing.T) {
report.AddColumn(helper.NewAnnotationReportColumn(annotations), 0, 1)
fileName := "report.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/and_strategy_test.go b/strategy/and_strategy_test.go
index a18a46e..97fe8db 100644
--- a/strategy/and_strategy_test.go
+++ b/strategy/and_strategy_test.go
@@ -5,7 +5,6 @@
package strategy_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -49,7 +48,7 @@ func TestAndStrategyReport(t *testing.T) {
report := and.Report(snapshots)
fileName := "and.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/buy_and_hold_strategy_test.go b/strategy/buy_and_hold_strategy_test.go
index a6dde32..0b1e2d8 100644
--- a/strategy/buy_and_hold_strategy_test.go
+++ b/strategy/buy_and_hold_strategy_test.go
@@ -5,7 +5,6 @@
package strategy_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestBuyAndHoldStrategyReport(t *testing.T) {
report := bah.Report(snapshots)
fileName := "buy_and_hold_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/compound/macd_rsi_strategy_test.go b/strategy/compound/macd_rsi_strategy_test.go
index 10416ff..405b3c2 100644
--- a/strategy/compound/macd_rsi_strategy_test.go
+++ b/strategy/compound/macd_rsi_strategy_test.go
@@ -5,7 +5,6 @@
package compound_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestMacdRsiStrategyReport(t *testing.T) {
report := macdRsi.Report(snapshots)
fileName := "macd_rsi_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/decorator/README.md b/strategy/decorator/README.md
index 63f1a0b..2fb06b4 100644
--- a/strategy/decorator/README.md
+++ b/strategy/decorator/README.md
@@ -140,7 +140,7 @@ Report processes the provided asset snapshots and generates a report annotated w
## type [StopLossStrategy]()
-StopLossStrategy prevents a loss by recommending a sell action when the assets drops below the given threshold.
+StopLossStrategy prevents a loss by recommending a sell action when the assets drop below the given threshold.
```go
type StopLossStrategy struct {
diff --git a/strategy/decorator/inverse_strategy_test.go b/strategy/decorator/inverse_strategy_test.go
index a785f1d..46a507d 100644
--- a/strategy/decorator/inverse_strategy_test.go
+++ b/strategy/decorator/inverse_strategy_test.go
@@ -5,7 +5,6 @@
package decorator_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -29,9 +28,9 @@ func TestInverseStrategy(t *testing.T) {
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action })
innerStrategy := trend.NewMacdStrategy()
- strategy := decorator.NewInverseStrategy(innerStrategy)
+ inverseStrategy := decorator.NewInverseStrategy(innerStrategy)
- actual := strategy.Compute(snapshots)
+ actual := inverseStrategy.Compute(snapshots)
err = helper.CheckEquals(actual, expected)
if err != nil {
@@ -46,12 +45,12 @@ func TestInverseStrategyReport(t *testing.T) {
}
innerStrategy := trend.NewMacdStrategy()
- strategy := decorator.NewInverseStrategy(innerStrategy)
+ inverseStrategy := decorator.NewInverseStrategy(innerStrategy)
- report := strategy.Report(snapshots)
+ report := inverseStrategy.Report(snapshots)
fileName := "inverse_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/decorator/no_loss_strategy_test.go b/strategy/decorator/no_loss_strategy_test.go
index 15e633a..dd255d2 100644
--- a/strategy/decorator/no_loss_strategy_test.go
+++ b/strategy/decorator/no_loss_strategy_test.go
@@ -5,7 +5,6 @@
package decorator_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -29,9 +28,9 @@ func TestNoLossStrategy(t *testing.T) {
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action })
innerStrategy := trend.NewAroonStrategy()
- strategy := decorator.NewNoLossStrategy(innerStrategy)
+ noLossStrategy := decorator.NewNoLossStrategy(innerStrategy)
- actual := strategy.Compute(snapshots)
+ actual := noLossStrategy.Compute(snapshots)
err = helper.CheckEquals(actual, expected)
if err != nil {
@@ -46,12 +45,12 @@ func TestNoLossStrategyReport(t *testing.T) {
}
innerStrategy := trend.NewAroonStrategy()
- strategy := decorator.NewNoLossStrategy(innerStrategy)
+ noLossStrategy := decorator.NewNoLossStrategy(innerStrategy)
- report := strategy.Report(snapshots)
+ report := noLossStrategy.Report(snapshots)
fileName := "no_loss_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/decorator/stop_loss_strategy.go b/strategy/decorator/stop_loss_strategy.go
index cbab9cc..46c6d6a 100644
--- a/strategy/decorator/stop_loss_strategy.go
+++ b/strategy/decorator/stop_loss_strategy.go
@@ -12,7 +12,7 @@ import (
"github.com/cinar/indicator/v2/strategy"
)
-// StopLossStrategy prevents a loss by recommending a sell action when the assets drops below the given threshold.
+// StopLossStrategy prevents a loss by recommending a sell action when the assets drop below the given threshold.
type StopLossStrategy struct {
// InnertStrategy is the inner strategy.
InnertStrategy strategy.Strategy
diff --git a/strategy/decorator/stop_loss_strategy_test.go b/strategy/decorator/stop_loss_strategy_test.go
index e7bcf3e..62c5487 100644
--- a/strategy/decorator/stop_loss_strategy_test.go
+++ b/strategy/decorator/stop_loss_strategy_test.go
@@ -5,7 +5,6 @@
package decorator_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -29,9 +28,9 @@ func TestStopLossStrategy(t *testing.T) {
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action })
innerStrategy := trend.NewAroonStrategy()
- strategy := decorator.NewStopLossStrategy(innerStrategy, 0.02)
+ stopLossStrategy := decorator.NewStopLossStrategy(innerStrategy, 0.02)
- actual := strategy.Compute(snapshots)
+ actual := stopLossStrategy.Compute(snapshots)
err = helper.CheckEquals(actual, expected)
if err != nil {
@@ -46,12 +45,12 @@ func TestStopLossStrategyReport(t *testing.T) {
}
innerStrategy := trend.NewAroonStrategy()
- strategy := decorator.NewStopLossStrategy(innerStrategy, 0.02)
+ stopLossStrategy := decorator.NewStopLossStrategy(innerStrategy, 0.02)
- report := strategy.Report(snapshots)
+ report := stopLossStrategy.Report(snapshots)
fileName := "stop_loss_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/majority_strategy_test.go b/strategy/majority_strategy_test.go
index acf7488..d690081 100644
--- a/strategy/majority_strategy_test.go
+++ b/strategy/majority_strategy_test.go
@@ -5,7 +5,6 @@
package strategy_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -50,7 +49,7 @@ func TestMajorityStrategyReport(t *testing.T) {
report := majority.Report(snapshots)
fileName := "majority.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/momentum/awesome_oscillator_strategy_test.go b/strategy/momentum/awesome_oscillator_strategy_test.go
index 78a6b18..bce684b 100644
--- a/strategy/momentum/awesome_oscillator_strategy_test.go
+++ b/strategy/momentum/awesome_oscillator_strategy_test.go
@@ -5,7 +5,6 @@
package momentum_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestAwesomeOscillatorStrategyReport(t *testing.T) {
report := ao.Report(snapshots)
fileName := "awesome_oscillator_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/momentum/rsi_strategy_test.go b/strategy/momentum/rsi_strategy_test.go
index a7a8221..bbdf146 100644
--- a/strategy/momentum/rsi_strategy_test.go
+++ b/strategy/momentum/rsi_strategy_test.go
@@ -5,7 +5,6 @@
package momentum_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestRsiStrategyReport(t *testing.T) {
report := rsi.Report(snapshots)
fileName := "rsi_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/momentum/stochastic_rsi_strategy_test.go b/strategy/momentum/stochastic_rsi_strategy_test.go
index e7b1a9e..b762a16 100644
--- a/strategy/momentum/stochastic_rsi_strategy_test.go
+++ b/strategy/momentum/stochastic_rsi_strategy_test.go
@@ -5,7 +5,6 @@
package momentum_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestStochasticRsiStrategyReport(t *testing.T) {
report := rsi.Report(snapshots)
fileName := "stochastic_rsi_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/momentum/triple_rsi_strategy_test.go b/strategy/momentum/triple_rsi_strategy_test.go
index 7a93937..9d83f01 100644
--- a/strategy/momentum/triple_rsi_strategy_test.go
+++ b/strategy/momentum/triple_rsi_strategy_test.go
@@ -5,7 +5,6 @@
package momentum_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestTripleRsiStrategyReport(t *testing.T) {
report := tripleRsi.Report(snapshots)
fileName := "triple_rsi_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/or_strategy_test.go b/strategy/or_strategy_test.go
index aba8b6f..599e40b 100644
--- a/strategy/or_strategy_test.go
+++ b/strategy/or_strategy_test.go
@@ -5,7 +5,6 @@
package strategy_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -50,7 +49,7 @@ func TestOrStrategyReport(t *testing.T) {
report := or.Report(snapshots)
fileName := "or.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/split_strategy_test.go b/strategy/split_strategy_test.go
index 513d3de..dc4cb51 100644
--- a/strategy/split_strategy_test.go
+++ b/strategy/split_strategy_test.go
@@ -5,7 +5,6 @@
package strategy_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -54,7 +53,7 @@ func TestSplitStrategyReport(t *testing.T) {
report := split.Report(snapshots)
fileName := "split.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/apo_strategy_test.go b/strategy/trend/apo_strategy_test.go
index f836826..0511c29 100644
--- a/strategy/trend/apo_strategy_test.go
+++ b/strategy/trend/apo_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestApoStrategyReport(t *testing.T) {
report := apo.Report(snapshots)
fileName := "apo_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/aroon_strategy.go b/strategy/trend/aroon_strategy.go
index 1343147..fcc48ed 100644
--- a/strategy/trend/aroon_strategy.go
+++ b/strategy/trend/aroon_strategy.go
@@ -57,7 +57,7 @@ func (a *AroonStrategy) Compute(c <-chan *asset.Snapshot) <-chan strategy.Action
return strategy.Hold
})
- // Aroon starts only after the a full period.
+ // Aroon starts only after a full period.
actions = helper.Shift(actions, a.Aroon.Period-1, strategy.Hold)
return actions
diff --git a/strategy/trend/aroon_strategy_test.go b/strategy/trend/aroon_strategy_test.go
index f24e278..5f1a5ae 100644
--- a/strategy/trend/aroon_strategy_test.go
+++ b/strategy/trend/aroon_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestAroonStrategyReport(t *testing.T) {
report := aroon.Report(snapshots)
fileName := "aroon_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/bop_strategy_test.go b/strategy/trend/bop_strategy_test.go
index fb21eb5..930ca03 100644
--- a/strategy/trend/bop_strategy_test.go
+++ b/strategy/trend/bop_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestBopStrategyReport(t *testing.T) {
report := bop.Report(snapshots)
fileName := "bop_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/cci_strategy_test.go b/strategy/trend/cci_strategy_test.go
index 5b69f09..f0d4f9c 100644
--- a/strategy/trend/cci_strategy_test.go
+++ b/strategy/trend/cci_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestCciStrategyReport(t *testing.T) {
report := cci.Report(snapshots)
fileName := "cci_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/dema_strategy.go b/strategy/trend/dema_strategy.go
index fd6a4c0..f77a856 100644
--- a/strategy/trend/dema_strategy.go
+++ b/strategy/trend/dema_strategy.go
@@ -79,7 +79,7 @@ func (d *DemaStrategy) Compute(c <-chan *asset.Snapshot) <-chan strategy.Action
return strategy.Hold
})
- // DEMA starts only after the a full periods for each EMA used.
+ // DEMA starts only after a full periods for each EMA used.
actions = helper.Skip(actions, d.Dema2.IdlePeriod())
actions = helper.Shift(actions, d.Dema2.IdlePeriod(), strategy.Hold)
diff --git a/strategy/trend/dema_strategy_test.go b/strategy/trend/dema_strategy_test.go
index 16ea0e6..d725f30 100644
--- a/strategy/trend/dema_strategy_test.go
+++ b/strategy/trend/dema_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestDemaStrategyReport(t *testing.T) {
report := dema.Report(snapshots)
fileName := "dema_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/envelope_strategy_test.go b/strategy/trend/envelope_strategy_test.go
index 2efdbb2..9b110ae 100644
--- a/strategy/trend/envelope_strategy_test.go
+++ b/strategy/trend/envelope_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestEnvelopeStrategyReport(t *testing.T) {
report := envelope.Report(snapshots)
fileName := "envelope_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/golden_cross_strategy_test.go b/strategy/trend/golden_cross_strategy_test.go
index f6ec0a9..b02e68c 100644
--- a/strategy/trend/golden_cross_strategy_test.go
+++ b/strategy/trend/golden_cross_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -27,8 +26,8 @@ func TestGoldenCrossStrategy(t *testing.T) {
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action })
- strategy := trend.NewGoldenCrossStrategyWith(5, 20)
- actual := strategy.Compute(snapshots)
+ gcs := trend.NewGoldenCrossStrategyWith(5, 20)
+ actual := gcs.Compute(snapshots)
err = helper.CheckEquals(actual, expected)
if err != nil {
@@ -42,12 +41,12 @@ func TestGoldenCrossStrategyReport(t *testing.T) {
t.Fatal(err)
}
- strategy := trend.NewGoldenCrossStrategyWith(5, 20)
+ gcs := trend.NewGoldenCrossStrategyWith(5, 20)
- report := strategy.Report(snapshots)
+ report := gcs.Report(snapshots)
fileName := "golden_cross_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/kama_strategy_test.go b/strategy/trend/kama_strategy_test.go
index bf8279a..77d7b47 100644
--- a/strategy/trend/kama_strategy_test.go
+++ b/strategy/trend/kama_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestKamaStrategyReport(t *testing.T) {
report := kama.Report(snapshots)
fileName := "kama_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/kdj_strategy_test.go b/strategy/trend/kdj_strategy_test.go
index 60313ff..ee9f1c1 100644
--- a/strategy/trend/kdj_strategy_test.go
+++ b/strategy/trend/kdj_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestKdjStrategyReport(t *testing.T) {
report := kdj.Report(snapshots)
fileName := "kdj_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/macd_strategy_test.go b/strategy/trend/macd_strategy_test.go
index 38522cd..8a462d9 100644
--- a/strategy/trend/macd_strategy_test.go
+++ b/strategy/trend/macd_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestMacdStrategyReport(t *testing.T) {
report := macd.Report(snapshots)
fileName := "macd_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/qstick_strategy_test.go b/strategy/trend/qstick_strategy_test.go
index 0732f5e..4ac4ba7 100644
--- a/strategy/trend/qstick_strategy_test.go
+++ b/strategy/trend/qstick_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestQstickStrategyReport(t *testing.T) {
report := qstick.Report(snapshots)
fileName := "qstick_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/smma_strategy_test.go b/strategy/trend/smma_strategy_test.go
index 80eff01..7cb8e58 100644
--- a/strategy/trend/smma_strategy_test.go
+++ b/strategy/trend/smma_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestSmmaStrategyReport(t *testing.T) {
report := smma.Report(snapshots)
fileName := "smma_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/trima_strategy.go b/strategy/trend/trima_strategy.go
index 5d6d194..0d2ccfa 100644
--- a/strategy/trend/trima_strategy.go
+++ b/strategy/trend/trima_strategy.go
@@ -71,7 +71,7 @@ func (t *TrimaStrategy) Compute(c <-chan *asset.Snapshot) <-chan strategy.Action
return strategy.Hold
})
- // TRIMA starts only after the a full periods for each EMA used.
+ // TRIMA starts only after a full periods for each EMA used.
actions = helper.Shift(actions, t.Long.IdlePeriod(), strategy.Hold)
return actions
diff --git a/strategy/trend/trima_strategy_test.go b/strategy/trend/trima_strategy_test.go
index d458af6..ea6edc6 100644
--- a/strategy/trend/trima_strategy_test.go
+++ b/strategy/trend/trima_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestTrimaStrategyReport(t *testing.T) {
report := trima.Report(snapshots)
fileName := "trima_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/triple_moving_average_crossover_strategy_test.go b/strategy/trend/triple_moving_average_crossover_strategy_test.go
index ed23108..d29f074 100644
--- a/strategy/trend/triple_moving_average_crossover_strategy_test.go
+++ b/strategy/trend/triple_moving_average_crossover_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -27,8 +26,8 @@ func TestTripleMovingAverageCrossoverStrategy(t *testing.T) {
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action })
- strategy := trend.NewTripleMovingAverageCrossoverStrategyWith(2, 5, 20)
- actual := strategy.Compute(snapshots)
+ tmacStrategy := trend.NewTripleMovingAverageCrossoverStrategyWith(2, 5, 20)
+ actual := tmacStrategy.Compute(snapshots)
err = helper.CheckEquals(actual, expected)
if err != nil {
@@ -42,12 +41,12 @@ func TestTripleMovingAverageCrossoverStrategyReport(t *testing.T) {
t.Fatal(err)
}
- strategy := trend.NewTripleMovingAverageCrossoverStrategyWith(2, 5, 20)
+ tmacStrategy := trend.NewTripleMovingAverageCrossoverStrategyWith(2, 5, 20)
- report := strategy.Report(snapshots)
+ report := tmacStrategy.Report(snapshots)
fileName := "triple_moving_average_crossover_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/trix_strategy_test.go b/strategy/trend/trix_strategy_test.go
index 4d7c4f6..209d786 100644
--- a/strategy/trend/trix_strategy_test.go
+++ b/strategy/trend/trix_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestTrixStrategyReport(t *testing.T) {
report := trix.Report(snapshots)
fileName := "trix_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/tsi_strategy_test.go b/strategy/trend/tsi_strategy_test.go
index be1837a..1ce8e7d 100644
--- a/strategy/trend/tsi_strategy_test.go
+++ b/strategy/trend/tsi_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestTsiStrategyReport(t *testing.T) {
report := tsi.Report(snapshots)
fileName := "tsi_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/trend/vwma_strategy.go b/strategy/trend/vwma_strategy.go
index e63fd0a..e9666d6 100644
--- a/strategy/trend/vwma_strategy.go
+++ b/strategy/trend/vwma_strategy.go
@@ -61,7 +61,7 @@ func (v *VwmaStrategy) Compute(c <-chan *asset.Snapshot) <-chan strategy.Action
return strategy.Hold
})
- // VWMA starts only after the a full period.
+ // VWMA starts only after a full period.
actions = helper.Shift(actions, v.Vwma.Period-1, strategy.Hold)
return actions
@@ -110,7 +110,7 @@ func (v *VwmaStrategy) calculateSmaAndVwma(c <-chan *asset.Snapshot) (<-chan flo
snapshots := helper.Duplicate(c, 2)
closings := helper.Duplicate(asset.SnapshotsAsClosings(snapshots[0]), 2)
- volume := helper.Map(snapshots[1], func(s *asset.Snapshot) float64 { return float64(s.Volume) })
+ volume := asset.SnapshotsAsVolumes(snapshots[1])
smas := v.Sma.Compute(closings[0])
vwmas := v.Vwma.Compute(closings[1], volume)
diff --git a/strategy/trend/vwma_strategy_test.go b/strategy/trend/vwma_strategy_test.go
index f3d7542..82c9ff8 100644
--- a/strategy/trend/vwma_strategy_test.go
+++ b/strategy/trend/vwma_strategy_test.go
@@ -5,7 +5,6 @@
package trend_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestVwmaStrategyReport(t *testing.T) {
report := vwma.Report(snapshots)
fileName := "vwma_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volatility/bollinger_bands_strategy_test.go b/strategy/volatility/bollinger_bands_strategy_test.go
index f82671b..59e31ee 100644
--- a/strategy/volatility/bollinger_bands_strategy_test.go
+++ b/strategy/volatility/bollinger_bands_strategy_test.go
@@ -5,7 +5,6 @@
package volatility_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestBollingerBandsStrategyReport(t *testing.T) {
report := bb.Report(snapshots)
fileName := "bollinger_bands_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volatility/super_trend_strategy_test.go b/strategy/volatility/super_trend_strategy_test.go
index faef4d5..f422147 100644
--- a/strategy/volatility/super_trend_strategy_test.go
+++ b/strategy/volatility/super_trend_strategy_test.go
@@ -5,7 +5,6 @@
package volatility_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -47,7 +46,7 @@ func TestSuperTrendStrategyReport(t *testing.T) {
report := superTrend.Report(snapshots)
fileName := "super_trend_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/chaikin_money_flow_strategy_test.go b/strategy/volume/chaikin_money_flow_strategy_test.go
index fb53139..6398ed3 100644
--- a/strategy/volume/chaikin_money_flow_strategy_test.go
+++ b/strategy/volume/chaikin_money_flow_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestChaikinMoneyFlowStrategyReport(t *testing.T) {
report := cmfs.Report(snapshots)
fileName := "chaikin_money_flow_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/ease_of_movement_strategy_test.go b/strategy/volume/ease_of_movement_strategy_test.go
index f3a2bf3..d304ef4 100644
--- a/strategy/volume/ease_of_movement_strategy_test.go
+++ b/strategy/volume/ease_of_movement_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestEaseOfMovementStrategyReport(t *testing.T) {
report := emvs.Report(snapshots)
fileName := "ease_of_movement_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/force_index_strategy_test.go b/strategy/volume/force_index_strategy_test.go
index 3aade49..1ff2bc6 100644
--- a/strategy/volume/force_index_strategy_test.go
+++ b/strategy/volume/force_index_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestForceIndexStrategyReport(t *testing.T) {
report := fis.Report(snapshots)
fileName := "force_index_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/money_flow_index_strategy_test.go b/strategy/volume/money_flow_index_strategy_test.go
index 598a8c5..50571fd 100644
--- a/strategy/volume/money_flow_index_strategy_test.go
+++ b/strategy/volume/money_flow_index_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestMoneyFlowIndexStrategyReport(t *testing.T) {
report := mfis.Report(snapshots)
fileName := "money_flow_index_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/negative_volume_index_strategy_test.go b/strategy/volume/negative_volume_index_strategy_test.go
index 1468008..1e3ad89 100644
--- a/strategy/volume/negative_volume_index_strategy_test.go
+++ b/strategy/volume/negative_volume_index_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestNegativeVolumeIndexStrategyReport(t *testing.T) {
report := nvis.Report(snapshots)
fileName := "negative_volume_index_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/strategy/volume/weighted_average_price_strategy_test.go b/strategy/volume/weighted_average_price_strategy_test.go
index f15578d..696bf70 100644
--- a/strategy/volume/weighted_average_price_strategy_test.go
+++ b/strategy/volume/weighted_average_price_strategy_test.go
@@ -5,7 +5,6 @@
package volume_test
import (
- "os"
"testing"
"github.com/cinar/indicator/v2/asset"
@@ -46,7 +45,7 @@ func TestVolumeWeightedAveragePriceStrategyReport(t *testing.T) {
report := vwaps.Report(snapshots)
fileName := "volume_weighted_average_price_strategy.html"
- defer os.Remove(fileName)
+ defer helper.Remove(t, fileName)
err = report.WriteToFile(fileName)
if err != nil {
diff --git a/trend/README.md b/trend/README.md
index c1efe36..662c8ca 100644
--- a/trend/README.md
+++ b/trend/README.md
@@ -343,7 +343,7 @@ const (
```
-## type [Apo]()
+## type [Apo]()
Apo represents the configuration parameters for calculating the Absolute Price Oscillator \(APO\). An APO value crossing above zero suggests a bullish trend, while crossing below zero indicates a bearish trend. Positive APO values signify an upward trend, while negative values signify a downward trend.
@@ -380,7 +380,7 @@ type Apo[T helper.Number] struct {
```
-### func [NewApo]()
+### func [NewApo]()
```go
func NewApo[T helper.Number]() *Apo[T]
@@ -389,7 +389,7 @@ func NewApo[T helper.Number]() *Apo[T]
NewApo function initializes a new APO instance with the default parameters.
-### func \(\*Apo\[T\]\) [Compute]()
+### func \(\*Apo\[T\]\) [Compute]()
```go
func (apo *Apo[T]) Compute(c <-chan T) <-chan T
@@ -508,7 +508,7 @@ func NewCci[T helper.Number]() *Cci[T]
NewCci function initializes a new CCI instance with the default parameters.
-### func [NewCciWithPeriod]()
+### func [NewCciWithPeriod]()
```go
func NewCciWithPeriod[T helper.Number](period int) *Cci[T]
@@ -517,7 +517,7 @@ func NewCciWithPeriod[T helper.Number](period int) *Cci[T]
NewCciWithPeriod function initializes a new CCI instance with the given period.
-### func \(\*Cci\[T\]\) [Compute]()
+### func \(\*Cci\[T\]\) [Compute]()
```go
func (c *Cci[T]) Compute(highs, lows, closings <-chan T) <-chan T
@@ -526,7 +526,7 @@ func (c *Cci[T]) Compute(highs, lows, closings <-chan T) <-chan T
Compute function takes a channel of numbers and computes the CCI and the signal line.
-### func \(\*Cci\[T\]\) [IdlePeriod]()
+### func \(\*Cci\[T\]\) [IdlePeriod]()
```go
func (c *Cci[T]) IdlePeriod() int
@@ -1189,7 +1189,7 @@ func NewMovingMaxWithPeriod[T helper.Number](period int) *MovingMax[T]
NewMovingMaxWithPeriod function initializes a new Moving Max instance with the given period.
-### func \(\*MovingMax\[T\]\) [Compute]()
+### func \(\*MovingMax\[T\]\) [Compute]()
```go
func (m *MovingMax[T]) Compute(c <-chan T) <-chan T
@@ -1198,7 +1198,7 @@ func (m *MovingMax[T]) Compute(c <-chan T) <-chan T
Compute function takes a channel of numbers and computes the Moving Max over the specified period.
-### func \(\*MovingMax\[T\]\) [IdlePeriod]()
+### func \(\*MovingMax\[T\]\) [IdlePeriod]()
```go
func (m *MovingMax[T]) IdlePeriod() int
@@ -1239,7 +1239,7 @@ func NewMovingMinWithPeriod[T helper.Number](period int) *MovingMin[T]
NewMovingMinWithPeriod function initializes a new Moving Min instance with the given period.
-### func \(\*MovingMin\[T\]\) [Compute]()
+### func \(\*MovingMin\[T\]\) [Compute]()
```go
func (m *MovingMin[T]) Compute(c <-chan T) <-chan T
@@ -1248,7 +1248,7 @@ func (m *MovingMin[T]) Compute(c <-chan T) <-chan T
Compute function takes a channel of numbers and computes the Moving Min over the specified period.
-### func \(\*MovingMin\[T\]\) [IdlePeriod]()
+### func \(\*MovingMin\[T\]\) [IdlePeriod]()
```go
func (m *MovingMin[T]) IdlePeriod() int
diff --git a/trend/apo.go b/trend/apo.go
index a5ddc83..32512be 100644
--- a/trend/apo.go
+++ b/trend/apo.go
@@ -6,6 +6,7 @@ package trend
import "github.com/cinar/indicator/v2/helper"
+//goland:noinspection ALL
const (
// DefaultApoFastPeriod is the default APO fast period of 14.
DefaultApoFastPeriod = 14
diff --git a/trend/aroon.go b/trend/aroon.go
index df3822b..e78a938 100644
--- a/trend/aroon.go
+++ b/trend/aroon.go
@@ -43,14 +43,11 @@ func NewAroon[T helper.Number]() *Aroon[T] {
// Compute function takes a channel of numbers and computes the Aroon
// over the specified period.
func (a *Aroon[T]) Compute(high, low <-chan T) (<-chan T, <-chan T) {
- max := NewMovingMax[T]()
- max.Period = a.Period
+ movingMax := NewMovingMaxWithPeriod[T](a.Period)
+ movingMin := NewMovingMinWithPeriod[T](a.Period)
- min := NewMovingMin[T]()
- min.Period = a.Period
-
- sinceLastHigh := helper.Since[T, T](max.Compute(high))
- sinceLastLow := helper.Since[T, T](min.Compute(low))
+ sinceLastHigh := helper.Since[T, T](movingMax.Compute(high))
+ sinceLastLow := helper.Since[T, T](movingMin.Compute(low))
// Aroon Up = ((25 - Period Since Last 25 Period High) / 25) * 100
aroonUp := helper.MultiplyBy(sinceLastHigh, -1)
diff --git a/trend/cci.go b/trend/cci.go
index 59fbd49..c7722ed 100644
--- a/trend/cci.go
+++ b/trend/cci.go
@@ -33,9 +33,7 @@ type Cci[T helper.Number] struct {
// NewCci function initializes a new CCI instance with the default parameters.
func NewCci[T helper.Number]() *Cci[T] {
- return &Cci[T]{
- Period: DefaultCciPeriod,
- }
+ return NewCciWithPeriod[T](DefaultCciPeriod)
}
// NewCciWithPeriod function initializes a new CCI instance with the given period.
diff --git a/trend/kama.go b/trend/kama.go
index 70316a5..09dd4af 100644
--- a/trend/kama.go
+++ b/trend/kama.go
@@ -92,7 +92,7 @@ func (k *Kama[T]) Compute(closings <-chan T) <-chan T {
helper.IncrementBy(
helper.MultiplyBy(
ers,
- (fastSc-slowSc),
+ fastSc-slowSc,
),
slowSc,
),
diff --git a/trend/moving_max.go b/trend/moving_max.go
index bb6432e..78e0ce6 100644
--- a/trend/moving_max.go
+++ b/trend/moving_max.go
@@ -22,10 +22,9 @@ func NewMovingMax[T helper.Number]() *MovingMax[T] {
// NewMovingMaxWithPeriod function initializes a new Moving Max instance with the given period.
func NewMovingMaxWithPeriod[T helper.Number](period int) *MovingMax[T] {
- max := NewMovingMax[T]()
- max.Period = period
-
- return max
+ return &MovingMax[T]{
+ Period: period,
+ }
}
// Compute function takes a channel of numbers and computes the
diff --git a/trend/moving_max_test.go b/trend/moving_max_test.go
index 7383eb8..ceba337 100644
--- a/trend/moving_max_test.go
+++ b/trend/moving_max_test.go
@@ -15,8 +15,8 @@ func TestMovingMax(t *testing.T) {
input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
expected := helper.SliceToChan([]int{20, 20, 5, 8, 10, 10, 10})
- max := trend.NewMovingMaxWithPeriod[int](4)
- actual := max.Compute(input)
+ movingMax := trend.NewMovingMaxWithPeriod[int](4)
+ actual := movingMax.Compute(input)
err := helper.CheckEquals(actual, expected)
if err != nil {
diff --git a/trend/moving_min.go b/trend/moving_min.go
index 5963223..9efb59c 100644
--- a/trend/moving_min.go
+++ b/trend/moving_min.go
@@ -22,10 +22,9 @@ func NewMovingMin[T helper.Number]() *MovingMin[T] {
// NewMovingMinWithPeriod function initializes a new Moving Min instance with the given period.
func NewMovingMinWithPeriod[T helper.Number](period int) *MovingMin[T] {
- min := NewMovingMin[T]()
- min.Period = period
-
- return min
+ return &MovingMin[T]{
+ Period: period,
+ }
}
// Compute function takes a channel of numbers and computes the
diff --git a/trend/moving_min_test.go b/trend/moving_min_test.go
index e52e0dc..a106fb6 100644
--- a/trend/moving_min_test.go
+++ b/trend/moving_min_test.go
@@ -15,8 +15,8 @@ func TestMovingMin(t *testing.T) {
input := helper.SliceToChan([]int{-10, 20, -4, -5, 1, 5, 8, 10, -20, 4})
expected := helper.SliceToChan([]int{-10, -5, -5, -5, 1, -20, -20})
- min := trend.NewMovingMinWithPeriod[int](4)
- actual := min.Compute(input)
+ movingMin := trend.NewMovingMinWithPeriod[int](4)
+ actual := movingMin.Compute(input)
err := helper.CheckEquals(actual, expected)
if err != nil {
diff --git a/volatility/README.md b/volatility/README.md
index e2d95ec..86a8c29 100644
--- a/volatility/README.md
+++ b/volatility/README.md
@@ -150,6 +150,15 @@ const (
)
```
+
+
+```go
+const (
+ // DefaultMovingStdPeriod is the default time period for Moving Standard Deviation.
+ DefaultMovingStdPeriod = 1
+)
+```
+
```go
@@ -169,7 +178,7 @@ const (
```
-## type [AccelerationBands]()
+## type [AccelerationBands]()
AccelerationBands represents the configuration parameters for calculating the Acceleration Bands.
@@ -194,7 +203,7 @@ type AccelerationBands[T helper.Number] struct {
```
-### func [NewAccelerationBands]()
+### func [NewAccelerationBands]()
```go
func NewAccelerationBands[T helper.Number]() *AccelerationBands[T]
@@ -203,7 +212,7 @@ func NewAccelerationBands[T helper.Number]() *AccelerationBands[T]
NewAccelerationBands function initializes a new Acceleration Bands instance with the default parameters.
-### func \(\*AccelerationBands\[T\]\) [Compute]()
+### func \(\*AccelerationBands\[T\]\) [Compute]()
```go
func (a *AccelerationBands[T]) Compute(high, low, closing <-chan T) (<-chan T, <-chan T, <-chan T)
@@ -212,7 +221,7 @@ func (a *AccelerationBands[T]) Compute(high, low, closing <-chan T) (<-chan T, <
Compute function takes a channel of numbers and computes the Acceleration Bands over the specified period.
-### func \(\*AccelerationBands\[T\]\) [IdlePeriod]()
+### func \(\*AccelerationBands\[T\]\) [IdlePeriod]()
```go
func (a *AccelerationBands[T]) IdlePeriod() int
@@ -296,7 +305,7 @@ IdlePeriod is the initial period that Acceleration Bands won't yield any results
BollingerBandWidth represents the configuration parameters for calculating the Bollinger Band Width. It measures the percentage difference between the upper band and the lower band. It decreases as Bollinger Bands narrows and increases as Bollinger Bands widens.
-During a period of rising price volatity the band width widens, and during a period of low market volatity band width contracts.
+During a period of rising price volatity the bandwidth widens, and during a period of low market volatity bandwidth contracts.
```
Band Width = (Upper Band - Lower Band) / Middle BollingerBandWidth
@@ -578,7 +587,7 @@ func (k *KeltnerChannel[T]) IdlePeriod() int
IdlePeriod is the initial period that Keltner Channel won't yield any results.
-## type [MovingStd]()
+## type [MovingStd]()
MovingStd represents the configuration parameters for calculating the Moving Standard Deviation over the specified period.
@@ -594,7 +603,7 @@ type MovingStd[T helper.Number] struct {
```
-### func [NewMovingStd]()
+### func [NewMovingStd]()
```go
func NewMovingStd[T helper.Number]() *MovingStd[T]
@@ -603,7 +612,7 @@ func NewMovingStd[T helper.Number]() *MovingStd[T]
NewMovingStd function initializes a new Moving Standard Deviation instance with the default parameters.
-### func [NewMovingStdWithPeriod]()
+### func [NewMovingStdWithPeriod]()
```go
func NewMovingStdWithPeriod[T helper.Number](period int) *MovingStd[T]
@@ -612,7 +621,7 @@ func NewMovingStdWithPeriod[T helper.Number](period int) *MovingStd[T]
NewMovingStdWithPeriod function initializes a new Moving Standard Deviation instance with the given period.
-### func \(\*MovingStd\[T\]\) [Compute]()
+### func \(\*MovingStd\[T\]\) [Compute]()
```go
func (m *MovingStd[T]) Compute(c <-chan T) <-chan T
@@ -621,7 +630,7 @@ func (m *MovingStd[T]) Compute(c <-chan T) <-chan T
Compute function takes a channel of numbers and computes the Moving Standard Deviation over the specified period.
-### func \(\*MovingStd\[T\]\) [IdlePeriod]()
+### func \(\*MovingStd\[T\]\) [IdlePeriod]()
```go
func (m *MovingStd[T]) IdlePeriod() int
diff --git a/volatility/acceleration_bands.go b/volatility/acceleration_bands.go
index df5a6f3..c6f4a0a 100644
--- a/volatility/acceleration_bands.go
+++ b/volatility/acceleration_bands.go
@@ -9,6 +9,7 @@ import (
"github.com/cinar/indicator/v2/trend"
)
+//goland:noinspection GoUnnecessarilyExportedIdentifiers
const (
// DefaultAccelerationBandsPeriod is the default period for the Acceleration Bands.
DefaultAccelerationBandsPeriod = 20
diff --git a/volatility/bollinger_band_width.go b/volatility/bollinger_band_width.go
index c9be48d..6cd959a 100644
--- a/volatility/bollinger_band_width.go
+++ b/volatility/bollinger_band_width.go
@@ -12,8 +12,8 @@ import (
// It measures the percentage difference between the upper band and the lower band. It decreases as
// Bollinger Bands narrows and increases as Bollinger Bands widens.
//
-// During a period of rising price volatity the band width widens, and during a period of low market
-// volatity band width contracts.
+// During a period of rising price volatity the bandwidth widens, and during a period of low market
+// volatity bandwidth contracts.
//
// Band Width = (Upper Band - Lower Band) / Middle BollingerBandWidth
//
diff --git a/volatility/chandelier_exit.go b/volatility/chandelier_exit.go
index 117b7bb..6d305b9 100644
--- a/volatility/chandelier_exit.go
+++ b/volatility/chandelier_exit.go
@@ -48,19 +48,19 @@ func (c *ChandelierExit[T]) Compute(highs, lows, closings <-chan T) (<-chan T, <
highsSplice := helper.Duplicate(highs, 2)
lowsSplice := helper.Duplicate(lows, 2)
- max := trend.NewMovingMaxWithPeriod[T](c.Period)
- min := trend.NewMovingMinWithPeriod[T](c.Period)
+ movingMax := trend.NewMovingMaxWithPeriod[T](c.Period)
+ movingMin := trend.NewMovingMinWithPeriod[T](c.Period)
atr := NewAtrWithPeriod[T](c.Period)
maxHighs := helper.Skip(
- max.Compute(highsSplice[0]),
- atr.IdlePeriod()-max.IdlePeriod(),
+ movingMax.Compute(highsSplice[0]),
+ atr.IdlePeriod()-movingMax.IdlePeriod(),
)
minLows := helper.Skip(
- min.Compute(lowsSplice[0]),
- atr.IdlePeriod()-min.IdlePeriod(),
+ movingMin.Compute(lowsSplice[0]),
+ atr.IdlePeriod()-movingMin.IdlePeriod(),
)
atr3Splice := helper.Duplicate(
diff --git a/volatility/moving_std.go b/volatility/moving_std.go
index 5ed4177..a376c36 100644
--- a/volatility/moving_std.go
+++ b/volatility/moving_std.go
@@ -10,6 +10,11 @@ import (
"github.com/cinar/indicator/v2/helper"
)
+const (
+ // DefaultMovingStdPeriod is the default time period for Moving Standard Deviation.
+ DefaultMovingStdPeriod = 1
+)
+
// MovingStd represents the configuration parameters for calculating the Moving Standard Deviation
// over the specified period.
//
@@ -21,7 +26,7 @@ type MovingStd[T helper.Number] struct {
// NewMovingStd function initializes a new Moving Standard Deviation instance with the default parameters.
func NewMovingStd[T helper.Number]() *MovingStd[T] {
- return NewMovingStdWithPeriod[T](1)
+ return NewMovingStdWithPeriod[T](DefaultMovingStdPeriod)
}
// NewMovingStdWithPeriod function initializes a new Moving Standard Deviation instance with the given period.
diff --git a/volatility/ulcer_index.go b/volatility/ulcer_index.go
index c5dffca..f7e67be 100644
--- a/volatility/ulcer_index.go
+++ b/volatility/ulcer_index.go
@@ -44,14 +44,14 @@ func (u *UlcerIndex[T]) Compute(closings <-chan T) <-chan T {
closingsSplice := helper.Duplicate(closings, 2)
// High Closings = Max(period, Closings)
- max := trend.NewMovingMaxWithPeriod[T](u.Period)
+ movingMax := trend.NewMovingMaxWithPeriod[T](u.Period)
highsSplice := helper.Duplicate(
- max.Compute(closingsSplice[0]),
+ movingMax.Compute(closingsSplice[0]),
2,
)
// Percentage Drawdown = 100 * ((Closings - High Closings) / High Closings)
- closingsSplice[1] = helper.Skip(closingsSplice[1], max.Period-1)
+ closingsSplice[1] = helper.Skip(closingsSplice[1], movingMax.Period-1)
percentageDrawdown := helper.MultiplyBy(
helper.Divide(