cmd/backtest: calculate performance in quote asset

This commit is contained in:
c9s 2022-02-01 00:54:55 +08:00
parent f96c2e6271
commit 82adff338e
2 changed files with 34 additions and 16 deletions

View File

@ -24,6 +24,15 @@ import (
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
type BackTestReport struct {
Symbol string `json:"symbol,omitempty"`
LastPrice float64 `json:"lastPrice,omitempty"`
StartPrice float64 `json:"startPrice,omitempty"`
PnLReport *pnl.AverageCostPnlReport `json:"pnlReport,omitempty"`
InitialBalances types.BalanceMap `json:"initialBalances,omitempty"`
FinalBalances types.BalanceMap `json:"finalBalances,omitempty"`
}
func init() { func init() {
BacktestCmd.Flags().String("exchange", "", "target exchange") BacktestCmd.Flags().String("exchange", "", "target exchange")
BacktestCmd.Flags().Bool("sync", false, "sync backtest data") BacktestCmd.Flags().Bool("sync", false, "sync backtest data")
@ -350,14 +359,7 @@ var BacktestCmd = &cobra.Command{
finalBalances.Print() finalBalances.Print()
if jsonOutputEnabled { if jsonOutputEnabled {
result := struct { result := BackTestReport{
Symbol string `json:"symbol,omitempty"`
LastPrice float64 `json:"lastPrice,omitempty"`
StartPrice float64 `json:"startPrice,omitempty"`
PnLReport *pnl.AverageCostPnlReport `json:"pnlReport,omitempty"`
InitialBalances types.BalanceMap `json:"initialBalances,omitempty"`
FinalBalances types.BalanceMap `json:"finalBalances,omitempty"`
}{
Symbol: symbol, Symbol: symbol,
LastPrice: lastPrice, LastPrice: lastPrice,
StartPrice: startPrice, StartPrice: startPrice,
@ -376,14 +378,24 @@ var BacktestCmd = &cobra.Command{
} }
} }
if wantBaseAssetBaseline { initQuoteAsset := inQuoteAsset(initBalances, market, startPrice)
initBaseAsset := inBaseAsset(initBalances, market, startPrice) finalQuoteAsset := inQuoteAsset(finalBalances, market, startPrice)
finalBaseAsset := inBaseAsset(finalBalances, market, lastPrice) log.Infof("INITIAL ASSET IN %s ~= %s %s (1 %s = %f)", market.QuoteCurrency, market.FormatQuantity(initQuoteAsset), market.QuoteCurrency, market.BaseCurrency, startPrice)
log.Infof("INITIAL ASSET ~= %s %s (1 %s = %f)", market.FormatQuantity(initBaseAsset), market.BaseCurrency, market.BaseCurrency, startPrice) log.Infof("FINAL ASSET IN %s ~= %s %s (1 %s = %f)", market.QuoteCurrency, market.FormatQuantity(finalQuoteAsset), market.QuoteCurrency, market.BaseCurrency, lastPrice)
log.Infof("FINAL ASSET ~= %s %s (1 %s = %f)", market.FormatQuantity(finalBaseAsset), market.BaseCurrency, market.BaseCurrency, lastPrice)
log.Infof("%s BASE ASSET PERFORMANCE: %.2f%% (= (%.2f - %.2f) / %.2f)", market.BaseCurrency, (finalBaseAsset-initBaseAsset)/initBaseAsset*100.0, finalBaseAsset, initBaseAsset, initBaseAsset) if finalQuoteAsset > initQuoteAsset {
log.Infof("%s PERFORMANCE: %.2f%% (= (%.2f - %.2f) / %.2f)", market.BaseCurrency, (lastPrice-startPrice)/startPrice*100.0, lastPrice, startPrice, startPrice) log.Infof("ASSET INCREASED %f %s (+%f%%)", finalQuoteAsset-initQuoteAsset, market.QuoteCurrency, (finalQuoteAsset-initQuoteAsset)/initQuoteAsset*100.0)
} else {
log.Infof("ASSET DECREASED %f %s (-%f%%)", finalQuoteAsset-initQuoteAsset, market.QuoteCurrency, (finalQuoteAsset-initQuoteAsset)/initQuoteAsset*100.0)
}
if wantBaseAssetBaseline {
// initBaseAsset := inBaseAsset(initBalances, market, startPrice)
// finalBaseAsset := inBaseAsset(finalBalances, market, lastPrice)
// log.Infof("INITIAL ASSET IN %s ~= %s %s (1 %s = %f)", market.BaseCurrency, market.FormatQuantity(initBaseAsset), market.BaseCurrency, market.BaseCurrency, startPrice)
// log.Infof("FINAL ASSET IN %s ~= %s %s (1 %s = %f)", market.BaseCurrency, market.FormatQuantity(finalBaseAsset), market.BaseCurrency, market.BaseCurrency, lastPrice)
log.Infof("%s BASE ASSET PERFORMANCE: %.2f%% (= (%.2f - %.2f) / %.2f)", market.BaseCurrency, (lastPrice-startPrice)/startPrice*100.0, lastPrice, startPrice, startPrice)
} }
} }
} }

View File

@ -9,10 +9,16 @@ import (
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
func inQuoteAsset(balances types.BalanceMap, market types.Market, price float64) float64 {
quote := balances[market.QuoteCurrency]
base := balances[market.BaseCurrency]
return base.Total().Float64()*price + quote.Total().Float64()
}
func inBaseAsset(balances types.BalanceMap, market types.Market, price float64) float64 { func inBaseAsset(balances types.BalanceMap, market types.Market, price float64) float64 {
quote := balances[market.QuoteCurrency] quote := balances[market.QuoteCurrency]
base := balances[market.BaseCurrency] base := balances[market.BaseCurrency]
return (base.Locked.Float64() + base.Available.Float64()) + ((quote.Locked.Float64() + quote.Available.Float64()) / price) return base.Total().Float64() + (quote.Total().Float64() / price)
} }
func newExchange(session string) (types.Exchange, error) { func newExchange(session string) (types.Exchange, error) {