diff --git a/pkg/bbgo/injection.go b/pkg/bbgo/injection.go index 03ff9fd7f..cf9c47d42 100644 --- a/pkg/bbgo/injection.go +++ b/pkg/bbgo/injection.go @@ -84,6 +84,8 @@ func parseStructAndInject(f interface{}, objects ...interface{}) error { continue } + fieldName := st.Field(i).Name + switch k := fv.Kind(); k { case reflect.Ptr, reflect.Struct: @@ -99,12 +101,18 @@ func parseStructAndInject(f interface{}, objects ...interface{}) error { return fmt.Errorf("field %v of %s can not be set to %s, make sure it is an exported field", fv, sv.Type(), ot) } - if k == reflect.Ptr && ot.Kind() == reflect.Struct { - fv.Set(reflect.ValueOf(obj).Addr()) - } else { - fv.Set(reflect.ValueOf(obj)) + if k == reflect.Ptr && !fv.IsNil() { + logrus.Debugf("[injection] field %s is not nil, not injecting", fieldName) + continue } + if k == reflect.Ptr && ot.Kind() == reflect.Struct { + logrus.Debugf("[injection] found ptr + struct, injecting field %s to %T", fieldName, obj) + fv.Set(reflect.ValueOf(obj).Addr()) + } else { + logrus.Debugf("[injection] injecting field %s to %T", fieldName, obj) + fv.Set(reflect.ValueOf(obj)) + } } } diff --git a/pkg/bbgo/persistence.go b/pkg/bbgo/persistence.go index 665813b35..7dde77f61 100644 --- a/pkg/bbgo/persistence.go +++ b/pkg/bbgo/persistence.go @@ -3,8 +3,9 @@ package bbgo import ( "fmt" - "github.com/c9s/bbgo/pkg/service" log "github.com/sirupsen/logrus" + + "github.com/c9s/bbgo/pkg/service" ) type PersistenceSelector struct { @@ -48,6 +49,8 @@ func (p *Persistence) Load(val interface{}, subIDs ...string) error { return err } + log.Debugf("using persistence store %T for loading", ps) + if p.PersistenceSelector.StoreID == "" { p.PersistenceSelector.StoreID = "default" } @@ -62,6 +65,8 @@ func (p *Persistence) Save(val interface{}, subIDs ...string) error { return err } + log.Debugf("using persistence store %T for storing", ps) + if p.PersistenceSelector.StoreID == "" { p.PersistenceSelector.StoreID = "default" } diff --git a/pkg/bbgo/trader.go b/pkg/bbgo/trader.go index f5d1736de..c6eefb2c1 100644 --- a/pkg/bbgo/trader.go +++ b/pkg/bbgo/trader.go @@ -219,7 +219,7 @@ func (trader *Trader) RunSingleExchangeStrategy(ctx context.Context, strategy Si return errors.New("strategy object is not a struct") } - if err := trader.injectCommonServices(strategy) ; err != nil { + if err := trader.injectCommonServices(strategy); err != nil { return err } @@ -337,7 +337,7 @@ func (trader *Trader) Run(ctx context.Context) error { continue } - if err := trader.injectCommonServices(strategy) ; err != nil { + if err := trader.injectCommonServices(strategy); err != nil { return err } @@ -361,6 +361,29 @@ func (trader *Trader) injectCommonServices(s interface{}) error { Facade: persistenceFacade, } + // a special injection for persistence selector: + // if user defined the selector, the facade pointer will be nil, hence we need to update the persistence facade pointer + sv := reflect.ValueOf(s).Elem() + if field, ok := hasField(sv, "Persistence"); ok { + // the selector is set, but we need to update the facade pointer + if !field.IsNil() { + elem := field.Elem() + if elem.Kind() != reflect.Struct { + return fmt.Errorf("field Persistence is not a struct element, %s given", field) + } + + if err := injectField(elem, "Facade", persistenceFacade, true); err != nil { + return err + } + + /* + if err := parseStructAndInject(field.Interface(), persistenceFacade); err != nil { + return err + } + */ + } + } + return parseStructAndInject(s, &trader.Graceful, &trader.logger, @@ -371,11 +394,10 @@ func (trader *Trader) injectCommonServices(s interface{}) error { trader.environment.AccountService, trader.environment, persistence, - persistenceFacade, + persistenceFacade, // if the strategy use persistence facade separately ) } - // ReportPnL configure and set the PnLReporter with the given notifier func (trader *Trader) ReportPnL() *PnLReporterManager { return NewPnLReporter(&trader.environment.Notifiability) diff --git a/pkg/strategy/bollmaker/strategy.go b/pkg/strategy/bollmaker/strategy.go index 22d0ba941..e1b50ef80 100644 --- a/pkg/strategy/bollmaker/strategy.go +++ b/pkg/strategy/bollmaker/strategy.go @@ -242,9 +242,9 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu func (s *Strategy) SaveState() error { if err := s.Persistence.Save(s.state, ID, s.Symbol, stateKey); err != nil { return err - } else { - log.Infof("state is saved => %+v", s.state) } + + log.Infof("state is saved => %+v", s.state) return nil }