mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
refactor report structure and rewrite manifest paths
This commit is contained in:
parent
06e2902e5e
commit
b51d6b4ba1
|
@ -39,13 +39,13 @@ type SummaryReport struct {
|
|||
FinalTotalBalances types.BalanceMap `json:"finalTotalBalances"`
|
||||
|
||||
SymbolReports []SessionSymbolReport `json:"symbolReports,omitempty"`
|
||||
|
||||
Manifests Manifests `json:"manifests,omitempty"`
|
||||
}
|
||||
|
||||
// SessionSymbolReport is the report per exchange session
|
||||
// trades are merged, collected and re-calculated
|
||||
type SessionSymbolReport struct {
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
Exchange types.ExchangeName `json:"exchange"`
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
Market types.Market `json:"market"`
|
||||
|
@ -155,7 +155,7 @@ func AddReportIndexRun(outputDirectory string, run Run) error {
|
|||
if err := fileLock.Unlock(); err != nil {
|
||||
log.WithError(err).Errorf("report index file lock error: %s", lockFile)
|
||||
}
|
||||
if err := os.Remove(lockFile) ; err != nil {
|
||||
if err := os.Remove(lockFile); err != nil {
|
||||
log.WithError(err).Errorf("can not remove lock file: %s", lockFile)
|
||||
}
|
||||
}()
|
||||
|
|
|
@ -308,8 +308,12 @@ var BacktestCmd = &cobra.Command{
|
|||
err = trader.IterateStrategies(func(st bbgo.StrategyID) error {
|
||||
return stateRecorder.Scan(st.(backtest.Instance))
|
||||
})
|
||||
manifests = stateRecorder.Manifests()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
manifests = stateRecorder.Manifests()
|
||||
manifests, err = rewriteManifestPaths(manifests, reportDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -443,15 +447,10 @@ var BacktestCmd = &cobra.Command{
|
|||
// put the logger back to print the pnl
|
||||
log.SetLevel(log.InfoLevel)
|
||||
|
||||
color.Green("BACK-TEST REPORT")
|
||||
color.Green("===============================================\n")
|
||||
color.Green("START TIME: %s\n", startTime.Format(time.RFC1123))
|
||||
color.Green("END TIME: %s\n", endTime.Format(time.RFC1123))
|
||||
|
||||
// aggregate total balances
|
||||
initTotalBalances := types.BalanceMap{}
|
||||
finalTotalBalances := types.BalanceMap{}
|
||||
sessionNames := []string{}
|
||||
var sessionNames []string
|
||||
for _, session := range environ.Sessions() {
|
||||
sessionNames = append(sessionNames, session.Name)
|
||||
accountConfig := userConfig.Backtest.GetAccount(session.Name)
|
||||
|
@ -461,6 +460,11 @@ var BacktestCmd = &cobra.Command{
|
|||
finalBalances := session.GetAccount().Balances()
|
||||
finalTotalBalances = finalTotalBalances.Add(finalBalances)
|
||||
}
|
||||
|
||||
color.Green("BACK-TEST REPORT")
|
||||
color.Green("===============================================\n")
|
||||
color.Green("START TIME: %s\n", startTime.Format(time.RFC1123))
|
||||
color.Green("END TIME: %s\n", endTime.Format(time.RFC1123))
|
||||
color.Green("INITIAL TOTAL BALANCE: %v\n", initTotalBalances)
|
||||
color.Green("FINAL TOTAL BALANCE: %v\n", finalTotalBalances)
|
||||
|
||||
|
@ -470,60 +474,17 @@ var BacktestCmd = &cobra.Command{
|
|||
Sessions: sessionNames,
|
||||
InitialTotalBalances: initTotalBalances,
|
||||
FinalTotalBalances: finalTotalBalances,
|
||||
Manifests: manifests,
|
||||
}
|
||||
_ = summaryReport
|
||||
|
||||
for _, session := range environ.Sessions() {
|
||||
backtestExchange, ok := session.Exchange.(*backtest.Exchange)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected error, exchange instance is not a backtest exchange")
|
||||
}
|
||||
|
||||
// per symbol report
|
||||
exchangeName := session.Exchange.Name().String()
|
||||
|
||||
for symbol, trades := range session.Trades {
|
||||
market, ok := session.Market(symbol)
|
||||
if !ok {
|
||||
return fmt.Errorf("market not found: %s, %s", symbol, exchangeName)
|
||||
symbolReport, err := createSymbolReport(userConfig, session, symbol, trades.Trades)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
calculator := &pnl.AverageCostCalculator{
|
||||
TradingFeeCurrency: backtestExchange.PlatformFeeCurrency(),
|
||||
Market: market,
|
||||
}
|
||||
|
||||
startPrice, ok := session.StartPrice(symbol)
|
||||
if !ok {
|
||||
return fmt.Errorf("start price not found: %s, %s. run --sync first", symbol, exchangeName)
|
||||
}
|
||||
|
||||
lastPrice, ok := session.LastPrice(symbol)
|
||||
if !ok {
|
||||
return fmt.Errorf("last price not found: %s, %s", symbol, exchangeName)
|
||||
}
|
||||
|
||||
report := calculator.Calculate(symbol, trades.Trades, lastPrice)
|
||||
|
||||
accountConfig := userConfig.Backtest.GetAccount(exchangeName)
|
||||
initBalances := accountConfig.Balances.BalanceMap()
|
||||
finalBalances := session.GetAccount().Balances()
|
||||
|
||||
symbolReport := backtest.SessionSymbolReport{
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
Exchange: session.Exchange.Name(),
|
||||
Symbol: symbol,
|
||||
Market: market,
|
||||
LastPrice: lastPrice,
|
||||
StartPrice: startPrice,
|
||||
PnL: report,
|
||||
InitialBalances: initBalances,
|
||||
FinalBalances: finalBalances,
|
||||
Manifests: manifests,
|
||||
}
|
||||
summaryReport.SymbolReports = append(summaryReport.SymbolReports, symbolReport)
|
||||
|
||||
summaryReport.SymbolReports = append(summaryReport.SymbolReports, *symbolReport)
|
||||
|
||||
// write report to a file
|
||||
if generatingReport {
|
||||
|
@ -534,11 +495,15 @@ var BacktestCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
symbolReport.Print(wantBaseAssetBaseline)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if generatingReport && reportFileInSubDir {
|
||||
summaryReportFile := filepath.Join(reportDir, "summary.json")
|
||||
if err := util.WriteJsonFile(summaryReportFile, summaryReport); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// append report index
|
||||
if err := backtest.AddReportIndexRun(outputDirectory, backtest.Run{
|
||||
ID: runID,
|
||||
|
@ -553,6 +518,50 @@ var BacktestCmd = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func createSymbolReport(userConfig *bbgo.Config, session *bbgo.ExchangeSession, symbol string, trades []types.Trade) (*backtest.SessionSymbolReport, error) {
|
||||
backtestExchange, ok := session.Exchange.(*backtest.Exchange)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected error, exchange instance is not a backtest exchange")
|
||||
}
|
||||
|
||||
market, ok := session.Market(symbol)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("market not found: %s, %s", symbol, session.Exchange.Name())
|
||||
}
|
||||
|
||||
startPrice, ok := session.StartPrice(symbol)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("start price not found: %s, %s. run --sync first", symbol, session.Exchange.Name())
|
||||
}
|
||||
|
||||
lastPrice, ok := session.LastPrice(symbol)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("last price not found: %s, %s", symbol, session.Exchange.Name())
|
||||
}
|
||||
|
||||
calculator := &pnl.AverageCostCalculator{
|
||||
TradingFeeCurrency: backtestExchange.PlatformFeeCurrency(),
|
||||
Market: market,
|
||||
}
|
||||
|
||||
report := calculator.Calculate(symbol, trades, lastPrice)
|
||||
accountConfig := userConfig.Backtest.GetAccount(session.Exchange.Name().String())
|
||||
initBalances := accountConfig.Balances.BalanceMap()
|
||||
finalBalances := session.GetAccount().Balances()
|
||||
symbolReport := backtest.SessionSymbolReport{
|
||||
Exchange: session.Exchange.Name(),
|
||||
Symbol: symbol,
|
||||
Market: market,
|
||||
LastPrice: lastPrice,
|
||||
StartPrice: startPrice,
|
||||
PnL: report,
|
||||
InitialBalances: initBalances,
|
||||
FinalBalances: finalBalances,
|
||||
// Manifests: manifests,
|
||||
}
|
||||
return &symbolReport, nil
|
||||
}
|
||||
|
||||
func verify(userConfig *bbgo.Config, backtestService *service.BacktestService, sourceExchanges map[types.ExchangeName]types.Exchange, startTime time.Time, verboseCnt int) error {
|
||||
for _, sourceExchange := range sourceExchanges {
|
||||
err := backtestService.Verify(userConfig.Backtest.Symbols, startTime, time.Now(), sourceExchange, verboseCnt)
|
||||
|
@ -644,6 +653,18 @@ func sync(ctx context.Context, userConfig *bbgo.Config, backtestService *service
|
|||
return nil
|
||||
}
|
||||
|
||||
func rewriteManifestPaths(manifests backtest.Manifests, basePath string) (backtest.Manifests, error) {
|
||||
var filterManifests = backtest.Manifests{}
|
||||
for k, m := range manifests {
|
||||
p, err := filepath.Rel(basePath, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filterManifests[k] = p
|
||||
}
|
||||
return filterManifests, nil
|
||||
}
|
||||
|
||||
func printSymbolReport(report backtest.SessionSymbolReport) {
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user