mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
refactor session sync
This commit is contained in:
parent
90069a8589
commit
eaa8c647b5
|
@ -76,6 +76,21 @@ func (environ *Environment) Sessions() map[string]*ExchangeSession {
|
|||
return environ.sessions
|
||||
}
|
||||
|
||||
func (environ *Environment) SelectSessions(names ...string) map[string]*ExchangeSession {
|
||||
if len(names) == 0 {
|
||||
return environ.sessions
|
||||
}
|
||||
|
||||
sessions := make(map[string]*ExchangeSession)
|
||||
for _, name := range names {
|
||||
if s, ok := environ.Session(name) ; ok {
|
||||
sessions[name] = s
|
||||
}
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
func (environ *Environment) ConfigureDatabase(ctx context.Context, driver string, dsn string) error {
|
||||
environ.DatabaseService = service.NewDatabaseService(driver, dsn)
|
||||
err := environ.DatabaseService.Connect()
|
||||
|
|
91
pkg/bbgo/sync.go
Normal file
91
pkg/bbgo/sync.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package bbgo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func stringSliceContains(slice []string, needle string) bool {
|
||||
for _, s := range slice {
|
||||
if s == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func FindPossibleSymbols(session *ExchangeSession) (symbols []string, err error) {
|
||||
var balances = session.Account.Balances()
|
||||
var fiatCurrencies = []string{"USDC", "USDT", "USD", "TWD", "EUR", "GBP"}
|
||||
var fiatAssets []string
|
||||
|
||||
for _, currency := range fiatCurrencies {
|
||||
if balance, ok := balances[currency]; ok && balance.Total() > 0 {
|
||||
fiatAssets = append(fiatAssets, currency)
|
||||
}
|
||||
}
|
||||
|
||||
var symbolMap = map[string]struct{}{}
|
||||
|
||||
for _, market := range session.Markets() {
|
||||
// ignore the markets that are not fiat currency markets
|
||||
if !stringSliceContains(fiatAssets, market.QuoteCurrency) {
|
||||
continue
|
||||
}
|
||||
|
||||
// ignore the asset that we don't have in the balance sheet
|
||||
balance, hasAsset := balances[market.BaseCurrency]
|
||||
if !hasAsset || balance.Total() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
symbolMap[market.Symbol] = struct{}{}
|
||||
}
|
||||
|
||||
for s := range symbolMap {
|
||||
symbols = append(symbols, s)
|
||||
}
|
||||
|
||||
return symbols, nil
|
||||
}
|
||||
|
||||
// SyncSessionSymbols syncs the trades from the given exchange session
|
||||
func SyncSessionSymbols(ctx context.Context, environ *Environment, session *ExchangeSession, startTime time.Time, symbols ...string) error {
|
||||
for _, symbol := range symbols {
|
||||
logrus.Debugf("syncing trades from exchange session %s...", session.Name)
|
||||
if err := environ.TradeSync.SyncTrades(ctx, session.Exchange, symbol, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("syncing orders from exchange session %s...", session.Name)
|
||||
if err := environ.TradeSync.SyncOrders(ctx, session.Exchange, symbol, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSessionSymbols(session *ExchangeSession, defaultSymbols ...string) ([]string, error) {
|
||||
if session.IsolatedMargin {
|
||||
return []string{session.IsolatedMarginSymbol}, nil
|
||||
}
|
||||
|
||||
if len(defaultSymbols) > 0 {
|
||||
return defaultSymbols, nil
|
||||
}
|
||||
|
||||
return FindPossibleSymbols(session)
|
||||
}
|
||||
|
||||
func SyncSession(ctx context.Context, environ *Environment, session *ExchangeSession, startTime time.Time, defaultSymbols ...string) error {
|
||||
symbols, err := getSessionSymbols(session, defaultSymbols...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return SyncSessionSymbols(ctx, environ, session, startTime, symbols...)
|
||||
}
|
127
pkg/cmd/sync.go
127
pkg/cmd/sync.go
|
@ -2,7 +2,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
|
@ -86,129 +85,31 @@ var SyncCmd = &cobra.Command{
|
|||
return err
|
||||
}
|
||||
|
||||
var symbols []string
|
||||
var defaultSymbols []string
|
||||
if len(symbol) > 0 {
|
||||
symbols = []string{symbol}
|
||||
defaultSymbols = []string{symbol}
|
||||
}
|
||||
|
||||
var selectedSessions []string
|
||||
|
||||
if len(sessionName) > 0 {
|
||||
session, ok := environ.Session(sessionName)
|
||||
if !ok {
|
||||
return fmt.Errorf("session %s not found", sessionName)
|
||||
}
|
||||
|
||||
if len(symbols) == 0 {
|
||||
symbols, err = findPossibleSymbols(ctx, environ, session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("found possible symbols: %v", symbols)
|
||||
}
|
||||
|
||||
for _, s := range symbols {
|
||||
if err := syncSessionSymbol(ctx, environ, session, s, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
selectedSessions = []string{sessionName}
|
||||
}
|
||||
|
||||
for _, session := range environ.Sessions() {
|
||||
if len(symbols) == 0 {
|
||||
symbols, err = findPossibleSymbols(ctx, environ, session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("found possible symbols: %v", symbols)
|
||||
}
|
||||
|
||||
for _, s := range symbols {
|
||||
if err := syncSessionSymbol(ctx, environ, session, s, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := syncSessionSymbol(ctx, environ, session, symbol, startTime); err != nil {
|
||||
sessions := environ.SelectSessions(selectedSessions...)
|
||||
for _, session := range sessions {
|
||||
if err := session.Init(ctx, environ) ; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := bbgo.SyncSession(ctx, environ, session, startTime, defaultSymbols...) ; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("exchange session %s synchronization done", session.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func stringSliceContains(slice []string, needle string) bool {
|
||||
for _, s := range slice {
|
||||
if s == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func findPossibleSymbols(ctx context.Context, environ *bbgo.Environment, session *bbgo.ExchangeSession) (symbols []string, err error) {
|
||||
err = session.Init(ctx, environ)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var balances = session.Account.Balances()
|
||||
var fiatCurrencies = []string{"USDC", "USDT", "USD", "TWD", "EUR", "GBP"}
|
||||
var fiatAssets []string
|
||||
|
||||
for _, currency := range fiatCurrencies {
|
||||
if balance, ok := balances[currency] ; ok && balance.Total() > 0 {
|
||||
fiatAssets = append(fiatAssets, currency)
|
||||
}
|
||||
}
|
||||
|
||||
var symbolMap = map[string]struct{}{}
|
||||
|
||||
for _, market := range session.Markets() {
|
||||
// ignore the markets that are not fiat currency markets
|
||||
if !stringSliceContains(fiatAssets, market.QuoteCurrency) {
|
||||
continue
|
||||
}
|
||||
|
||||
// ignore the asset that we don't have in the balance sheet
|
||||
balance, hasAsset := balances[market.BaseCurrency]
|
||||
if !hasAsset || balance.Total() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
symbolMap[market.Symbol] = struct{}{}
|
||||
}
|
||||
|
||||
for s := range symbolMap {
|
||||
symbols = append(symbols, s)
|
||||
}
|
||||
|
||||
return symbols, nil
|
||||
}
|
||||
|
||||
func syncSessionSymbol(ctx context.Context, environ *bbgo.Environment, session *bbgo.ExchangeSession, symbol string, startTime time.Time) error {
|
||||
log.Infof("starting syncing exchange session %s", session.Name)
|
||||
|
||||
if session.IsolatedMargin {
|
||||
log.Infof("session is configured as isolated margin session, using isolated margin symbol %s instead of %s", session.IsolatedMarginSymbol, symbol)
|
||||
symbol = session.IsolatedMarginSymbol
|
||||
}
|
||||
|
||||
log.Infof("syncing trades from exchange session %s...", session.Name)
|
||||
if err := environ.TradeSync.SyncTrades(ctx, session.Exchange, symbol, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("syncing orders from exchange session %s...", session.Name)
|
||||
if err := environ.TradeSync.SyncOrders(ctx, session.Exchange, symbol, startTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("exchange session %s synchronization done", session.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user