mirror of
https://github.com/c9s/bbgo.git
synced 2024-09-20 08:11:08 +00:00
unmarshal imports into config
This commit is contained in:
parent
e1e8a16f97
commit
cd28fb8771
|
@ -2,7 +2,6 @@ package bbgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
|
@ -96,7 +95,6 @@ func (reporter *AverageCostPnLReporter) Run() {
|
||||||
for _, sessionName := range reporter.Sessions {
|
for _, sessionName := range reporter.Sessions {
|
||||||
session := reporter.environment.sessions[sessionName]
|
session := reporter.environment.sessions[sessionName]
|
||||||
calculator := &pnl.AverageCostCalculator{
|
calculator := &pnl.AverageCostCalculator{
|
||||||
StartTime: time.Time{},
|
|
||||||
TradingFeeCurrency: session.Exchange.PlatformFeeCurrency(),
|
TradingFeeCurrency: session.Exchange.PlatformFeeCurrency(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
107
pkg/cmd/run.go
107
pkg/cmd/run.go
|
@ -24,9 +24,60 @@ func init() {
|
||||||
RootCmd.AddCommand(RunCmd)
|
RootCmd.AddCommand(RunCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runConfig(ctx context.Context, configFile string) error {
|
||||||
|
userConfig, err := config.Load(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
slackToken := viper.GetString("slack-token")
|
||||||
|
if len(slackToken) == 0 {
|
||||||
|
return errSlackTokenUndefined
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.AddHook(slacklog.NewLogHook(slackToken, viper.GetString("slack-error-channel")))
|
||||||
|
|
||||||
|
var notifier = slacknotifier.New(slackToken, viper.GetString("slack-channel"))
|
||||||
|
|
||||||
|
db, err := cmdutil.ConnectMySQL()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
environ := bbgo.NewDefaultEnvironment(db)
|
||||||
|
environ.ReportTrade(notifier)
|
||||||
|
|
||||||
|
trader := bbgo.NewTrader(environ)
|
||||||
|
|
||||||
|
for _, entry := range userConfig.ExchangeStrategies {
|
||||||
|
for _, mount := range entry.Mounts {
|
||||||
|
logrus.Infof("attaching strategy %T on %s...", entry.Strategy, mount)
|
||||||
|
trader.AttachStrategyOn(mount, entry.Strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, strategy := range userConfig.CrossExchangeStrategies {
|
||||||
|
logrus.Infof("attaching strategy %T", strategy)
|
||||||
|
trader.AttachCrossExchangeStrategy(strategy)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, report := range userConfig.PnLReporters {
|
||||||
|
if len(report.AverageCostBySymbols) > 0 {
|
||||||
|
trader.ReportPnL(notifier).
|
||||||
|
AverageCostBySymbols(report.AverageCostBySymbols...).
|
||||||
|
Of(report.Of...).
|
||||||
|
When(report.When...)
|
||||||
|
} else {
|
||||||
|
return errors.Errorf("unsupported PnL reporter: %+v", report)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trader.Run(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
var RunCmd = &cobra.Command{
|
var RunCmd = &cobra.Command{
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: "run strategies",
|
Short: "run strategies from config file",
|
||||||
|
|
||||||
// SilenceUsage is an option to silence usage when an error occurs.
|
// SilenceUsage is an option to silence usage when an error occurs.
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
|
@ -38,63 +89,13 @@ var RunCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(configFile) == 0 {
|
if len(configFile) == 0 {
|
||||||
return errors.New("--config option is not given")
|
return errors.New("--config option is required")
|
||||||
}
|
|
||||||
|
|
||||||
userConfig, err := config.Load(configFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
slackToken := viper.GetString("slack-token")
|
err = runConfig(ctx, configFile)
|
||||||
if len(slackToken) == 0 {
|
|
||||||
return errSlackTokenUndefined
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.AddHook(slacklog.NewLogHook(slackToken, viper.GetString("slack-error-channel")))
|
|
||||||
|
|
||||||
var notifier = slacknotifier.New(slackToken, viper.GetString("slack-channel"))
|
|
||||||
|
|
||||||
db, err := cmdutil.ConnectMySQL()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
environ := bbgo.NewDefaultEnvironment(db)
|
|
||||||
environ.ReportTrade(notifier)
|
|
||||||
|
|
||||||
trader := bbgo.NewTrader(environ)
|
|
||||||
|
|
||||||
for _, entry := range userConfig.ExchangeStrategies {
|
|
||||||
for _, mount := range entry.Mounts {
|
|
||||||
logrus.Infof("attaching strategy %T on %s...", entry.Strategy, mount)
|
|
||||||
trader.AttachStrategyOn(mount, entry.Strategy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, strategy := range userConfig.CrossExchangeStrategies {
|
|
||||||
logrus.Infof("attaching strategy %T", strategy)
|
|
||||||
trader.AttachCrossExchangeStrategy(strategy)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, report := range userConfig.PnLReporters {
|
|
||||||
if len(report.AverageCostBySymbols) > 0 {
|
|
||||||
trader.ReportPnL(notifier).
|
|
||||||
AverageCostBySymbols(report.AverageCostBySymbols...).
|
|
||||||
Of(report.Of...).
|
|
||||||
When(report.When...)
|
|
||||||
} else {
|
|
||||||
return errors.Errorf("unsupported PnL reporter: %+v", report)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = trader.Run(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdutil.WaitForSignal(ctx, syscall.SIGINT, syscall.SIGTERM)
|
cmdutil.WaitForSignal(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -67,28 +67,32 @@ type Config struct {
|
||||||
|
|
||||||
type Stash map[string]interface{}
|
type Stash map[string]interface{}
|
||||||
|
|
||||||
func loadStash(configFile string) (Stash, error) {
|
func loadStash(config []byte) (Stash, error) {
|
||||||
config, err := ioutil.ReadFile(configFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
stash := make(Stash)
|
stash := make(Stash)
|
||||||
if err := yaml.Unmarshal(config, stash); err != nil {
|
if err := yaml.Unmarshal(config, stash); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return stash, err
|
return stash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load(configFile string) (*Config, error) {
|
func Load(configFile string) (*Config, error) {
|
||||||
var config Config
|
var config Config
|
||||||
|
|
||||||
stash, err := loadStash(configFile)
|
content, err := ioutil.ReadFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stash, err := loadStash(content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := loadImports(&config, stash); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := loadExchangeStrategies(&config, stash); err != nil {
|
if err := loadExchangeStrategies(&config, stash); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -104,6 +108,21 @@ func Load(configFile string) (*Config, error) {
|
||||||
return &config, nil
|
return &config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadImports(config *Config, stash Stash) error {
|
||||||
|
importStash, ok := stash["imports"]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
imports, err := reUnmarshal(importStash, &config.Imports)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Imports = *imports.(*[]string)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func loadReportPnL(config *Config, stash Stash) error {
|
func loadReportPnL(config *Config, stash Stash) error {
|
||||||
reporterStash, ok := stash["reportPnL"]
|
reporterStash, ok := stash["reportPnL"]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -120,16 +139,16 @@ func loadReportPnL(config *Config, stash Stash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadCrossExchangeStrategies(config *Config, stash Stash) (err error) {
|
func loadCrossExchangeStrategies(config *Config, stash Stash) (err error) {
|
||||||
if len(bbgo.LoadedCrossExchangeStrategies) == 0 {
|
|
||||||
return errors.New("no cross exchange strategy is registered")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
exchangeStrategiesConf, ok := stash["crossExchangeStrategies"]
|
exchangeStrategiesConf, ok := stash["crossExchangeStrategies"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(bbgo.LoadedCrossExchangeStrategies) == 0 {
|
||||||
|
return errors.New("no cross exchange strategy is registered")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
configList, ok := exchangeStrategiesConf.([]interface{})
|
configList, ok := exchangeStrategiesConf.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("expecting list in crossExchangeStrategies")
|
return errors.New("expecting list in crossExchangeStrategies")
|
||||||
|
@ -158,21 +177,20 @@ func loadCrossExchangeStrategies(config *Config, stash Stash) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadExchangeStrategies(config *Config, stash Stash) (err error) {
|
func loadExchangeStrategies(config *Config, stash Stash) (err error) {
|
||||||
if len(bbgo.LoadedExchangeStrategies) == 0 {
|
|
||||||
return errors.New("no exchange strategy is registered")
|
|
||||||
}
|
|
||||||
|
|
||||||
exchangeStrategiesConf, ok := stash["exchangeStrategies"]
|
exchangeStrategiesConf, ok := stash["exchangeStrategies"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(bbgo.LoadedExchangeStrategies) == 0 {
|
||||||
|
return errors.New("no exchange strategy is registered")
|
||||||
|
}
|
||||||
|
|
||||||
configList, ok := exchangeStrategiesConf.([]interface{})
|
configList, ok := exchangeStrategiesConf.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("expecting list in exchangeStrategies")
|
return errors.New("expecting list in exchangeStrategies")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for _, entry := range configList {
|
for _, entry := range configList {
|
||||||
configStash, ok := entry.(Stash)
|
configStash, ok := entry.(Stash)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -188,7 +206,6 @@ func loadExchangeStrategies(config *Config, stash Stash) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for id, conf := range configStash {
|
for id, conf := range configStash {
|
||||||
// look up the real struct type
|
// look up the real struct type
|
||||||
if st, ok := bbgo.LoadedExchangeStrategies[id]; ok {
|
if st, ok := bbgo.LoadedExchangeStrategies[id]; ok {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user