bbgo_origin/cmd/bbgo-lorca/main.go

162 lines
3.4 KiB
Go
Raw Permalink Normal View History

2021-02-04 10:22:47 +00:00
package main
import (
"context"
"net"
"os"
"os/signal"
"path/filepath"
2021-02-04 10:22:47 +00:00
"runtime"
2021-02-21 10:58:25 +00:00
time2 "time"
2021-02-04 10:22:47 +00:00
2021-02-04 12:31:04 +00:00
"github.com/joho/godotenv"
2021-02-04 10:22:47 +00:00
"github.com/zserge/lorca"
log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/server"
)
func main() {
ep, err := os.Executable()
if err != nil {
log.Fatalln("failed to find the current executable:", err)
}
err = os.Chdir(filepath.Join(filepath.Dir(ep), "..", "Resources"))
if err != nil {
log.Fatalln("chdir error:", err)
}
dotenvFile := ".env.local"
2021-02-17 11:06:20 +00:00
if _, err := os.Stat(dotenvFile); err == nil {
if err := godotenv.Load(dotenvFile); err != nil {
log.WithError(err).Error("error loading dotenv file")
return
}
2021-02-04 12:31:04 +00:00
}
2021-02-04 10:22:47 +00:00
var args []string
if runtime.GOOS == "linux" {
args = append(args, "--class=bbgo")
}
2021-02-17 11:06:20 +00:00
// args = append(args, "--enable-logging", "--v=99")
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
2021-02-04 10:22:47 +00:00
// here allocate a chrome window with a blank page.
2021-02-05 01:09:59 +00:00
ui, err := lorca.New("", "", 1024, 780, args...)
2021-02-04 10:22:47 +00:00
if err != nil {
log.WithError(err).Error("failed to initialize the window")
return
}
defer ui.Close()
configFile := "bbgo.yaml"
var setup *server.Setup
var userConfig *bbgo.Config
_, err = os.Stat(configFile)
if os.IsNotExist(err) {
setup = &server.Setup{
Context: ctx,
Cancel: cancel,
Token: "",
2021-02-05 05:01:07 +00:00
BeforeRestart: func() {
2021-02-17 11:06:20 +00:00
if err := ui.Close(); err != nil {
2021-02-05 05:01:07 +00:00
log.WithError(err).Errorf("ui close error")
}
},
2021-02-04 10:22:47 +00:00
}
userConfig = &bbgo.Config{
Notifications: nil,
Persistence: nil,
Sessions: nil,
ExchangeStrategies: nil,
}
} else {
userConfig, err = bbgo.Load(configFile, true)
if err != nil {
log.WithError(err).Error("can not load config file")
return
}
}
environ := bbgo.NewEnvironment()
trader := bbgo.NewTrader(environ)
// we could initialize the environment from the settings
if setup == nil {
2022-09-06 08:50:45 +00:00
if err := bbgo.BootstrapEnvironment(ctx, environ, userConfig); err != nil {
2021-02-04 10:22:47 +00:00
log.WithError(err).Error("failed to bootstrap environment")
return
}
2021-03-22 09:30:43 +00:00
if err := trader.Configure(userConfig); err != nil {
2021-02-04 10:22:47 +00:00
log.WithError(err).Error("failed to configure trader")
return
}
if err := trader.LoadState(); err != nil {
log.WithError(err).Error("failed to load strategy states")
return
}
2021-02-04 10:22:47 +00:00
// for setup mode, we don't start the trader
2021-02-17 11:06:20 +00:00
go func() {
if err := trader.Run(ctx); err != nil {
log.WithError(err).Error("failed to start trader")
}
}()
2021-02-04 10:22:47 +00:00
}
2021-02-17 11:06:20 +00:00
// find a free port for binding the server
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
log.WithError(err).Error("can not bind listener")
return
}
defer ln.Close()
baseURL := "http://" + ln.Addr().String()
2021-02-04 10:22:47 +00:00
2021-02-17 11:06:20 +00:00
srv := &server.Server{
Config: userConfig,
Environ: environ,
Trader: trader,
OpenInBrowser: false,
Setup: setup,
}
go func() {
2021-02-04 10:22:47 +00:00
if err := srv.RunWithListener(ctx, ln); err != nil {
log.WithError(err).Errorf("server error")
}
}()
2021-02-17 11:06:20 +00:00
log.Infof("pinging the server at %s", baseURL)
2021-02-21 10:58:25 +00:00
server.PingUntil(ctx, time2.Second, baseURL, func() {
2021-02-17 11:06:20 +00:00
log.Infof("got pong, loading base url %s to ui...", baseURL)
2021-02-04 10:22:47 +00:00
2021-02-17 11:06:20 +00:00
if err := ui.Load(baseURL); err != nil {
2021-02-04 10:22:47 +00:00
log.WithError(err).Error("failed to load page")
}
})
// Wait until the interrupt signal arrives or browser window is closed
sigc := make(chan os.Signal)
signal.Notify(sigc, os.Interrupt)
select {
case <-sigc:
case <-ui.Done():
}
log.Println("exiting...")
}