mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
fix: move some modify implementation to dynamic
This commit is contained in:
parent
d40b34e4d6
commit
aaa657dcc3
|
@ -325,8 +325,6 @@ type Config struct {
|
|||
CrossExchangeStrategies []CrossExchangeStrategy `json:"-" yaml:"-"`
|
||||
|
||||
PnLReporters []PnLReporterConfig `json:"reportPnL,omitempty" yaml:"reportPnL,omitempty"`
|
||||
|
||||
ConfigFile string
|
||||
}
|
||||
|
||||
func (c *Config) Map() (map[string]interface{}, error) {
|
||||
|
@ -480,10 +478,6 @@ func Load(configFile string, loadStrategies bool) (*Config, error) {
|
|||
if err := yaml.Unmarshal(content, &config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.ConfigFile = configFile
|
||||
for _, session := range config.Sessions {
|
||||
session.ConfigPath = config.ConfigFile
|
||||
}
|
||||
|
||||
// for backward compatible
|
||||
if config.Build == nil {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/dynamic"
|
||||
"github.com/c9s/bbgo/pkg/interact"
|
||||
"github.com/c9s/bbgo/pkg/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -23,37 +23,33 @@ func RegisterModifier(s interface{}) {
|
|||
RegisterCommand("/modify", "Modify config", func(reply interact.Reply) {
|
||||
reply.Message("Please choose the field name in config to modify:")
|
||||
mapping = make(map[string]string)
|
||||
for i := 0; i < val.Type().NumField(); i++ {
|
||||
t := val.Type().Field(i)
|
||||
if !t.IsExported() {
|
||||
continue
|
||||
}
|
||||
modifiable := t.Tag.Get("modifiable")
|
||||
if modifiable != "true" {
|
||||
continue
|
||||
}
|
||||
jsonTag := t.Tag.Get("json")
|
||||
if jsonTag == "" || jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
name := strings.Split(jsonTag, ",")[0]
|
||||
mapping[name] = t.Name
|
||||
reply.AddButton(name, name, name)
|
||||
}
|
||||
}).Next(func(target string, reply interact.Reply) {
|
||||
dynamic.GetModifiableFields(val, func(tagName, name string) {
|
||||
mapping[tagName] = name
|
||||
reply.AddButton(tagName, tagName, tagName)
|
||||
})
|
||||
}).Next(func(target string, reply interact.Reply) error {
|
||||
targetName = mapping[target]
|
||||
field := val.FieldByName(targetName)
|
||||
field, ok := dynamic.GetModifiableField(val, targetName)
|
||||
if !ok {
|
||||
reply.Message(fmt.Sprintf("target %s is not modifiable", targetName))
|
||||
return fmt.Errorf("target %s is not modifiable", targetName)
|
||||
}
|
||||
currVal = field.Interface()
|
||||
if e, err := json.Marshal(currVal); err == nil {
|
||||
currVal = string(e)
|
||||
}
|
||||
reply.Message(fmt.Sprintf("Please enter the new value, current value: %v", currVal))
|
||||
return nil
|
||||
}).Next(func(value string, reply interact.Reply) {
|
||||
log.Infof("%s", value)
|
||||
log.Infof("try to modify from %s to %s", currVal, value)
|
||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||
kc.RemoveKeyboard()
|
||||
}
|
||||
field := val.FieldByName(targetName)
|
||||
field, ok := dynamic.GetModifiableField(val, targetName)
|
||||
if !ok {
|
||||
reply.Message(fmt.Sprintf("target %s is not modifiable", targetName))
|
||||
return
|
||||
}
|
||||
x := reflect.New(field.Type())
|
||||
xi := x.Interface()
|
||||
if err := json.Unmarshal([]byte(value), &xi); err != nil {
|
|
@ -40,7 +40,6 @@ type ExchangeSession struct {
|
|||
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
|
||||
Passphrase string `json:"passphrase,omitempty" yaml:"passphrase,omitempty"`
|
||||
SubAccount string `json:"subAccount,omitempty" yaml:"subAccount,omitempty"`
|
||||
ConfigPath string
|
||||
|
||||
// Withdrawal is used for enabling withdrawal functions
|
||||
Withdrawal bool `json:"withdrawal,omitempty" yaml:"withdrawal,omitempty"`
|
||||
|
|
|
@ -267,7 +267,6 @@ var BacktestCmd = &cobra.Command{
|
|||
exchangeFromConfig := userConfig.Sessions[name.String()]
|
||||
if exchangeFromConfig != nil {
|
||||
session.UseHeikinAshi = exchangeFromConfig.UseHeikinAshi
|
||||
session.ConfigPath = exchangeFromConfig.ConfigPath
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package dynamic
|
||||
|
||||
import "reflect"
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func HasField(rs reflect.Value, fieldName string) (field reflect.Value, ok bool) {
|
||||
field = rs.FieldByName(fieldName)
|
||||
|
@ -24,3 +27,39 @@ func LookupSymbolField(rs reflect.Value) (string, bool) {
|
|||
return field.String(), true
|
||||
}
|
||||
|
||||
// Used by bbgo/interact_modify.go
|
||||
func GetModifiableFields(val reflect.Value, callback func(tagName, name string)) {
|
||||
for i := 0; i < val.Type().NumField(); i++ {
|
||||
t := val.Type().Field(i)
|
||||
if !t.IsExported() {
|
||||
continue
|
||||
}
|
||||
modifiable := t.Tag.Get("modifiable")
|
||||
if modifiable != "true" {
|
||||
continue
|
||||
}
|
||||
jsonTag := t.Tag.Get("json")
|
||||
if jsonTag == "" || jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
name := strings.Split(jsonTag, ",")[0]
|
||||
callback(name, t.Name)
|
||||
}
|
||||
}
|
||||
|
||||
var ZeroValue reflect.Value = reflect.Zero(reflect.TypeOf(0))
|
||||
|
||||
func GetModifiableField(val reflect.Value, name string) (reflect.Value, bool) {
|
||||
field, ok := val.Type().FieldByName(name)
|
||||
if !ok {
|
||||
return ZeroValue, ok
|
||||
}
|
||||
if field.Tag.Get("modifiable") != "true" {
|
||||
return ZeroValue, false
|
||||
}
|
||||
jsonTag := field.Tag.Get("json")
|
||||
if jsonTag == "" || jsonTag == "-" {
|
||||
return ZeroValue, false
|
||||
}
|
||||
return val.FieldByName(name), true
|
||||
}
|
||||
|
|
37
pkg/dynamic/field_test.go
Normal file
37
pkg/dynamic/field_test.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package dynamic
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type Strategy struct {
|
||||
Field1 fixedpoint.Value `json:"field1" modifiable:"true"`
|
||||
Field2 float64 `json:"field2"`
|
||||
field3 float64 `json:"field3" modifiable:"true"`
|
||||
}
|
||||
|
||||
func TestGetModifiableFields(t *testing.T) {
|
||||
s := Strategy{}
|
||||
val := reflect.ValueOf(s)
|
||||
GetModifiableFields(val, func(tagName, name string) {
|
||||
assert.Equal(t, tagName, "field1")
|
||||
assert.Equal(t, name, "Field1")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetModifiableField(t *testing.T) {
|
||||
s := Strategy{}
|
||||
val := reflect.ValueOf(s)
|
||||
_, ok := GetModifiableField(val, "Field1")
|
||||
assert.True(t, ok)
|
||||
_, ok = GetModifiableField(val, "Field2")
|
||||
assert.False(t, ok)
|
||||
_, ok = GetModifiableField(val, "Field3")
|
||||
assert.False(t, ok)
|
||||
_, ok = GetModifiableField(val, "Random")
|
||||
assert.False(t, ok)
|
||||
}
|
Loading…
Reference in New Issue
Block a user