-
-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Describe Request Data report is added to enable the backtest results to be programmatically accessed. Fixed #217 # Change Type New feature.
- Loading branch information
Showing
4 changed files
with
303 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,86 @@ | ||
// Copyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package backtest | ||
|
||
import ( | ||
"github.com/cinar/indicator/v2/asset" | ||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/strategy" | ||
) | ||
|
||
// DataStrategyResult is the strategy result. | ||
type DataStrategyResult struct { | ||
// Asset is the asset name. | ||
Asset string | ||
|
||
// Strategy is the strategy instnace. | ||
Strategy strategy.Strategy | ||
|
||
// Outcome is the strategy outcome. | ||
Outcome float64 | ||
|
||
// Action is the final action recommended by the strategy. | ||
Action strategy.Action | ||
|
||
// Transactions are the action recommendations. | ||
Transactions []strategy.Action | ||
} | ||
|
||
// DataReport is the bactest data report enablign programmatic access to the backtest results. | ||
type DataReport struct { | ||
// Results are the backtest results for the assets. | ||
Results map[string][]*DataStrategyResult | ||
} | ||
|
||
// NewDataReport initializes a new data report instance. | ||
func NewDataReport() *DataReport { | ||
return &DataReport{ | ||
Results: make(map[string][]*DataStrategyResult), | ||
} | ||
} | ||
|
||
// Begin is called when the backtest begins. | ||
func (*DataReport) Begin(_ []string, _ []strategy.Strategy) error { | ||
return nil | ||
} | ||
|
||
// AssetBegin is called when backtesting for the given asset begins. | ||
func (d *DataReport) AssetBegin(name string, strategies []strategy.Strategy) error { | ||
d.Results[name] = make([]*DataStrategyResult, 0, len(strategies)) | ||
return nil | ||
} | ||
|
||
// Write writes the given strategy actions and outomes to the report. | ||
func (d *DataReport) Write(assetName string, currentStrategy strategy.Strategy, snapshots <-chan *asset.Snapshot, actions <-chan strategy.Action, outcomes <-chan float64) error { | ||
go helper.Drain(snapshots) | ||
|
||
actionsSplice := helper.Duplicate(actions, 2) | ||
|
||
lastOutcome := helper.Last(outcomes, 1) | ||
lastAction := helper.Last(actionsSplice[0], 1) | ||
transactions := helper.ChanToSlice(actionsSplice[1]) | ||
|
||
result := &DataStrategyResult{ | ||
Asset: assetName, | ||
Strategy: currentStrategy, | ||
Outcome: <-lastOutcome, | ||
Action: <-lastAction, | ||
Transactions: transactions, | ||
} | ||
|
||
d.Results[assetName] = append(d.Results[assetName], result) | ||
|
||
return nil | ||
} | ||
|
||
// AssetEnd is called when backtesting for the given asset ends. | ||
func (*DataReport) AssetEnd(_ string) error { | ||
return nil | ||
} | ||
|
||
// End is called when the backtest ends. | ||
func (*DataReport) End() error { | ||
return nil | ||
} |
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,78 @@ | ||
// Copyright (c) 2021-2024 Onur Cinar. | ||
// The source code is provided under GNU AGPLv3 License. | ||
// https://github.com/cinar/indicator | ||
|
||
package backtest_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/cinar/indicator/v2/asset" | ||
"github.com/cinar/indicator/v2/backtest" | ||
"github.com/cinar/indicator/v2/helper" | ||
"github.com/cinar/indicator/v2/strategy" | ||
) | ||
|
||
func TestDataReport(t *testing.T) { | ||
repository := asset.NewFileSystemRepository("testdata/repository") | ||
|
||
assets := []string{ | ||
"brk-b", | ||
} | ||
|
||
strategies := []strategy.Strategy{ | ||
strategy.NewBuyAndHoldStrategy(), | ||
} | ||
|
||
report := backtest.NewDataReport() | ||
|
||
err := report.Begin(assets, strategies) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = report.AssetBegin(assets[0], strategies) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
snapshots, err := repository.Get(assets[0]) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
snapshotsSplice := helper.Duplicate(snapshots, 3) | ||
actionsSplice := helper.Duplicate( | ||
strategies[0].Compute(snapshotsSplice[1]), | ||
2, | ||
) | ||
|
||
outcomes := strategy.Outcome( | ||
asset.SnapshotsAsClosings(snapshotsSplice[2]), | ||
actionsSplice[1], | ||
) | ||
|
||
err = report.Write(assets[0], strategies[0], snapshotsSplice[0], actionsSplice[0], outcomes) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = report.AssetEnd(assets[0]) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = report.End() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
results, ok := report.Results[assets[0]] | ||
if !ok { | ||
t.Fatal("asset result not found") | ||
} | ||
|
||
if len(results) != len(strategies) { | ||
t.Fatalf("results count and strategies count are not the same, %d %d", len(results), len(strategies)) | ||
} | ||
} |
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 @@ | ||
package backtest |