bbgo

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2020 License: MIT Imports: 24 Imported by: 97

Documentation

Index

Constants

View Source
const TemplateOrderReport = `:handshake: {{ .Symbol }} {{ .Side }} Order Update @ {{ .Price  }}`
View Source
const TemplateTradeReport = `:handshake: {{ .Symbol }} {{ .Side }} Trade Execution @ {{ .Price  }}`

Variables

View Source
var (
	ErrQuoteBalanceLevelTooLow  = errors.New("quote balance level is too low")
	ErrInsufficientQuoteBalance = errors.New("insufficient quote balance")

	ErrAssetBalanceLevelTooLow  = errors.New("asset balance level too low")
	ErrInsufficientAssetBalance = errors.New("insufficient asset balance")
	ErrAssetBalanceLevelTooHigh = errors.New("asset balance level too high")
)
View Source
var LoadedCrossExchangeStrategies = make(map[string]CrossExchangeStrategy)
View Source
var LoadedExchangeStrategies = make(map[string]SingleExchangeStrategy)
View Source
var SupportedExchanges = []types.ExchangeName{"binance", "max"}

Functions

func CacheDir

func CacheDir() string

func HomeDir

func HomeDir() string

func LoadExchangeMarketsWithCache

func LoadExchangeMarketsWithCache(ctx context.Context, ex types.Exchange) (markets types.MarketMap, err error)

func RegisterStrategy

func RegisterStrategy(key string, s interface{})

func SourceDir

func SourceDir() string

func WithCache

func WithCache(key string, obj interface{}, fetcher DataFetcher) error

WithCache let you use the cache with the given cache key, variable reference and your data fetcher, The key must be an unique ID. obj is the pointer of your local variable fetcher is the closure that will fetch your remote data or some slow operation.

Types

type AverageCostPnLReporter

type AverageCostPnLReporter struct {
	Sessions []string
	Symbols  []string
	// contains filtered or unexported fields
}

func (*AverageCostPnLReporter) Of

func (reporter *AverageCostPnLReporter) Of(sessions ...string) *AverageCostPnLReporter

func (*AverageCostPnLReporter) Run

func (reporter *AverageCostPnLReporter) Run()

func (*AverageCostPnLReporter) When

func (reporter *AverageCostPnLReporter) When(specs ...string) *AverageCostPnLReporter

type Backtest

type Backtest struct {
	StartTime string `json:"startTime" yaml:"startTime"`
	EndTime   string `json:"endTime" yaml:"endTime"`

	Account BacktestAccount `json:"account" yaml:"account"`
	Symbols []string        `json:"symbols" yaml:"symbols"`
}

func (Backtest) ParseEndTime

func (t Backtest) ParseEndTime() (time.Time, error)

func (Backtest) ParseStartTime

func (t Backtest) ParseStartTime() (time.Time, error)

type BacktestAccount

type BacktestAccount struct {
	MakerCommission  int                       `json:"makerCommission"`
	TakerCommission  int                       `json:"takerCommission"`
	BuyerCommission  int                       `json:"buyerCommission"`
	SellerCommission int                       `json:"sellerCommission"`
	Balances         BacktestAccountBalanceMap `json:"balances" yaml:"balances"`
}

type BacktestAccountBalanceMap

type BacktestAccountBalanceMap map[string]fixedpoint.Value

func (BacktestAccountBalanceMap) BalanceMap

type BasicRiskController

type BasicRiskController struct {
	Logger *logrus.Logger

	MaxOrderAmount      fixedpoint.Value `json:"maxOrderAmount,omitempty"`
	MinQuoteBalance     fixedpoint.Value `json:"minQuoteBalance,omitempty"`
	MaxBaseAssetBalance fixedpoint.Value `json:"maxBaseAssetBalance,omitempty"`
	MinBaseAssetBalance fixedpoint.Value `json:"minBaseAssetBalance,omitempty"`
}

func (*BasicRiskController) ProcessOrders

func (c *BasicRiskController) ProcessOrders(session *ExchangeSession, orders ...types.SubmitOrder) (outOrders []types.SubmitOrder, errs []error)

ProcessOrders filters and modifies the submit order objects by: 1. Increase the quantity by the minimal requirement 2. Decrease the quantity by risk controls 3. If the quantity does not meet minimal requirement, we should ignore the submit order.

type Config

type Config struct {
	Imports []string `json:"imports" yaml:"imports"`

	Backtest *Backtest `json:"backtest,omitempty" yaml:"backtest,omitempty"`

	Notifications *NotificationConfig `json:"notifications,omitempty" yaml:"notifications,omitempty"`

	Sessions map[string]Session `json:"sessions,omitempty" yaml:"sessions,omitempty"`

	RiskControls *RiskControls `json:"riskControls,omitempty" yaml:"riskControls,omitempty"`

	ExchangeStrategies      []ExchangeStrategyMount
	CrossExchangeStrategies []CrossExchangeStrategy

	PnLReporters []PnLReporterConfig `json:"reportPnL,omitempty" yaml:"reportPnL,omitempty"`
}

func Load

func Load(configFile string) (*Config, error)

type Context

type Context struct {
	sync.Mutex
}

deprecated: legacy context struct

type CrossExchangeStrategy

type CrossExchangeStrategy interface {
	Run(ctx context.Context, orderExecutionRouter OrderExecutionRouter, sessions map[string]*ExchangeSession) error
}

type DataFetcher

type DataFetcher func() (interface{}, error)

type Environment

type Environment struct {
	// Notifiability here for environment is for the streaming data notification
	// note that, for back tests, we don't need notification.
	Notifiability

	TradeService *service.TradeService
	TradeSync    *service.SyncService
	// contains filtered or unexported fields
}

Environment presents the real exchange data layer

func NewEnvironment

func NewEnvironment() *Environment

func (*Environment) AddExchange

func (environ *Environment) AddExchange(name string, exchange types.Exchange) (session *ExchangeSession)

func (*Environment) ConfigureNotification

func (environ *Environment) ConfigureNotification(conf *NotificationConfig)

configure notification rules for symbol-based routes, we should register the same symbol rules for each session. for session-based routes, we should set the fixed callbacks for each session

func (*Environment) Connect

func (environ *Environment) Connect(ctx context.Context) error

func (*Environment) Init

func (environ *Environment) Init(ctx context.Context) (err error)

Init prepares the data that will be used by the strategies

func (*Environment) Sessions

func (environ *Environment) Sessions() map[string]*ExchangeSession

func (*Environment) SetStartTime

func (environ *Environment) SetStartTime(t time.Time) *Environment

func (*Environment) SyncTrades

func (environ *Environment) SyncTrades(db *sqlx.DB) *Environment

func (*Environment) SyncTradesFrom

func (environ *Environment) SyncTradesFrom(t time.Time) *Environment

SyncTradesFrom overrides the default trade scan time (-7 days)

type ExchangeOrderExecutionRouter

type ExchangeOrderExecutionRouter struct {
	Notifiability
	// contains filtered or unexported fields
}

func (*ExchangeOrderExecutionRouter) SubmitOrdersTo

func (e *ExchangeOrderExecutionRouter) SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) (types.OrderSlice, error)

type ExchangeOrderExecutor

type ExchangeOrderExecutor struct {
	Notifiability `json:"-"`
	// contains filtered or unexported fields
}

ExchangeOrderExecutor is an order executor wrapper for single exchange instance.

func (*ExchangeOrderExecutor) SetLogger

func (e *ExchangeOrderExecutor) SetLogger(logger Logger)

func (*ExchangeOrderExecutor) SubmitOrders

func (e *ExchangeOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (types.OrderSlice, error)

type ExchangeSession

type ExchangeSession struct {
	// exchange session based notification system
	// we make it as a value field so that we can configure it separately
	Notifiability

	// Exchange session name
	Name string

	// The exchange account states
	Account *types.Account

	// Stream is the connection stream of the exchange
	Stream types.Stream

	Subscriptions map[types.Subscription]types.Subscription

	Exchange types.Exchange

	// Trades collects the executed trades from the exchange
	// map: symbol -> []trade
	Trades map[string][]types.Trade
	// contains filtered or unexported fields
}

ExchangeSession presents the exchange connection session It also maintains and collects the data returned from the stream.

func NewExchangeSession

func NewExchangeSession(name string, exchange types.Exchange) *ExchangeSession

func (*ExchangeSession) LastPrice

func (session *ExchangeSession) LastPrice(symbol string) (price float64, ok bool)

func (*ExchangeSession) Market

func (session *ExchangeSession) Market(symbol string) (market types.Market, ok bool)

func (*ExchangeSession) MarketDataStore

func (session *ExchangeSession) MarketDataStore(symbol string) (s *MarketDataStore, ok bool)

MarketDataStore returns the market data store of a symbol

func (*ExchangeSession) StandardIndicatorSet

func (session *ExchangeSession) StandardIndicatorSet(symbol string) (*StandardIndicatorSet, bool)

func (*ExchangeSession) StartPrice

func (session *ExchangeSession) StartPrice(symbol string) (price float64, ok bool)

func (*ExchangeSession) Subscribe

func (session *ExchangeSession) Subscribe(channel types.Channel, symbol string, options types.SubscribeOptions) *ExchangeSession

Subscribe save the subscription info, later it will be assigned to the stream

type ExchangeSessionSubscriber

type ExchangeSessionSubscriber interface {
	Subscribe(session *ExchangeSession)
}

type ExchangeStrategyMount

type ExchangeStrategyMount struct {
	// Mounts contains the session name to mount
	Mounts []string

	// Strategy is the strategy we loaded from config
	Strategy SingleExchangeStrategy
}

ExchangeStrategyMount wraps the SingleExchangeStrategy with the session name for mounting

type LocalActiveOrderBook

type LocalActiveOrderBook struct {
	Bids *types.SyncOrderMap
	Asks *types.SyncOrderMap
}

LocalActiveOrderBook manages the local active order books.

func NewLocalActiveOrderBook

func NewLocalActiveOrderBook() *LocalActiveOrderBook

func (*LocalActiveOrderBook) Add

func (b *LocalActiveOrderBook) Add(orders ...types.Order)

func (*LocalActiveOrderBook) Delete

func (b *LocalActiveOrderBook) Delete(order types.Order)

func (*LocalActiveOrderBook) NumOfAsks

func (b *LocalActiveOrderBook) NumOfAsks() int

func (*LocalActiveOrderBook) NumOfBids

func (b *LocalActiveOrderBook) NumOfBids() int

func (*LocalActiveOrderBook) Orders

func (*LocalActiveOrderBook) Print

func (b *LocalActiveOrderBook) Print()

func (*LocalActiveOrderBook) Update

func (b *LocalActiveOrderBook) Update(orders ...types.Order)

func (*LocalActiveOrderBook) WriteOff

func (b *LocalActiveOrderBook) WriteOff(order types.Order) bool

WriteOff writes off the filled order on the opposite side. This method does not write off order by order amount or order quantity.

type Logger

type Logger interface {
	Warnf(message string, args ...interface{})
	Errorf(message string, args ...interface{})
	Infof(message string, args ...interface{})
}

type Logging

type Logging interface {
	EnableLogging()
	DisableLogging()
}

type MarketDataStore

type MarketDataStore struct {
	Symbol string

	// KLineWindows stores all loaded klines per interval
	KLineWindows map[types.Interval]types.KLineWindow `json:"-"`

	LastKLine types.KLine
	// contains filtered or unexported fields
}

MarketDataStore receives and maintain the public market data

func NewMarketDataStore

func NewMarketDataStore(symbol string) *MarketDataStore

func (*MarketDataStore) AddKLine

func (store *MarketDataStore) AddKLine(kline types.KLine)

func (*MarketDataStore) BindStream

func (store *MarketDataStore) BindStream(stream types.Stream)

func (*MarketDataStore) EmitKLineWindowUpdate

func (store *MarketDataStore) EmitKLineWindowUpdate(interval types.Interval, kline types.KLineWindow)

func (*MarketDataStore) EmitOrderBookUpdate

func (store *MarketDataStore) EmitOrderBookUpdate(orderBook *types.StreamOrderBook)

func (*MarketDataStore) KLinesOfInterval

func (store *MarketDataStore) KLinesOfInterval(interval types.Interval) (kLines types.KLineWindow, ok bool)

KLinesOfInterval returns the kline window of the given interval

func (*MarketDataStore) OnKLineWindowUpdate

func (store *MarketDataStore) OnKLineWindowUpdate(cb func(interval types.Interval, kline types.KLineWindow))

func (*MarketDataStore) OnOrderBookUpdate

func (store *MarketDataStore) OnOrderBookUpdate(cb func(orderBook *types.StreamOrderBook))

func (*MarketDataStore) OrderBook

func (store *MarketDataStore) OrderBook() types.OrderBook

func (*MarketDataStore) SetKLineWindows

func (store *MarketDataStore) SetKLineWindows(windows map[types.Interval]types.KLineWindow)

type Notifiability

type Notifiability struct {
	SessionChannelRouter *PatternChannelRouter
	SymbolChannelRouter  *PatternChannelRouter
	ObjectChannelRouter  *ObjectChannelRouter
	// contains filtered or unexported fields
}

func (*Notifiability) AddNotifier

func (m *Notifiability) AddNotifier(notifier Notifier)

AddNotifier adds the notifier that implements the Notifier interface.

func (*Notifiability) Notify

func (m *Notifiability) Notify(format string, args ...interface{})

func (*Notifiability) NotifyTo

func (m *Notifiability) NotifyTo(channel, format string, args ...interface{})

func (*Notifiability) RouteObject

func (m *Notifiability) RouteObject(obj interface{}) (channel string, ok bool)

RouteObject routes object to channel

func (*Notifiability) RouteSession

func (m *Notifiability) RouteSession(session string) (channel string, ok bool)

RouteSession routes session name to channel

func (*Notifiability) RouteSymbol

func (m *Notifiability) RouteSymbol(symbol string) (channel string, ok bool)

RouteSession routes symbol name to channel

type NotificationConfig

type NotificationConfig struct {
	Slack *SlackNotification `json:"slack,omitempty" yaml:"slack,omitempty"`

	SymbolChannels  map[string]string `json:"symbolChannels,omitempty" yaml:"symbolChannels,omitempty"`
	SessionChannels map[string]string `json:"sessionChannels,omitempty" yaml:"sessionChannels,omitempty"`

	Routing *NotificationRouting `json:"routing,omitempty" yaml:"routing,omitempty"`
}

type NotificationRouting

type NotificationRouting struct {
	Trade       string `json:"trade,omitempty" yaml:"trade,omitempty"`
	Order       string `json:"order,omitempty" yaml:"order,omitempty"`
	SubmitOrder string `json:"submitOrder,omitempty" yaml:"submitOrder,omitempty"`
	PnL         string `json:"pnL,omitempty" yaml:"pnL,omitempty"`
}

type Notifier

type Notifier interface {
	NotifyTo(channel, format string, args ...interface{})
	Notify(format string, args ...interface{})
}

type NullNotifier

type NullNotifier struct{}

func (*NullNotifier) Notify

func (n *NullNotifier) Notify(format string, args ...interface{})

func (*NullNotifier) NotifyTo

func (n *NullNotifier) NotifyTo(channel, format string, args ...interface{})

type ObjectChannelHandler

type ObjectChannelHandler func(obj interface{}) (channel string, ok bool)

type ObjectChannelRouter

type ObjectChannelRouter struct {
	// contains filtered or unexported fields
}

func NewObjectChannelRouter

func NewObjectChannelRouter() *ObjectChannelRouter

func (*ObjectChannelRouter) AddRoute

func (router *ObjectChannelRouter) AddRoute(f ObjectChannelHandler)

func (*ObjectChannelRouter) Route

func (router *ObjectChannelRouter) Route(obj interface{}) (channel string, ok bool)

type OrderExecutionRouter

type OrderExecutionRouter interface {
	// SubmitOrderTo submit order to a specific exchange session
	SubmitOrdersTo(ctx context.Context, session string, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error)
}

type OrderExecutor

type OrderExecutor interface {
	SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error)
}

type PatternChannelRouter

type PatternChannelRouter struct {
	// contains filtered or unexported fields
}

func NewPatternChannelRouter

func NewPatternChannelRouter(routes map[string]string) *PatternChannelRouter

func (*PatternChannelRouter) AddRoute

func (router *PatternChannelRouter) AddRoute(routes map[string]string)

func (*PatternChannelRouter) Route

func (router *PatternChannelRouter) Route(text string) (channel string, ok bool)

type PnLReporter

type PnLReporter interface {
	Run()
}

type PnLReporterConfig

type PnLReporterConfig struct {
	AverageCostBySymbols StringSlice `json:"averageCostBySymbols" yaml:"averageCostBySymbols"`
	Of                   StringSlice `json:"of" yaml:"of"`
	When                 StringSlice `json:"when" yaml:"when"`
}

type PnLReporterManager

type PnLReporterManager struct {
	// contains filtered or unexported fields
}

func NewPnLReporter

func NewPnLReporter(notifier Notifier) *PnLReporterManager

func (*PnLReporterManager) AverageCostBySymbols

func (manager *PnLReporterManager) AverageCostBySymbols(symbols ...string) *AverageCostPnLReporter

type RiskControlOrderExecutor

type RiskControlOrderExecutor struct {
	*ExchangeOrderExecutor

	// Symbol => Executor config
	BySymbol map[string]*SymbolBasedRiskController `json:"bySymbol,omitempty" yaml:"bySymbol,omitempty"`
}

func (*RiskControlOrderExecutor) SubmitOrders

func (e *RiskControlOrderExecutor) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (retOrders types.OrderSlice, err error)

type RiskControls

type RiskControls struct {
	SessionBasedRiskControl map[string]*SessionBasedRiskControl `json:"sessionBased,omitempty" yaml:"sessionBased,omitempty"`
}

type Session

type Session struct {
	ExchangeName string `json:"exchange" yaml:"exchange"`
	EnvVarPrefix string `json:"envVarPrefix" yaml:"envVarPrefix"`
}

type SessionBasedRiskControl

type SessionBasedRiskControl struct {
	OrderExecutor *RiskControlOrderExecutor `json:"orderExecutor,omitempty" yaml:"orderExecutor"`
}

func (*SessionBasedRiskControl) SetBaseOrderExecutor

func (control *SessionBasedRiskControl) SetBaseOrderExecutor(executor *ExchangeOrderExecutor)

type SilentLogger

type SilentLogger struct{}

func (*SilentLogger) Errorf

func (logger *SilentLogger) Errorf(message string, args ...interface{})

func (*SilentLogger) Infof

func (logger *SilentLogger) Infof(message string, args ...interface{})

func (*SilentLogger) Warnf

func (logger *SilentLogger) Warnf(message string, args ...interface{})

type SingleExchangeStrategy

type SingleExchangeStrategy interface {
	Run(ctx context.Context, orderExecutor OrderExecutor, session *ExchangeSession) error
}

SingleExchangeStrategy represents the single Exchange strategy

type SlackNotification

type SlackNotification struct {
	DefaultChannel string `json:"defaultChannel,omitempty"  yaml:"defaultChannel,omitempty"`
	ErrorChannel   string `json:"errorChannel,omitempty"  yaml:"errorChannel,omitempty"`
}

type StandardIndicatorSet

type StandardIndicatorSet struct {
	Symbol string
	// Standard indicators
	// interval -> window
	SMA  map[types.IntervalWindow]*indicator.SMA
	EWMA map[types.IntervalWindow]*indicator.EWMA
	BOLL map[types.IntervalWindow]*indicator.BOLL
	// contains filtered or unexported fields
}

func NewStandardIndicatorSet

func NewStandardIndicatorSet(symbol string, store *MarketDataStore) *StandardIndicatorSet

func (*StandardIndicatorSet) GetBOLL

GetBOLL returns the bollinger band indicator of the given interval and the window, Please note that the K for std dev is fixed and defaults to 2.0

func (*StandardIndicatorSet) GetEWMA

GetEWMA returns the exponential weighed moving average indicator of the given interval and the window size.

func (*StandardIndicatorSet) GetSMA

GetSMA returns the simple moving average indicator of the given interval and the window size.

type Stash

type Stash map[string]interface{}

type StringSlice

type StringSlice []string

func (*StringSlice) UnmarshalJSON

func (s *StringSlice) UnmarshalJSON(b []byte) error

func (*StringSlice) UnmarshalYAML

func (s *StringSlice) UnmarshalYAML(unmarshal func(interface{}) error) (err error)

type SymbolBasedRiskController

type SymbolBasedRiskController struct {
	BasicRiskController *BasicRiskController `json:"basic,omitempty" yaml:"basic,omitempty"`
}

type TradeReporter

type TradeReporter struct {
	*Notifiability
}

type Trader

type Trader struct {
	// contains filtered or unexported fields
}

func NewTrader

func NewTrader(environ *Environment) *Trader

func (*Trader) AttachCrossExchangeStrategy

func (trader *Trader) AttachCrossExchangeStrategy(strategy CrossExchangeStrategy) *Trader

AttachCrossExchangeStrategy attaches the cross exchange strategy

func (*Trader) AttachStrategyOn

func (trader *Trader) AttachStrategyOn(session string, strategies ...SingleExchangeStrategy) *Trader

AttachStrategyOn attaches the single exchange strategy on an exchange session. Single exchange strategy is the default behavior.

func (*Trader) DisableLogging

func (trader *Trader) DisableLogging()

func (*Trader) EnableLogging

func (trader *Trader) EnableLogging()

func (*Trader) ReportPnL

func (trader *Trader) ReportPnL() *PnLReporterManager

ReportPnL configure and set the PnLReporter with the given notifier

func (*Trader) Run

func (trader *Trader) Run(ctx context.Context) error

func (*Trader) SetRiskControls

func (trader *Trader) SetRiskControls(riskControls *RiskControls)

TODO: provide a more DSL way to configure risk controls

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL