-
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
598 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<!-- Code generated by gomarkdoc. DO NOT EDIT --> | ||
|
||
# volume | ||
|
||
```go | ||
import "github.com/cinar/indicator/v2/strategy/volume" | ||
``` | ||
|
||
Package volume contains the volume strategy functions. | ||
|
||
This package belongs to the Indicator project. Indicator is a Golang module that supplies a variety of technical indicators, strategies, and a backtesting framework for analysis. | ||
|
||
### License | ||
|
||
``` | ||
Copyright (c) 2021-2024 Onur Cinar. | ||
The source code is provided under GNU AGPLv3 License. | ||
https://github.com/cinar/indicator | ||
``` | ||
|
||
### Disclaimer | ||
|
||
The information provided on this project is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security. | ||
|
||
## Index | ||
|
||
- [Constants](<#constants>) | ||
- [func AllStrategies\(\) \[\]strategy.Strategy](<#AllStrategies>) | ||
- [type MoneyFlowIndexStrategy](<#MoneyFlowIndexStrategy>) | ||
- [func NewMoneyFlowIndexStrategy\(\) \*MoneyFlowIndexStrategy](<#NewMoneyFlowIndexStrategy>) | ||
- [func NewMoneyFlowIndexStrategyWith\(sellAt, buyAt float64\) \*MoneyFlowIndexStrategy](<#NewMoneyFlowIndexStrategyWith>) | ||
- [func \(m \*MoneyFlowIndexStrategy\) Compute\(snapshots \<\-chan \*asset.Snapshot\) \<\-chan strategy.Action](<#MoneyFlowIndexStrategy.Compute>) | ||
- [func \(m \*MoneyFlowIndexStrategy\) Name\(\) string](<#MoneyFlowIndexStrategy.Name>) | ||
- [func \(m \*MoneyFlowIndexStrategy\) Report\(c \<\-chan \*asset.Snapshot\) \*helper.Report](<#MoneyFlowIndexStrategy.Report>) | ||
|
||
|
||
## Constants | ||
|
||
<a name="DefaultMoneyFlowIndexStrategySellAt"></a> | ||
|
||
```go | ||
const ( | ||
// DefaultMoneyFlowIndexStrategySellAt is the default sell at of 80. | ||
DefaultMoneyFlowIndexStrategySellAt = 80 | ||
|
||
// DefaultMoneyFlowIndexStrategyBuyAt is the default buy at of 20. | ||
DefaultMoneyFlowIndexStrategyBuyAt = 20 | ||
) | ||
``` | ||
|
||
<a name="AllStrategies"></a> | ||
## func [AllStrategies](<https://github.com/cinar/indicator/blob/master/strategy/volume/volume.go#L26>) | ||
|
||
```go | ||
func AllStrategies() []strategy.Strategy | ||
``` | ||
|
||
AllStrategies returns a slice containing references to all available volume strategies. | ||
|
||
<a name="MoneyFlowIndexStrategy"></a> | ||
## type [MoneyFlowIndexStrategy](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L26-L35>) | ||
|
||
MoneyFlowIndexStrategy represents the configuration parameters for calculating the Money Flow Index strategy. Recommends a Sell action when it crosses over 80, and recommends a Buy action when it crosses below 20. | ||
|
||
```go | ||
type MoneyFlowIndexStrategy struct { | ||
// MoneyFlowIndex is the Money Flow Index indicator instance. | ||
MoneyFlowIndex *volume.Mfi[float64] | ||
|
||
// SellAt is the sell at value. | ||
SellAt float64 | ||
|
||
// BuyAt is the buy at value. | ||
BuyAt float64 | ||
} | ||
``` | ||
|
||
<a name="NewMoneyFlowIndexStrategy"></a> | ||
### func [NewMoneyFlowIndexStrategy](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L38>) | ||
|
||
```go | ||
func NewMoneyFlowIndexStrategy() *MoneyFlowIndexStrategy | ||
``` | ||
|
||
NewMoneyFlowIndexStrategy function initializes a new Money Flow Index strategy instance with the default parameters. | ||
|
||
<a name="NewMoneyFlowIndexStrategyWith"></a> | ||
### func [NewMoneyFlowIndexStrategyWith](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L47>) | ||
|
||
```go | ||
func NewMoneyFlowIndexStrategyWith(sellAt, buyAt float64) *MoneyFlowIndexStrategy | ||
``` | ||
|
||
NewMoneyFlowIndexStrategyWith function initializes a new Money Flow Index strategy instance with the given parameters. | ||
|
||
<a name="MoneyFlowIndexStrategy.Compute"></a> | ||
### func \(\*MoneyFlowIndexStrategy\) [Compute](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L61>) | ||
|
||
```go | ||
func (m *MoneyFlowIndexStrategy) Compute(snapshots <-chan *asset.Snapshot) <-chan strategy.Action | ||
``` | ||
|
||
Compute processes the provided asset snapshots and generates a stream of actionable recommendations. | ||
|
||
<a name="MoneyFlowIndexStrategy.Name"></a> | ||
### func \(\*MoneyFlowIndexStrategy\) [Name](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L56>) | ||
|
||
```go | ||
func (m *MoneyFlowIndexStrategy) Name() string | ||
``` | ||
|
||
Name returns the name of the strategy. | ||
|
||
<a name="MoneyFlowIndexStrategy.Report"></a> | ||
### func \(\*MoneyFlowIndexStrategy\) [Report](<https://github.com/cinar/indicator/blob/master/strategy/volume/money_flow_index_strategy.go#L90>) | ||
|
||
```go | ||
func (m *MoneyFlowIndexStrategy) Report(c <-chan *asset.Snapshot) *helper.Report | ||
``` | ||
|
||
Report processes the provided asset snapshots and generates a report annotated with the recommended actions. | ||
|
||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>) |
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,137 @@ | ||
// Copyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package volume | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cinar/indicator/v2/asset" | ||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/strategy" | ||
"github.com/cinar/indicator/v2/volume" | ||
) | ||
|
||
const ( | ||
// DefaultMoneyFlowIndexStrategySellAt is the default sell at of 80. | ||
DefaultMoneyFlowIndexStrategySellAt = 80 | ||
|
||
// DefaultMoneyFlowIndexStrategyBuyAt is the default buy at of 20. | ||
DefaultMoneyFlowIndexStrategyBuyAt = 20 | ||
) | ||
|
||
// MoneyFlowIndexStrategy represents the configuration parameters for calculating the Money Flow Index strategy. | ||
// Recommends a Sell action when it crosses over 80, and recommends a Buy action when it crosses below 20. | ||
type MoneyFlowIndexStrategy struct { | ||
// MoneyFlowIndex is the Money Flow Index indicator instance. | ||
MoneyFlowIndex *volume.Mfi[float64] | ||
|
||
// SellAt is the sell at value. | ||
SellAt float64 | ||
|
||
// BuyAt is the buy at value. | ||
BuyAt float64 | ||
} | ||
|
||
// NewMoneyFlowIndexStrategy function initializes a new Money Flow Index strategy instance with the default parameters. | ||
func NewMoneyFlowIndexStrategy() *MoneyFlowIndexStrategy { | ||
return NewMoneyFlowIndexStrategyWith( | ||
DefaultMoneyFlowIndexStrategySellAt, | ||
DefaultMoneyFlowIndexStrategyBuyAt, | ||
) | ||
} | ||
|
||
// NewMoneyFlowIndexStrategyWith function initializes a new Money Flow Index strategy instance with the | ||
// given parameters. | ||
func NewMoneyFlowIndexStrategyWith(sellAt, buyAt float64) *MoneyFlowIndexStrategy { | ||
return &MoneyFlowIndexStrategy{ | ||
MoneyFlowIndex: volume.NewMfi[float64](), | ||
SellAt: sellAt, | ||
BuyAt: buyAt, | ||
} | ||
} | ||
|
||
// Name returns the name of the strategy. | ||
func (m *MoneyFlowIndexStrategy) Name() string { | ||
return fmt.Sprintf("Money Flow Index Strategy (%f)", m.SellAt) | ||
} | ||
|
||
// Compute processes the provided asset snapshots and generates a stream of actionable recommendations. | ||
func (m *MoneyFlowIndexStrategy) Compute(snapshots <-chan *asset.Snapshot) <-chan strategy.Action { | ||
snapshotsSplice := helper.Duplicate(snapshots, 4) | ||
|
||
highs := asset.SnapshotsAsHighs(snapshotsSplice[0]) | ||
lows := asset.SnapshotsAsLows(snapshotsSplice[1]) | ||
closings := asset.SnapshotsAsClosings(snapshotsSplice[2]) | ||
volumes := asset.SnapshotsAsVolumes(snapshotsSplice[3]) | ||
|
||
mfis := m.MoneyFlowIndex.Compute(highs, lows, closings, volumes) | ||
|
||
actions := helper.Map(mfis, func(mfi float64) strategy.Action { | ||
if mfi >= m.SellAt { | ||
return strategy.Sell | ||
} | ||
|
||
if mfi <= m.BuyAt { | ||
return strategy.Buy | ||
} | ||
|
||
return strategy.Hold | ||
}) | ||
|
||
// Money Flow Index starts only after a full period. | ||
actions = helper.Shift(actions, m.MoneyFlowIndex.IdlePeriod(), strategy.Hold) | ||
|
||
return actions | ||
} | ||
|
||
// Report processes the provided asset snapshots and generates a report annotated with the recommended actions. | ||
func (m *MoneyFlowIndexStrategy) Report(c <-chan *asset.Snapshot) *helper.Report { | ||
// | ||
// snapshots[0] -> dates | ||
// snapshots[1] -> highs | | ||
// snapshots[2] -> lows | | ||
// snapshots[3] -> closings[0] -> closings | ||
// closings[1] -> superTrend | ||
// snapshots[4] -> volumes | ||
// snapshots[5] -> actions -> annotations | ||
// -> outcomes | ||
// | ||
snapshots := helper.Duplicate(c, 6) | ||
|
||
dates := helper.Skip( | ||
asset.SnapshotsAsDates(snapshots[0]), | ||
m.MoneyFlowIndex.IdlePeriod(), | ||
) | ||
|
||
highs := asset.SnapshotsAsHighs(snapshots[1]) | ||
lows := asset.SnapshotsAsLows(snapshots[2]) | ||
closingsSplice := helper.Duplicate( | ||
asset.SnapshotsAsClosings(snapshots[3]), | ||
2, | ||
) | ||
volumes := asset.SnapshotsAsVolumes(snapshots[4]) | ||
|
||
mfis := m.MoneyFlowIndex.Compute(highs, lows, closingsSplice[0], volumes) | ||
closingsSplice[1] = helper.Skip(closingsSplice[1], m.MoneyFlowIndex.IdlePeriod()) | ||
|
||
actions, outcomes := strategy.ComputeWithOutcome(m, snapshots[5]) | ||
actions = helper.Skip(actions, m.MoneyFlowIndex.IdlePeriod()) | ||
outcomes = helper.Skip(outcomes, m.MoneyFlowIndex.IdlePeriod()) | ||
|
||
annotations := strategy.ActionsToAnnotations(actions) | ||
outcomes = helper.MultiplyBy(outcomes, 100) | ||
|
||
report := helper.NewReport(m.Name(), dates) | ||
report.AddChart() | ||
report.AddChart() | ||
|
||
report.AddColumn(helper.NewNumericReportColumn("Close", closingsSplice[1])) | ||
report.AddColumn(helper.NewNumericReportColumn("Money Flow Index", mfis), 1) | ||
report.AddColumn(helper.NewAnnotationReportColumn(annotations), 0, 1) | ||
|
||
report.AddColumn(helper.NewNumericReportColumn("Outcome", outcomes), 2) | ||
|
||
return report | ||
} |
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,55 @@ | ||
// Copyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package volume_test | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/cinar/indicator/v2/asset" | ||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/strategy" | ||
"github.com/cinar/indicator/v2/strategy/volume" | ||
) | ||
|
||
func TestMoneyFlowIndexStrategy(t *testing.T) { | ||
snapshots, err := helper.ReadFromCsvFile[asset.Snapshot]("testdata/brk-b.csv", true) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
results, err := helper.ReadFromCsvFile[strategy.Result]("testdata/money_flow_index_strategy.csv", true) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
expected := helper.Map(results, func(r *strategy.Result) strategy.Action { return r.Action }) | ||
|
||
mfis := volume.NewMoneyFlowIndexStrategy() | ||
actual := mfis.Compute(snapshots) | ||
|
||
err = helper.CheckEquals(actual, expected) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
func TestMoneyFlowIndexStrategyReport(t *testing.T) { | ||
snapshots, err := helper.ReadFromCsvFile[asset.Snapshot]("testdata/brk-b.csv", true) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
mfis := volume.NewMoneyFlowIndexStrategy() | ||
report := mfis.Report(snapshots) | ||
|
||
fileName := "money_flow_index_strategy.html" | ||
defer os.Remove(fileName) | ||
|
||
err = report.WriteToFile(fileName) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
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 @@ | ||
../../../asset/testdata/repository/brk-b.csv |
Oops, something went wrong.