backtest

package
v1.60.3 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2024 License: AGPL-3.0 Imports: 29 Imported by: 3

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:

  1. 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.

  2. 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:

  1. 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

View Source
const DateFormat = "2006-01-02T15:04"
View Source
const FeeToken = "FEE"

FeeToken is used to simulate the exchange platform fee token This is to ease the back-testing environment for closing positions.

View Source
const SessionTimeFormat = "2006-01-02T15_04"

Variables

View Source
var ErrEmptyOrderType = errors.New("order type can not be empty string")
View Source
var ErrNegativeQuantity = errors.New("order quantity can not be negative")
View Source
var ErrUnimplemented = errors.New("unimplemented method")
View Source
var ErrZeroQuantity = errors.New("order quantity can not be zero")
View Source
var FS = &fs{}

Functions

func AddReportIndexRun added in v1.33.0

func AddReportIndexRun(outputDirectory string, run Run) error

func CollectSubscriptionIntervals added in v1.43.0

func CollectSubscriptionIntervals(environ *bbgo.Environment) (allKLineIntervals map[types.Interval]struct{}, requiredInterval types.Interval, backTestIntervals []types.Interval)

func FormatSessionName added in v1.33.0

func FormatSessionName(sessions []string, symbols []string, startTime, endTime time.Time) string

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 (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) error

func (*Exchange) CloseMarketData added in v1.28.0

func (e *Exchange) CloseMarketData() error

func (*Exchange) ConsumeKLine added in v1.28.0

func (e *Exchange) ConsumeKLine(k types.KLine, requiredInterval types.Interval)

func (*Exchange) Name

func (e *Exchange) Name() types.ExchangeName

func (*Exchange) NewStream

func (e *Exchange) NewStream() types.Stream

func (*Exchange) PlatformFeeCurrency

func (e *Exchange) PlatformFeeCurrency() string

func (*Exchange) QueryAccount

func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error)

func (*Exchange) QueryAccountBalances

func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error)

func (*Exchange) QueryClosedOrders

func (e *Exchange) QueryClosedOrders(
	ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64,
) (orders []types.Order, err error)

func (*Exchange) QueryDepositHistory

func (e *Exchange) QueryDepositHistory(
	ctx context.Context, asset string, since, until time.Time,
) (allDeposits []types.Deposit, err error)

func (*Exchange) QueryKLines

func (e *Exchange) QueryKLines(
	ctx context.Context, symbol string, interval types.Interval, options types.KLineQueryOptions,
) ([]types.KLine, error)

func (*Exchange) QueryMarkets

func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error)

func (*Exchange) QueryOpenOrders

func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error)

func (*Exchange) QueryOrder added in v1.36.0

func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.Order, error)

func (*Exchange) QueryTicker added in v1.11.1

func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error)

func (*Exchange) QueryTickers added in v1.11.0

func (e *Exchange) QueryTickers(ctx context.Context, symbol ...string) (map[string]types.Ticker, error)

func (*Exchange) QueryTrades

func (e *Exchange) QueryTrades(
	ctx context.Context, symbol string, options *types.TradeQueryOptions,
) ([]types.Trade, error)

func (*Exchange) QueryWithdrawHistory

func (e *Exchange) QueryWithdrawHistory(
	ctx context.Context, asset string, since, until time.Time,
) (allWithdraws []types.Withdraw, err error)

func (*Exchange) SubmitOrder added in v1.40.3

func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (createdOrder *types.Order, err error)

func (*Exchange) SubscribeMarketData added in v1.33.0

func (e *Exchange) SubscribeMarketData(
	startTime, endTime time.Time, requiredInterval types.Interval, extraIntervals ...types.Interval,
) (chan types.KLine, error)

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

func InitializeExchangeSources(sessions map[string]*bbgo.ExchangeSession, startTime, endTime time.Time, requiredInterval types.Interval, extraIntervals ...types.Interval) (exchangeSources []*ExchangeDataSource, err error)

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 Instance added in v1.33.0

type Instance interface {
	ID() string
	InstanceID() string
}

type InstancePropertyIndex added in v1.33.0

type InstancePropertyIndex struct {
	ID         string
	InstanceID string
	Property   string
}

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

func (*KLineDumper) Record added in v1.33.0

func (d *KLineDumper) Record(k types.KLine) error

type ManifestEntry added in v1.33.0

type ManifestEntry struct {
	Type             string `json:"type"`
	Filename         string `json:"filename"`
	StrategyID       string `json:"strategyID"`
	StrategyInstance string `json:"strategyInstance"`
	StrategyProperty string `json:"strategyProperty"`
}

type Manifests added in v1.33.0

type Manifests map[InstancePropertyIndex]string

func (Manifests) MarshalJSON added in v1.33.0

func (m Manifests) MarshalJSON() ([]byte, error)

func (*Manifests) UnmarshalJSON added in v1.33.0

func (m *Manifests) UnmarshalJSON(j []byte) error

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 Run added in v1.33.0

type Run struct {
	ID     string       `json:"id"`
	Config *bbgo.Config `json:"config"`
	Time   time.Time    `json:"time"`
}

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 (m *SimplePriceMatching) CancelOrder(o types.Order) (types.Order, error)

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

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)

Jump to

Keyboard shortcuts

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