mirror of
https://github.com/c9s/bbgo.git
synced 2024-09-20 08:11:08 +00:00
Merge pull request #750 from c9s/refactor/persistence-singleton
refactor: persistence singleton and improve backtest cancel performance
This commit is contained in:
commit
612df45c5e
|
@ -69,9 +69,14 @@ func (b *ActiveOrderBook) waitAllClear(ctx context.Context, waitTime, timeout ti
|
|||
|
||||
// GracefulCancel cancels the active orders gracefully
|
||||
func (b *ActiveOrderBook) GracefulCancel(ctx context.Context, ex types.Exchange) error {
|
||||
waitTime := CancelOrderWaitTime
|
||||
// optimize order cancel for back-testing
|
||||
if IsBackTesting {
|
||||
orders := b.Orders()
|
||||
return ex.CancelOrders(context.Background(), orders...)
|
||||
}
|
||||
|
||||
log.Debugf("[ActiveOrderBook] gracefully cancelling %s orders...", b.Symbol)
|
||||
waitTime := CancelOrderWaitTime
|
||||
|
||||
startTime := time.Now()
|
||||
// ensure every order is cancelled
|
||||
|
|
|
@ -37,6 +37,16 @@ func init() {
|
|||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// IsBackTesting is a global variable that indicates the current environment is back-test or not.
|
||||
var IsBackTesting = false
|
||||
|
||||
var BackTestService *service.BacktestService
|
||||
|
||||
func SetBackTesting(s *service.BacktestService) {
|
||||
BackTestService = s
|
||||
IsBackTesting = true
|
||||
}
|
||||
|
||||
var LoadedExchangeStrategies = make(map[string]SingleExchangeStrategy)
|
||||
var LoadedCrossExchangeStrategies = make(map[string]CrossExchangeStrategy)
|
||||
|
||||
|
@ -69,19 +79,18 @@ const (
|
|||
|
||||
// Environment presents the real exchange data layer
|
||||
type Environment struct {
|
||||
PersistenceServiceFacade *service.PersistenceServiceFacade
|
||||
DatabaseService *service.DatabaseService
|
||||
OrderService *service.OrderService
|
||||
TradeService *service.TradeService
|
||||
ProfitService *service.ProfitService
|
||||
PositionService *service.PositionService
|
||||
BacktestService *service.BacktestService
|
||||
RewardService *service.RewardService
|
||||
MarginService *service.MarginService
|
||||
SyncService *service.SyncService
|
||||
AccountService *service.AccountService
|
||||
WithdrawService *service.WithdrawService
|
||||
DepositService *service.DepositService
|
||||
DatabaseService *service.DatabaseService
|
||||
OrderService *service.OrderService
|
||||
TradeService *service.TradeService
|
||||
ProfitService *service.ProfitService
|
||||
PositionService *service.PositionService
|
||||
BacktestService *service.BacktestService
|
||||
RewardService *service.RewardService
|
||||
MarginService *service.MarginService
|
||||
SyncService *service.SyncService
|
||||
AccountService *service.AccountService
|
||||
WithdrawService *service.WithdrawService
|
||||
DepositService *service.DepositService
|
||||
|
||||
// startTime is the time of start point (which is used in the backtest)
|
||||
startTime time.Time
|
||||
|
@ -107,9 +116,6 @@ func NewEnvironment() *Environment {
|
|||
startTime: now,
|
||||
|
||||
syncStatus: SyncNotStarted,
|
||||
PersistenceServiceFacade: &service.PersistenceServiceFacade{
|
||||
Memory: service.NewMemoryService(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,7 +282,8 @@ func (environ *Environment) ConfigurePersistence(conf *PersistenceConfig) error
|
|||
return err
|
||||
}
|
||||
|
||||
environ.PersistenceServiceFacade.Redis = service.NewRedisPersistenceService(conf.Redis)
|
||||
redisPersistence := service.NewRedisPersistenceService(conf.Redis)
|
||||
PersistenceServiceFacade.Redis = redisPersistence
|
||||
}
|
||||
|
||||
if conf.Json != nil {
|
||||
|
@ -287,7 +294,8 @@ func (environ *Environment) ConfigurePersistence(conf *PersistenceConfig) error
|
|||
}
|
||||
}
|
||||
|
||||
environ.PersistenceServiceFacade.Json = &service.JsonPersistenceService{Directory: conf.Json.Directory}
|
||||
jsonPersistence := &service.JsonPersistenceService{Directory: conf.Json.Directory}
|
||||
PersistenceServiceFacade.Json = jsonPersistence
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -772,7 +780,7 @@ func (environ *Environment) ConfigureNotificationSystem(userConfig *Config) erro
|
|||
}
|
||||
}
|
||||
|
||||
var persistence = environ.PersistenceServiceFacade.Get()
|
||||
var persistence = PersistenceServiceFacade.Get()
|
||||
|
||||
err := environ.setupInteraction(persistence)
|
||||
if err != nil {
|
||||
|
|
|
@ -17,6 +17,12 @@ type PersistenceSelector struct {
|
|||
Type string `json:"type" yaml:"type"`
|
||||
}
|
||||
|
||||
var DefaultPersistenceServiceFacade = &service.PersistenceServiceFacade{
|
||||
Memory: service.NewMemoryService(),
|
||||
}
|
||||
|
||||
var PersistenceServiceFacade = DefaultPersistenceServiceFacade
|
||||
|
||||
// Persistence is used for strategy to inject the persistence.
|
||||
type Persistence struct {
|
||||
PersistenceSelector *PersistenceSelector `json:"persistence,omitempty" yaml:"persistence,omitempty"`
|
||||
|
|
|
@ -327,11 +327,11 @@ func (trader *Trader) LoadState() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if trader.environment.PersistenceServiceFacade == nil {
|
||||
if PersistenceServiceFacade == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ps := trader.environment.PersistenceServiceFacade.Get()
|
||||
ps := PersistenceServiceFacade.Get()
|
||||
|
||||
log.Infof("loading strategies states...")
|
||||
|
||||
|
@ -364,11 +364,11 @@ func (trader *Trader) SaveState() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if trader.environment.PersistenceServiceFacade == nil {
|
||||
if PersistenceServiceFacade == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ps := trader.environment.PersistenceServiceFacade.Get()
|
||||
ps := PersistenceServiceFacade.Get()
|
||||
|
||||
log.Infof("saving strategies states...")
|
||||
return trader.IterateStrategies(func(strategy StrategyID) error {
|
||||
|
@ -387,10 +387,9 @@ var defaultPersistenceSelector = &PersistenceSelector{
|
|||
}
|
||||
|
||||
func (trader *Trader) injectCommonServices(s interface{}) error {
|
||||
persistenceFacade := trader.environment.PersistenceServiceFacade
|
||||
persistence := &Persistence{
|
||||
PersistenceSelector: defaultPersistenceSelector,
|
||||
Facade: persistenceFacade,
|
||||
Facade: PersistenceServiceFacade,
|
||||
}
|
||||
|
||||
// a special injection for persistence selector:
|
||||
|
@ -404,7 +403,7 @@ func (trader *Trader) injectCommonServices(s interface{}) error {
|
|||
return fmt.Errorf("field Persistence is not a struct element, %s given", field)
|
||||
}
|
||||
|
||||
if err := injectField(elem, "Facade", persistenceFacade, true); err != nil {
|
||||
if err := injectField(elem, "Facade", PersistenceServiceFacade, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -426,6 +425,6 @@ func (trader *Trader) injectCommonServices(s interface{}) error {
|
|||
trader.environment.AccountService,
|
||||
trader.environment,
|
||||
persistence,
|
||||
persistenceFacade, // if the strategy use persistence facade separately
|
||||
PersistenceServiceFacade, // if the strategy use persistence facade separately
|
||||
)
|
||||
}
|
||||
|
|
|
@ -160,6 +160,7 @@ var BacktestCmd = &cobra.Command{
|
|||
|
||||
backtestService := &service.BacktestService{DB: environ.DatabaseService.DB}
|
||||
environ.BacktestService = backtestService
|
||||
bbgo.SetBackTesting(backtestService)
|
||||
|
||||
if len(sessionName) > 0 {
|
||||
userConfig.Backtest.Sessions = []string{sessionName}
|
||||
|
|
Loading…
Reference in New Issue
Block a user