mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 00:05:15 +00:00
support json output for backtesting
This commit is contained in:
parent
1e151a170a
commit
474be4e815
|
@ -21,12 +21,13 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
|||
|
||||
if len(trades) == 0 {
|
||||
return &AverageCostPnlReport{
|
||||
Symbol: symbol,
|
||||
CurrentPrice: currentPrice,
|
||||
NumTrades: 0,
|
||||
BuyVolume: bidVolume,
|
||||
SellVolume: askVolume,
|
||||
FeeInUSD: feeUSD,
|
||||
Symbol: symbol,
|
||||
Market: c.Market,
|
||||
LastPrice: currentPrice,
|
||||
NumTrades: 0,
|
||||
BuyVolume: bidVolume,
|
||||
SellVolume: askVolume,
|
||||
FeeInUSD: feeUSD,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +69,11 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
|||
|
||||
unrealizedProfit := (fixedpoint.NewFromFloat(currentPrice) - position.AverageCost).Mul(position.Base)
|
||||
return &AverageCostPnlReport{
|
||||
Symbol: symbol,
|
||||
CurrentPrice: currentPrice,
|
||||
NumTrades: len(trades),
|
||||
StartTime: time.Time(trades[0].Time),
|
||||
Symbol: symbol,
|
||||
Market: c.Market,
|
||||
LastPrice: currentPrice,
|
||||
NumTrades: len(trades),
|
||||
StartTime: time.Time(trades[0].Time),
|
||||
|
||||
BuyVolume: bidVolume,
|
||||
SellVolume: askVolume,
|
||||
|
@ -80,7 +82,7 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
|||
Profit: totalProfit,
|
||||
NetProfit: totalNetProfit,
|
||||
UnrealizedProfit: unrealizedProfit,
|
||||
AverageBidCost: position.AverageCost.Float64(),
|
||||
AverageCost: position.AverageCost.Float64(),
|
||||
FeeInUSD: (totalProfit - totalNetProfit).Float64(),
|
||||
CurrencyFees: currencyFees,
|
||||
}
|
||||
|
|
|
@ -3,8 +3,11 @@ package cmd
|
|||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -28,6 +31,7 @@ func init() {
|
|||
BacktestCmd.Flags().CountP("verbose", "v", "verbose level")
|
||||
BacktestCmd.Flags().String("config", "config/bbgo.yaml", "strategy config file")
|
||||
BacktestCmd.Flags().Bool("force", false, "force execution without confirm")
|
||||
BacktestCmd.Flags().String("output", "", "the report output directory")
|
||||
RootCmd.AddCommand(BacktestCmd)
|
||||
}
|
||||
|
||||
|
@ -65,6 +69,12 @@ var BacktestCmd = &cobra.Command{
|
|||
return err
|
||||
}
|
||||
|
||||
outputDirectory, err := cmd.Flags().GetString("output")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonOutputEnabled := len(outputDirectory) > 0
|
||||
|
||||
syncOnly, err := cmd.Flags().GetBool("sync-only")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -270,7 +280,7 @@ var BacktestCmd = &cobra.Command{
|
|||
|
||||
calculator := &pnl.AverageCostCalculator{
|
||||
TradingFeeCurrency: backtestExchange.PlatformFeeCurrency(),
|
||||
Market: market,
|
||||
Market: market,
|
||||
}
|
||||
|
||||
startPrice, ok := session.StartPrice(symbol)
|
||||
|
@ -278,14 +288,14 @@ var BacktestCmd = &cobra.Command{
|
|||
return fmt.Errorf("start price not found: %s", symbol)
|
||||
}
|
||||
|
||||
log.Infof("%s PROFIT AND LOSS REPORT", symbol)
|
||||
log.Infof("===============================================")
|
||||
|
||||
lastPrice, ok := session.LastPrice(symbol)
|
||||
if !ok {
|
||||
return fmt.Errorf("last price not found: %s", symbol)
|
||||
}
|
||||
|
||||
log.Infof("%s PROFIT AND LOSS REPORT", symbol)
|
||||
log.Infof("===============================================")
|
||||
|
||||
report := calculator.Calculate(symbol, trades.Trades, lastPrice)
|
||||
report.Print()
|
||||
|
||||
|
@ -298,6 +308,29 @@ var BacktestCmd = &cobra.Command{
|
|||
log.Infof("FINAL BALANCES:")
|
||||
finalBalances.Print()
|
||||
|
||||
if jsonOutputEnabled {
|
||||
result := struct {
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
PnLReport *pnl.AverageCostPnlReport `json:"pnlReport,omitempty"`
|
||||
InitialBalances types.BalanceMap `json:"initialBalances,omitempty"`
|
||||
FinalBalances types.BalanceMap `json:"finalBalances,omitempty"`
|
||||
}{
|
||||
Symbol: symbol,
|
||||
PnLReport: report,
|
||||
InitialBalances: initBalances,
|
||||
FinalBalances: finalBalances,
|
||||
}
|
||||
|
||||
jsonOutput, err := json.MarshalIndent(&result,"", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(outputDirectory, symbol + ".json"), jsonOutput, 0644) ; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if wantBaseAssetBaseline {
|
||||
initBaseAsset := inBaseAsset(initBalances, market, startPrice)
|
||||
finalBaseAsset := inBaseAsset(finalBalances, market, lastPrice)
|
||||
|
|
|
@ -3,10 +3,11 @@ package types
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/leekchan/accounting"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/leekchan/accounting"
|
||||
)
|
||||
|
||||
type Duration time.Duration
|
||||
|
@ -48,27 +49,27 @@ func (d *Duration) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
type Market struct {
|
||||
Symbol string
|
||||
LocalSymbol string // LocalSymbol is used for exchange's API
|
||||
Symbol string `json:"symbol"`
|
||||
LocalSymbol string `json:"localSymbol,omitempty" `// LocalSymbol is used for exchange's API
|
||||
|
||||
PricePrecision int
|
||||
VolumePrecision int
|
||||
QuoteCurrency string
|
||||
BaseCurrency string
|
||||
PricePrecision int `json:"pricePrecision,omitempty"`
|
||||
VolumePrecision int `json:"volumePrecision,omitempty"`
|
||||
QuoteCurrency string `json:"quoteCurrency,omitempty"`
|
||||
BaseCurrency string `json:"baseCurrency,omitempty"`
|
||||
|
||||
// The MIN_NOTIONAL filter defines the minimum notional value allowed for an order on a symbol.
|
||||
// An order's notional value is the price * quantity
|
||||
MinNotional float64
|
||||
MinAmount float64
|
||||
MinNotional float64 `json:"minNotional,omitempty"`
|
||||
MinAmount float64 `json:"minAmount,omitempty"`
|
||||
|
||||
// The LOT_SIZE filter defines the quantity
|
||||
MinQuantity float64
|
||||
MaxQuantity float64
|
||||
StepSize float64
|
||||
MinQuantity float64 `json:"minQuantity,omitempty"`
|
||||
MaxQuantity float64 `json:"maxQuantity,omitempty"`
|
||||
StepSize float64 `json:"stepSize,omitempty"`
|
||||
|
||||
MinPrice float64
|
||||
MaxPrice float64
|
||||
TickSize float64
|
||||
MinPrice float64 `json:"minPrice,omitempty"`
|
||||
MaxPrice float64 `json:"maxPrice,omitempty"`
|
||||
TickSize float64 `json:"tickSize,omitempty"`
|
||||
}
|
||||
|
||||
func (m Market) BaseCurrencyFormatter() *accounting.Accounting {
|
||||
|
|
Loading…
Reference in New Issue
Block a user