optimizer: add metrics label

This commit is contained in:
c9s 2022-05-20 01:53:51 +08:00
parent 95c9fe4502
commit b61af0db39
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 29 additions and 4 deletions

View File

@ -104,6 +104,10 @@ 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 {
fmt.Printf("%v\n", metrics[0].Labels)
}
for _, m := range metrics { for _, m := range metrics {
fmt.Printf("%v => %v\n", m.Params, m.Value) fmt.Printf("%v => %v\n", m.Params, m.Value)
} }

View File

@ -1,6 +1,7 @@
package optimizer package optimizer
import ( import (
"encoding/json"
"fmt" "fmt"
"sort" "sort"
@ -17,6 +18,7 @@ var TotalProfitMetricValueFunc = func(summaryReport *backtest.SummaryReport) fix
} }
type Metric struct { type Metric struct {
Labels []string `json:"labels,omitempty"`
Params []interface{} `json:"params,omitempty"` Params []interface{} `json:"params,omitempty"`
Value fixedpoint.Value `json:"value,omitempty"` Value fixedpoint.Value `json:"value,omitempty"`
} }
@ -24,6 +26,7 @@ type Metric struct {
type GridOptimizer struct { type GridOptimizer struct {
Config *Config Config *Config
ParamLabels []string
CurrentParams []interface{} CurrentParams []interface{}
} }
@ -31,11 +34,18 @@ func (o *GridOptimizer) buildOps() []OpFunc {
var ops []OpFunc var ops []OpFunc
o.CurrentParams = make([]interface{}, len(o.Config.Matrix)) o.CurrentParams = make([]interface{}, len(o.Config.Matrix))
o.ParamLabels = make([]string, len(o.Config.Matrix))
for i, selector := range o.Config.Matrix { for i, selector := range o.Config.Matrix {
var path = selector.Path var path = selector.Path
var ii = i // copy variable because we need to use them in the closure var ii = i // copy variable because we need to use them in the closure
if selector.Label != "" {
o.ParamLabels[ii] = selector.Label
} else {
o.ParamLabels[ii] = selector.Path
}
switch selector.Type { switch selector.Type {
case "range": case "range":
min := selector.Min min := selector.Min
@ -52,7 +62,7 @@ func (o *GridOptimizer) buildOps() []OpFunc {
f := func(configJson []byte, next func(configJson []byte) error) error { f := func(configJson []byte, next func(configJson []byte) error) error {
for _, val := range values { for _, val := range values {
jsonOp := []byte(fmt.Sprintf(`[ {"op": "replace", "path": "%s", "value": %v } ]`, path, val)) jsonOp := []byte(reformatJson(fmt.Sprintf(`[{"op": "replace", "path": "%s", "value": %v }]`, path, val)))
patch, err := jsonpatch.DecodePatch(jsonOp) patch, err := jsonpatch.DecodePatch(jsonOp)
if err != nil { if err != nil {
return err return err
@ -82,7 +92,7 @@ func (o *GridOptimizer) buildOps() []OpFunc {
for _, val := range values { for _, val := range values {
log.Debugf("%d %s: %v of %v", ii, path, val, values) log.Debugf("%d %s: %v of %v", ii, path, val, values)
jsonOp := []byte(fmt.Sprintf(`[{"op": "replace", "path": "%s", "value": "%s"}]`, path, val)) jsonOp := []byte(reformatJson(fmt.Sprintf(`[{"op": "replace", "path": "%s", "value": "%s"}]`, path, val)))
patch, err := jsonpatch.DecodePatch(jsonOp) patch, err := jsonpatch.DecodePatch(jsonOp)
if err != nil { if err != nil {
return err return err
@ -122,12 +132,12 @@ func (o *GridOptimizer) Run(executor Executor, configJson []byte) ([]Metric, err
return err return err
} }
// TODO: Add other metric value function // TODO: Add more metric value function
metricValue := TotalProfitMetricValueFunc(summaryReport) metricValue := TotalProfitMetricValueFunc(summaryReport)
// TODO: replace this with a local variable and return it as a function result
metrics = append(metrics, Metric{ metrics = append(metrics, Metric{
Params: o.CurrentParams, Params: o.CurrentParams,
Labels: o.ParamLabels,
Value: metricValue, Value: metricValue,
}) })
@ -158,3 +168,14 @@ func (o *GridOptimizer) Run(executor Executor, configJson []byte) ([]Metric, err
}) })
return metrics, err return metrics, err
} }
func reformatJson(text string) string {
var a interface{}
var err = json.Unmarshal([]byte(text), &a)
if err != nil {
return "{invalid json}"
}
out, _ := json.MarshalIndent(a, "", " ")
return string(out)
}