-
-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Double Exponential Moving Average (DEMA) added.
- Loading branch information
Showing
16 changed files
with
718 additions
and
32 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
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
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
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,128 @@ | ||
// Copyright (c) 2021-2023 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package strategy | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cinar/indicator/asset" | ||
"github.com/cinar/indicator/helper" | ||
"github.com/cinar/indicator/trend" | ||
) | ||
|
||
const ( | ||
// DefaultDemaStrategyPeriod1 is the first DEMA period. | ||
DefaultDemaStrategyPeriod1 = 5 | ||
|
||
// DefaultDemaStrategyPeriod2 is the second DEMA period. | ||
DefaultDemaStrategyPeriod2 = 35 | ||
) | ||
|
||
// DemaStrategy represents the configuration parameters for calculating the DEMA strategy. | ||
// A bullish cross occurs when DEMA with 5 days period moves above DEMA with 35 days period. | ||
// A bearish cross occurs when DEMA with 35 days period moves above DEMA With 5 days period. | ||
type DemaStrategy struct { | ||
Strategy | ||
|
||
// Dema1 represents the configuration parameters for | ||
// calculating the first DEMA. | ||
Dema1 *trend.Dema[float64] | ||
|
||
// Dema2 represents the configuration parameters for | ||
// calculating the second DEMA. | ||
Dema2 *trend.Dema[float64] | ||
} | ||
|
||
// NewDemaStrategy function initializes a new DEMA strategy instance | ||
// with the default parameters. | ||
func NewDemaStrategy() *DemaStrategy { | ||
dema1 := trend.NewDema[float64]() | ||
dema1.Ema1.Period = DefaultDemaStrategyPeriod1 | ||
dema1.Ema2.Period = DefaultDemaStrategyPeriod1 | ||
|
||
dema2 := trend.NewDema[float64]() | ||
dema2.Ema1.Period = DefaultDemaStrategyPeriod2 | ||
dema2.Ema2.Period = DefaultDemaStrategyPeriod2 | ||
|
||
return &DemaStrategy{ | ||
Dema1: dema1, | ||
Dema2: dema2, | ||
} | ||
} | ||
|
||
// Name returns the name of the strategy. | ||
func (*DemaStrategy) Name() string { | ||
return "DEMA Strategy" | ||
} | ||
|
||
// Compute processes the provided asset snapshots and generates a | ||
// stream of actionable recommendations. | ||
func (d *DemaStrategy) Compute(c <-chan *asset.Snapshot) <-chan Action { | ||
closings := helper.Duplicate(asset.SnapshotsAsClosings(c), 2) | ||
|
||
demas1 := d.Dema1.Compute(closings[0]) | ||
demas1 = helper.Shift(demas1, d.Dema1.IdlePeriod(), 0) | ||
|
||
demas2 := d.Dema2.Compute(closings[1]) | ||
demas2 = helper.Shift(demas2, d.Dema2.IdlePeriod(), 0) | ||
|
||
actions := NormalizeActions(helper.Operate(demas1, demas2, func(dema1, dema2 float64) Action { | ||
if dema1 > dema2 { | ||
return Buy | ||
} | ||
|
||
if dema2 > dema1 { | ||
return Sell | ||
} | ||
|
||
return Hold | ||
})) | ||
|
||
// DEMA starts only after the a full periods for each EMA used. | ||
actions = helper.Skip(actions, d.Dema2.IdlePeriod()) | ||
actions = helper.Shift(actions, d.Dema2.IdlePeriod(), Hold) | ||
|
||
return actions | ||
} | ||
|
||
// Report processes the provided asset snapshots and generates a | ||
// report annotated with the recommended actions. | ||
func (d *DemaStrategy) Report(c <-chan *asset.Snapshot) *helper.Report { | ||
// | ||
// snapshots[0] -> dates | ||
// snapshots[1] -> closings[0] -> demas1 | ||
// closings[1] -> demas2 | ||
// closings[2] -> closings | ||
// snapshots[2] -> actions -> annotations | ||
// -> outcomes | ||
// | ||
snapshots := helper.Duplicate(c, 3) | ||
|
||
dates := asset.SnapshotsAsDates(snapshots[0]) | ||
closings := helper.Duplicate(asset.SnapshotsAsClosings(snapshots[1]), 3) | ||
|
||
demas1 := d.Dema1.Compute(closings[0]) | ||
demas1 = helper.Shift(demas1, d.Dema1.IdlePeriod(), 0) | ||
|
||
demas2 := d.Dema2.Compute(closings[1]) | ||
demas2 = helper.Shift(demas2, d.Dema2.IdlePeriod(), 0) | ||
|
||
actions, outcomes := ComputeWithOutcome(d, snapshots[2]) | ||
annotations := ActionsToAnnotations(actions) | ||
outcomes = helper.MultiplyBy(outcomes, 100) | ||
|
||
report := helper.NewReport(d.Name(), dates) | ||
report.AddChart() | ||
report.AddChart() | ||
|
||
report.AddColumn(helper.NewNumericReportColumn("Close", closings[2])) | ||
report.AddColumn(helper.NewNumericReportColumn(fmt.Sprintf("Dema %d-day", d.Dema1.Ema1.Period), demas1), 1) | ||
report.AddColumn(helper.NewNumericReportColumn(fmt.Sprintf("Dema %d-day", d.Dema2.Ema1.Period), demas2), 1) | ||
report.AddColumn(helper.NewAnnotationReportColumn(annotations), 0, 1) | ||
|
||
report.AddColumn(helper.NewNumericReportColumn("Outcome", outcomes), 2) | ||
|
||
return report | ||
} |
Oops, something went wrong.