From 35c06ec2ab40dfffe69d804167ac7aba99b4900a Mon Sep 17 00:00:00 2001 From: Evgeny Samsonov Date: Thu, 6 Apr 2023 23:50:21 +0300 Subject: [PATCH 1/4] Flat max diff in percent --- indicator/trend.go | 29 ++++++++++++++++++++++++----- indicator/trend_test.go | 30 +++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/indicator/trend.go b/indicator/trend.go index 8ff31c6..6677308 100644 --- a/indicator/trend.go +++ b/indicator/trend.go @@ -8,33 +8,52 @@ const ( DownTrend float64 = -1 ) +type TrendOption func(*Trend) + +func TrendWithFlatMaxDiffInPercent(val bool) func(*Trend) { + return func(t *Trend) { + t.flatMaxDiffInPercent = val + } +} + // Trend returns a trend direction. // It bases on fast (with shorter period) and slow EMA. // flatMaxDiff allows setting max difference between // fast and slow EMA when Calculate returns the flat. type Trend struct { - fastEMAIndicator Indicator - slowEMAIndicator Indicator - flatMaxDiff float64 + fastEMAIndicator Indicator + slowEMAIndicator Indicator + flatMaxDiff float64 + flatMaxDiffInPercent bool } func NewTrend( fastEMAIndicator Indicator, slowEMAIndicator Indicator, flatMaxDiff float64, + opts ...TrendOption, ) *Trend { - return &Trend{ + trend := &Trend{ fastEMAIndicator: fastEMAIndicator, slowEMAIndicator: slowEMAIndicator, flatMaxDiff: flatMaxDiff, } + for _, opt := range opts { + opt(trend) + } + return trend } func (t *Trend) Calculate(index int) float64 { fastVal := t.fastEMAIndicator.Calculate(index) slowVal := t.slowEMAIndicator.Calculate(index) - if math.Abs(fastVal-slowVal)-t.flatMaxDiff <= 1e-6 { + flatMaxDiff := t.flatMaxDiff + if t.flatMaxDiffInPercent { + flatMaxDiff = slowVal * t.flatMaxDiff / 100 + } + + if math.Abs(fastVal-slowVal)-flatMaxDiff <= 1e-6 { return FlatTrend } if fastVal > slowVal { diff --git a/indicator/trend_test.go b/indicator/trend_test.go index bc26681..63102eb 100644 --- a/indicator/trend_test.go +++ b/indicator/trend_test.go @@ -8,10 +8,11 @@ import ( func TestTrend_Calculate(t *testing.T) { tests := []struct { - name string - fastVal float64 - slowVal float64 - want float64 + name string + fastVal float64 + slowVal float64 + flatMaxDiffInPercent bool + want float64 }{ { name: "up trend", @@ -37,6 +38,20 @@ func TestTrend_Calculate(t *testing.T) { slowVal: 1.0, want: FlatTrend, }, + { + name: "flat trend, diff in percent", + fastVal: 100.5, + slowVal: 100, + flatMaxDiffInPercent: true, + want: FlatTrend, + }, + { + name: "up trend, diff in percent", + fastVal: 100.7, + slowVal: 100, + flatMaxDiffInPercent: true, + want: UpTrend, + }, } for _, tt := range tests { @@ -44,7 +59,12 @@ func TestTrend_Calculate(t *testing.T) { slowEMAIndicator := &MockIndicator{} fastEMAIndicator := &MockIndicator{} - ind := NewTrend(fastEMAIndicator, slowEMAIndicator, 0.6) + ind := NewTrend( + fastEMAIndicator, + slowEMAIndicator, + 0.6, + TrendWithFlatMaxDiffInPercent(tt.flatMaxDiffInPercent), + ) fastEMAIndicator.On("Calculate", 1).Return(tt.fastVal) slowEMAIndicator.On("Calculate", 1).Return(tt.slowVal) From fe6a7fcd227a92d9dd1a7459081e9accbe2361c1 Mon Sep 17 00:00:00 2001 From: Evgeny Samsonov Date: Thu, 6 Apr 2023 23:54:26 +0300 Subject: [PATCH 2/4] Add github action & Makefile --- .github/workflows/lint.yml | 13 +++++++++++++ .github/workflows/test.yml | 21 +++++++++++++++++++++ Makefile | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 Makefile diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..9a9b53c --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,13 @@ +name: golangci-lint +on: + push: +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.52.2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..55c2b08 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: test +on: + push: +jobs: + test: + strategy: + matrix: + platform: [ ubuntu-latest ] + runs-on: ${{ matrix.platform }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Install go + uses: actions/setup-go@v2 + with: + go-version: '^1.15' + - name: Test + run: go test -gcflags='-N -l' -race -coverprofile=coverage.txt ./... + - name: Upload coverage to Codecov + run: bash <(curl -s https://codecov.io/bash) + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f496f37 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +.PHONY: help lint test doc +.DEFAULT_GOAL := help + +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +pre-push: lint test ## Run golang lint and test + +lint: ## Run golang lint using docker + go mod download + docker run --rm \ + -v ${GOPATH}/pkg/mod:/go/pkg/mod \ + -v ${PWD}:/app \ + -w /app \ + golangci/golangci-lint:v1.52.2 \ + golangci-lint run -v --modules-download-mode=readonly + +test: ## Run tests + go test ./... From cbfe242fb0f70781710ff1e512c8558309b697c0 Mon Sep 17 00:00:00 2001 From: Evgeny Samsonov Date: Sat, 8 Apr 2023 22:43:54 +0300 Subject: [PATCH 3/4] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb161c2..c88609e 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ fmt.Println(atrIndicator.Calculate(1)) // 22.84552 ### Trend -The indicator returns a trend direction. It bases on fast (with shorter period) and slow EMA. The third parameter of NewTrend allows setting max difference between fast and slow EMA when Calculate returns the flat. +The indicator returns a trend direction. It bases on fast (with shorter period) and slow EMA. The third parameter (flatMaxDiff) of NewTrend allows setting max difference between fast and slow EMA when Calculate returns the flat. Option TrendWithFlatMaxDiffInPercent allows to pass flatMaxDiff in percent ```go fastEMAIndicator, err := indicator.NewExponentialMovingAverage(series, 14) @@ -88,7 +88,7 @@ if err != nil { log.Fatalln(err) } -trendIndicator := indicator.NewTrend(fastEMAIndicator, slowEMAIndicator, 0.6) +trendIndicator := indicator.NewTrend(fastEMAIndicator, slowEMAIndicator, 0.6, TrendWithFlatMaxDiffInPercent(false)) trend := trendIndicator.Calculate(1) switch trend { case indicator.UpTrend: From fe17c1b9e14119f822c4420240154df2f026f47b Mon Sep 17 00:00:00 2001 From: Evgeny Samsonov Date: Sat, 8 Apr 2023 22:49:00 +0300 Subject: [PATCH 4/4] Add comment --- indicator/trend.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indicator/trend.go b/indicator/trend.go index 6677308..9783c49 100644 --- a/indicator/trend.go +++ b/indicator/trend.go @@ -10,6 +10,8 @@ const ( type TrendOption func(*Trend) +// TrendWithFlatMaxDiffInPercent allows to pass flatMaxDiff in percent. +// The default value is false func TrendWithFlatMaxDiffInPercent(val bool) func(*Trend) { return func(t *Trend) { t.flatMaxDiffInPercent = val