Documentation ¶
Overview ¶
The backtest process
The backtest engine loads the klines from the database into a kline-channel, there are multiple matching engine that matches the order sent from the strategy.
for each kline, the backtest engine:
1) load the kline, run matching logics to send out order update and trades to the user data stream. 2) once the matching process for the kline is done, the kline will be pushed to the market data stream. 3) go to 1 and load the next kline.
There are 2 ways that a strategy could work with backtest engine:
the strategy receives kline from the market data stream, and then it submits the order by the given market data to the backtest engine. backtest engine receives the order and then pushes the trade and order updates to the user data stream.
the strategy receives the trade and update its position.
the strategy places the orders when it starts. (like grid) the strategy then receives the order updates and then submit a new order by its order update message.
We need to ensure that:
- if the strategy submits the order from the market data stream, since it's a separate goroutine, the strategy should block the backtest engine to process the trades before the next kline is published.
Index ¶
- Constants
- Variables
- func AddReportIndexRun(outputDirectory string, run Run) error
- func CollectSubscriptionIntervals(environ *bbgo.Environment) (allKLineIntervals map[types.Interval]struct{}, requiredInterval types.Interval, ...)
- func FormatSessionName(sessions []string, symbols []string, startTime, endTime time.Time) string
- func InQuoteAsset(balances types.BalanceMap, market types.Market, price fixedpoint.Value) fixedpoint.Value
- func WriteReportIndex(outputDirectory string, reportIndex *ReportIndex) error
- type Exchange
- func (e *Exchange) BindUserData(userDataStream types.StandardStreamEmitter)
- func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) error
- func (e *Exchange) CloseMarketData() error
- func (e *Exchange) ConsumeKLine(k types.KLine, requiredInterval types.Interval)
- func (e *Exchange) Name() types.ExchangeName
- func (e *Exchange) NewStream() types.Stream
- func (e *Exchange) PlatformFeeCurrency() string
- func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error)
- func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error)
- func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) (orders []types.Order, err error)
- func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []types.Deposit, err error)
- func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval types.Interval, ...) ([]types.KLine, error)
- func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error)
- func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error)
- func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.Order, error)
- func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error)
- func (e *Exchange) QueryTickers(ctx context.Context, symbol ...string) (map[string]types.Ticker, error)
- func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *types.TradeQueryOptions) ([]types.Trade, error)
- func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error)
- func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (createdOrder *types.Order, err error)
- func (e *Exchange) SubscribeMarketData(startTime, endTime time.Time, requiredInterval types.Interval, ...) (chan types.KLine, error)
- type ExchangeDataSource
- type FeeModeFunction
- type Instance
- type InstancePropertyIndex
- type KLineDumper
- type ManifestEntry
- type Manifests
- type PriceOrder
- type PriceOrderSlice
- func (slice PriceOrderSlice) Find(price fixedpoint.Value, descending bool) (pv PriceOrder, idx int)
- func (slice PriceOrderSlice) First() (PriceOrder, bool)
- func (slice PriceOrderSlice) InsertAt(idx int, po PriceOrder) PriceOrderSlice
- func (slice PriceOrderSlice) Len() int
- func (slice PriceOrderSlice) Less(i, j int) bool
- func (slice PriceOrderSlice) Remove(price fixedpoint.Value, descending bool) PriceOrderSlice
- func (slice PriceOrderSlice) Swap(i, j int)
- func (slice PriceOrderSlice) Upsert(po PriceOrder, descending bool) PriceOrderSlice
- type ReportIndex
- type Run
- type SessionSymbolReport
- type SimplePriceMatching
- func (m *SimplePriceMatching) CancelOrder(o types.Order) (types.Order, error)
- func (m *SimplePriceMatching) EmitBalanceUpdate(balances types.BalanceMap)
- func (m *SimplePriceMatching) EmitOrderUpdate(order types.Order)
- func (m *SimplePriceMatching) EmitTradeUpdate(trade types.Trade)
- func (m *SimplePriceMatching) OnBalanceUpdate(cb func(balances types.BalanceMap))
- func (m *SimplePriceMatching) OnOrderUpdate(cb func(order types.Order))
- func (m *SimplePriceMatching) OnTradeUpdate(cb func(trade types.Trade))
- func (m *SimplePriceMatching) PlaceOrder(o types.SubmitOrder) (*types.Order, *types.Trade, error)
- type StateRecorder
- type SummaryReport
Constants ¶
const DateFormat = "2006-01-02T15:04"
const FeeToken = "FEE"
FeeToken is used to simulate the exchange platform fee token This is to ease the back-testing environment for closing positions.
const SessionTimeFormat = "2006-01-02T15_04"
Variables ¶
var ErrEmptyOrderType = errors.New("order type can not be empty string")
var ErrNegativeQuantity = errors.New("order quantity can not be negative")
var ErrUnimplemented = errors.New("unimplemented method")
var ErrZeroQuantity = errors.New("order quantity can not be zero")
var FS = &fs{}
Functions ¶
func AddReportIndexRun ¶ added in v1.33.0
func CollectSubscriptionIntervals ¶ added in v1.43.0
func FormatSessionName ¶ added in v1.33.0
FormatSessionName returns the back-test session name
func InQuoteAsset ¶ added in v1.37.0
func InQuoteAsset(balances types.BalanceMap, market types.Market, price fixedpoint.Value) fixedpoint.Value
InQuoteAsset converts all balances in quote asset
func WriteReportIndex ¶ added in v1.33.0
func WriteReportIndex(outputDirectory string, reportIndex *ReportIndex) error
Types ¶
type Exchange ¶
type Exchange struct { MarketDataStream types.StandardStreamEmitter Src *ExchangeDataSource // contains filtered or unexported fields }
func NewExchange ¶
func NewExchange( sourceName types.ExchangeName, sourceExchange types.Exchange, srv *service.BacktestService, config *bbgo.Backtest, ) (*Exchange, error)
func (*Exchange) BindUserData ¶ added in v1.36.0
func (e *Exchange) BindUserData(userDataStream types.StandardStreamEmitter)
func (*Exchange) CancelOrders ¶
func (*Exchange) CloseMarketData ¶ added in v1.28.0
func (*Exchange) ConsumeKLine ¶ added in v1.28.0
func (*Exchange) Name ¶
func (e *Exchange) Name() types.ExchangeName
func (*Exchange) PlatformFeeCurrency ¶
func (*Exchange) QueryAccount ¶
func (*Exchange) QueryAccountBalances ¶
func (*Exchange) QueryClosedOrders ¶
func (*Exchange) QueryDepositHistory ¶
func (*Exchange) QueryKLines ¶
func (*Exchange) QueryMarkets ¶
func (*Exchange) QueryOpenOrders ¶
func (*Exchange) QueryOrder ¶ added in v1.36.0
func (*Exchange) QueryTicker ¶ added in v1.11.1
func (*Exchange) QueryTickers ¶ added in v1.11.0
func (*Exchange) QueryTrades ¶
func (*Exchange) QueryWithdrawHistory ¶
func (*Exchange) SubmitOrder ¶ added in v1.40.3
type ExchangeDataSource ¶ added in v1.33.0
type ExchangeDataSource struct { C chan types.KLine Exchange *Exchange Session *bbgo.ExchangeSession Callbacks []func(types.KLine, *ExchangeDataSource) }
func InitializeExchangeSources ¶ added in v1.43.0
type FeeModeFunction ¶ added in v1.40.0
type FeeModeFunction func(order *types.Order, market *types.Market, feeRate fixedpoint.Value) (fee fixedpoint.Value, feeCurrency string)
type InstancePropertyIndex ¶ added in v1.33.0
type KLineDumper ¶ added in v1.33.0
type KLineDumper struct { OutputDirectory string // contains filtered or unexported fields }
KLineDumper dumps the received kline data into a folder for the backtest report to load the charts.
func NewKLineDumper ¶ added in v1.33.0
func NewKLineDumper(outputDirectory string) *KLineDumper
func (*KLineDumper) Close ¶ added in v1.33.0
func (d *KLineDumper) Close() error
func (*KLineDumper) Filenames ¶ added in v1.33.0
func (d *KLineDumper) Filenames() map[symbolInterval]string
type ManifestEntry ¶ added in v1.33.0
type Manifests ¶ added in v1.33.0
type Manifests map[InstancePropertyIndex]string
func (Manifests) MarshalJSON ¶ added in v1.33.0
func (*Manifests) UnmarshalJSON ¶ added in v1.33.0
type PriceOrder ¶
type PriceOrder struct { Price fixedpoint.Value Order types.Order }
type PriceOrderSlice ¶
type PriceOrderSlice []PriceOrder
func (PriceOrderSlice) Find ¶
func (slice PriceOrderSlice) Find(price fixedpoint.Value, descending bool) (pv PriceOrder, idx int)
FindPriceVolumePair finds the pair by the given price, this function is a read-only operation, so we use the value receiver to avoid copy value from the pointer If the price is not found, it will return the index where the price can be inserted at. true for descending (bid orders), false for ascending (ask orders)
func (PriceOrderSlice) First ¶
func (slice PriceOrderSlice) First() (PriceOrder, bool)
func (PriceOrderSlice) InsertAt ¶
func (slice PriceOrderSlice) InsertAt(idx int, po PriceOrder) PriceOrderSlice
func (PriceOrderSlice) Len ¶
func (slice PriceOrderSlice) Len() int
func (PriceOrderSlice) Less ¶
func (slice PriceOrderSlice) Less(i, j int) bool
func (PriceOrderSlice) Remove ¶
func (slice PriceOrderSlice) Remove(price fixedpoint.Value, descending bool) PriceOrderSlice
func (PriceOrderSlice) Swap ¶
func (slice PriceOrderSlice) Swap(i, j int)
func (PriceOrderSlice) Upsert ¶
func (slice PriceOrderSlice) Upsert(po PriceOrder, descending bool) PriceOrderSlice
type ReportIndex ¶ added in v1.33.0
type ReportIndex struct {
Runs []Run `json:"runs,omitempty"`
}
func LoadReportIndex ¶ added in v1.33.0
func LoadReportIndex(outputDirectory string) (*ReportIndex, error)
type SessionSymbolReport ¶ added in v1.33.0
type SessionSymbolReport struct { Exchange types.ExchangeName `json:"exchange"` Symbol string `json:"symbol,omitempty"` Intervals []types.Interval `json:"intervals,omitempty"` Subscriptions []types.Subscription `json:"subscriptions"` Market types.Market `json:"market"` LastPrice fixedpoint.Value `json:"lastPrice,omitempty"` StartPrice fixedpoint.Value `json:"startPrice,omitempty"` PnL *pnl.AverageCostPnLReport `json:"pnl,omitempty"` InitialBalances types.BalanceMap `json:"initialBalances,omitempty"` FinalBalances types.BalanceMap `json:"finalBalances,omitempty"` Manifests Manifests `json:"manifests,omitempty"` Sharpe fixedpoint.Value `json:"sharpeRatio"` Sortino fixedpoint.Value `json:"sortinoRatio"` ProfitFactor fixedpoint.Value `json:"profitFactor"` WinningRatio fixedpoint.Value `json:"winningRatio"` }
SessionSymbolReport is the report per exchange session trades are merged, collected and re-calculated
func (*SessionSymbolReport) FinalEquityValue ¶ added in v1.37.0
func (r *SessionSymbolReport) FinalEquityValue() fixedpoint.Value
func (*SessionSymbolReport) InitialEquityValue ¶ added in v1.37.0
func (r *SessionSymbolReport) InitialEquityValue() fixedpoint.Value
func (*SessionSymbolReport) Print ¶ added in v1.33.0
func (r *SessionSymbolReport) Print(wantBaseAssetBaseline bool)
type SimplePriceMatching ¶
type SimplePriceMatching struct { Symbol string Market types.Market // contains filtered or unexported fields }
SimplePriceMatching implements a simple kline data driven matching engine for backtest
func (*SimplePriceMatching) CancelOrder ¶
func (*SimplePriceMatching) EmitBalanceUpdate ¶
func (m *SimplePriceMatching) EmitBalanceUpdate(balances types.BalanceMap)
func (*SimplePriceMatching) EmitOrderUpdate ¶
func (m *SimplePriceMatching) EmitOrderUpdate(order types.Order)
func (*SimplePriceMatching) EmitTradeUpdate ¶
func (m *SimplePriceMatching) EmitTradeUpdate(trade types.Trade)
func (*SimplePriceMatching) OnBalanceUpdate ¶
func (m *SimplePriceMatching) OnBalanceUpdate(cb func(balances types.BalanceMap))
func (*SimplePriceMatching) OnOrderUpdate ¶
func (m *SimplePriceMatching) OnOrderUpdate(cb func(order types.Order))
func (*SimplePriceMatching) OnTradeUpdate ¶
func (m *SimplePriceMatching) OnTradeUpdate(cb func(trade types.Trade))
func (*SimplePriceMatching) PlaceOrder ¶
func (m *SimplePriceMatching) PlaceOrder(o types.SubmitOrder) (*types.Order, *types.Trade, error)
PlaceOrder returns the created order object, executed trade (if any) and error
type StateRecorder ¶ added in v1.33.0
type StateRecorder struct {
// contains filtered or unexported fields
}
func NewStateRecorder ¶ added in v1.33.0
func NewStateRecorder(outputDir string) *StateRecorder
func (*StateRecorder) Close ¶ added in v1.33.0
func (r *StateRecorder) Close() error
func (*StateRecorder) Manifests ¶ added in v1.33.0
func (r *StateRecorder) Manifests() Manifests
func (*StateRecorder) Scan ¶ added in v1.33.0
func (r *StateRecorder) Scan(instance Instance) error
func (*StateRecorder) Snapshot ¶ added in v1.33.0
func (r *StateRecorder) Snapshot() (int, error)
type SummaryReport ¶ added in v1.33.0
type SummaryReport struct { StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Sessions []string `json:"sessions"` Symbols []string `json:"symbols"` Intervals []types.Interval `json:"intervals"` InitialTotalBalances types.BalanceMap `json:"initialTotalBalances"` FinalTotalBalances types.BalanceMap `json:"finalTotalBalances"` InitialEquityValue fixedpoint.Value `json:"initialEquityValue"` FinalEquityValue fixedpoint.Value `json:"finalEquityValue"` // TotalProfit is the profit aggregated from the symbol reports TotalProfit fixedpoint.Value `json:"totalProfit,omitempty"` TotalUnrealizedProfit fixedpoint.Value `json:"totalUnrealizedProfit,omitempty"` TotalGrossProfit fixedpoint.Value `json:"totalGrossProfit,omitempty"` TotalGrossLoss fixedpoint.Value `json:"totalGrossLoss,omitempty"` SymbolReports []SessionSymbolReport `json:"symbolReports,omitempty"` Manifests Manifests `json:"manifests,omitempty"` }
SummaryReport is the summary of the back-test session
func ReadSummaryReport ¶ added in v1.33.0
func ReadSummaryReport(filename string) (*SummaryReport, error)