mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
optimizer: support multi metric value functions
Signed-off-by: c9s <yoanlin93@gmail.com>
This commit is contained in:
parent
6669db4264
commit
9be38e2421
|
@ -5,10 +5,10 @@
|
||||||
---
|
---
|
||||||
matrix:
|
matrix:
|
||||||
|
|
||||||
#- type: iterate
|
- type: iterate
|
||||||
# label: interval
|
label: interval
|
||||||
# path: '/exchangeStrategies/0/pivotshort/interval'
|
path: '/exchangeStrategies/0/pivotshort/interval'
|
||||||
# values: [ "5m", "30m" ]
|
values: [ "1m", "5m", "30m" ]
|
||||||
|
|
||||||
#- type: range
|
#- type: range
|
||||||
# path: '/exchangeStrategies/0/pivotshort/pivotLength'
|
# path: '/exchangeStrategies/0/pivotshort/pivotLength'
|
||||||
|
@ -17,31 +17,31 @@ matrix:
|
||||||
# max: 200.0
|
# max: 200.0
|
||||||
# step: 20.0
|
# step: 20.0
|
||||||
|
|
||||||
- type: range
|
# - type: range
|
||||||
path: '/exchangeStrategies/0/pivotshort/breakLow/stopEMARange'
|
# path: '/exchangeStrategies/0/pivotshort/breakLow/stopEMARange'
|
||||||
label: stopEMARange
|
# label: stopEMARange
|
||||||
min: 0%
|
# min: 0%
|
||||||
max: 10%
|
# max: 10%
|
||||||
step: 1%
|
# step: 1%
|
||||||
|
|
||||||
- type: range
|
|
||||||
path: '/exchangeStrategies/0/pivotshort/exit/roiStopLossPercentage'
|
|
||||||
label: roiStopLossPercentage
|
|
||||||
min: 0.5%
|
|
||||||
max: 2%
|
|
||||||
step: 0.5%
|
|
||||||
|
|
||||||
- type: range
|
|
||||||
path: '/exchangeStrategies/0/pivotshort/exit/roiTakeProfitPercentage'
|
|
||||||
label: roiTakeProfitPercentage
|
|
||||||
min: 10%
|
|
||||||
max: 50%
|
|
||||||
step: 5%
|
|
||||||
|
|
||||||
- type: range
|
|
||||||
path: '/exchangeStrategies/0/pivotshort/exit/roiMinTakeProfitPercentage'
|
|
||||||
label: roiMinTakeProfitPercentage
|
|
||||||
min: 3%
|
|
||||||
max: 10%
|
|
||||||
step: 1%
|
|
||||||
|
|
||||||
|
# - type: range
|
||||||
|
# path: '/exchangeStrategies/0/pivotshort/exit/roiStopLossPercentage'
|
||||||
|
# label: roiStopLossPercentage
|
||||||
|
# min: 0.5%
|
||||||
|
# max: 2%
|
||||||
|
# step: 0.5%
|
||||||
|
#
|
||||||
|
# - type: range
|
||||||
|
# path: '/exchangeStrategies/0/pivotshort/exit/roiTakeProfitPercentage'
|
||||||
|
# label: roiTakeProfitPercentage
|
||||||
|
# min: 10%
|
||||||
|
# max: 50%
|
||||||
|
# step: 5%
|
||||||
|
#
|
||||||
|
# - type: range
|
||||||
|
# path: '/exchangeStrategies/0/pivotshort/exit/roiMinTakeProfitPercentage'
|
||||||
|
# label: roiMinTakeProfitPercentage
|
||||||
|
# min: 3%
|
||||||
|
# max: 10%
|
||||||
|
# step: 1%
|
||||||
|
#
|
||||||
|
|
|
@ -104,12 +104,15 @@ var optimizeCmd = &cobra.Command{
|
||||||
// print metrics JSON to stdout
|
// print metrics JSON to stdout
|
||||||
fmt.Println(string(out))
|
fmt.Println(string(out))
|
||||||
} else {
|
} else {
|
||||||
if len(metrics) > 0 {
|
for n, values := range metrics {
|
||||||
fmt.Printf("%v\n", metrics[0].Labels)
|
if len(values) == 0 {
|
||||||
}
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for _, m := range metrics {
|
fmt.Printf("%v => %s\n", values[0].Labels, n)
|
||||||
fmt.Printf("%v => %v\n", m.Params, m.Value)
|
for _, m := range values {
|
||||||
|
fmt.Printf("%v => %s %v\n", m.Params, n, m.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,18 @@ type Metric struct {
|
||||||
Value fixedpoint.Value `json:"value,omitempty"`
|
Value fixedpoint.Value `json:"value,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func copyParams(params []interface{}) []interface{} {
|
||||||
|
var c = make([]interface{}, len(params))
|
||||||
|
copy(c, params)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyLabels(labels []string) []string {
|
||||||
|
var c = make([]string, len(labels))
|
||||||
|
copy(c, labels)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
type GridOptimizer struct {
|
type GridOptimizer struct {
|
||||||
Config *Config
|
Config *Config
|
||||||
|
|
||||||
|
@ -149,10 +161,13 @@ func (o *GridOptimizer) buildOps() []OpFunc {
|
||||||
return ops
|
return ops
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *GridOptimizer) Run(executor Executor, configJson []byte) ([]Metric, error) {
|
func (o *GridOptimizer) Run(executor Executor, configJson []byte) (map[string][]Metric, error) {
|
||||||
o.CurrentParams = make([]interface{}, len(o.Config.Matrix))
|
o.CurrentParams = make([]interface{}, len(o.Config.Matrix))
|
||||||
|
|
||||||
var metrics []Metric
|
var valueFunctions = map[string]MetricValueFunc{
|
||||||
|
"totalProfit": TotalProfitMetricValueFunc,
|
||||||
|
}
|
||||||
|
var metrics = map[string][]Metric{}
|
||||||
|
|
||||||
var ops = o.buildOps()
|
var ops = o.buildOps()
|
||||||
var app = func(configJson []byte, next func(configJson []byte) error) error {
|
var app = func(configJson []byte, next func(configJson []byte) error) error {
|
||||||
|
@ -161,19 +176,20 @@ func (o *GridOptimizer) Run(executor Executor, configJson []byte) ([]Metric, err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add more metric value function
|
for metricName, metricFunc := range valueFunctions {
|
||||||
metricValue := TotalProfitMetricValueFunc(summaryReport)
|
var metricValue = metricFunc(summaryReport)
|
||||||
|
var currentParams = copyParams(o.CurrentParams)
|
||||||
|
var labels = copyLabels(o.ParamLabels)
|
||||||
|
|
||||||
var currentParams = make([]interface{}, len(o.CurrentParams))
|
metrics[metricName] = append(metrics[metricName], Metric{
|
||||||
copy(currentParams, o.CurrentParams)
|
Params: currentParams,
|
||||||
|
Labels: labels,
|
||||||
|
Value: metricValue,
|
||||||
|
})
|
||||||
|
|
||||||
metrics = append(metrics, Metric{
|
log.Infof("params: %+v => %s %+v", currentParams, metricName, metricValue)
|
||||||
Params: currentParams,
|
}
|
||||||
Labels: o.ParamLabels,
|
|
||||||
Value: metricValue,
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Infof("current params: %+v => %+v", currentParams, metricValue)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,11 +209,14 @@ func (o *GridOptimizer) Run(executor Executor, configJson []byte) ([]Metric, err
|
||||||
|
|
||||||
err := wrapper(configJson)
|
err := wrapper(configJson)
|
||||||
|
|
||||||
sort.Slice(metrics, func(i, j int) bool {
|
for n := range metrics {
|
||||||
a := metrics[i].Value
|
sort.Slice(metrics[n], func(i, j int) bool {
|
||||||
b := metrics[j].Value
|
a := metrics[n][i].Value
|
||||||
return a.Compare(b) > 0
|
b := metrics[n][j].Value
|
||||||
})
|
return a.Compare(b) > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return metrics, err
|
return metrics, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,8 @@ func (e *LocalProcessExecutor) Execute(configJson []byte) (*backtest.SummaryRepo
|
||||||
return e.readReport(output)
|
return e.readReport(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jsonToYamlConfig translate json format config into a YAML format config file
|
||||||
|
// The generated file is a temp file
|
||||||
func jsonToYamlConfig(dir string, configJson []byte) (*os.File, error) {
|
func jsonToYamlConfig(dir string, configJson []byte) (*os.File, error) {
|
||||||
var o map[string]interface{}
|
var o map[string]interface{}
|
||||||
if err := json.Unmarshal(configJson, &o); err != nil {
|
if err := json.Unmarshal(configJson, &o); err != nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user