mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 00:35:15 +00:00
backtest: add gross profit and gross loss fields
This commit is contained in:
parent
7d232f86b8
commit
a51f26e3a7
|
@ -19,6 +19,8 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
||||||
var bidVolume = fixedpoint.Zero
|
var bidVolume = fixedpoint.Zero
|
||||||
var askVolume = fixedpoint.Zero
|
var askVolume = fixedpoint.Zero
|
||||||
var feeUSD = fixedpoint.Zero
|
var feeUSD = fixedpoint.Zero
|
||||||
|
var grossProfit = fixedpoint.Zero
|
||||||
|
var grossLoss = fixedpoint.Zero
|
||||||
|
|
||||||
if len(trades) == 0 {
|
if len(trades) == 0 {
|
||||||
return &AverageCostPnlReport{
|
return &AverageCostPnlReport{
|
||||||
|
@ -64,6 +66,12 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
||||||
totalNetProfit = totalNetProfit.Add(netProfit)
|
totalNetProfit = totalNetProfit.Add(netProfit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if profit.Sign() > 0 {
|
||||||
|
grossProfit = grossProfit.Add(profit)
|
||||||
|
} else if profit.Sign() < 0 {
|
||||||
|
grossLoss = grossLoss.Add(profit)
|
||||||
|
}
|
||||||
|
|
||||||
if trade.IsBuyer {
|
if trade.IsBuyer {
|
||||||
bidVolume = bidVolume.Add(trade.Quantity)
|
bidVolume = bidVolume.Add(trade.Quantity)
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,8 +104,12 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c
|
||||||
Profit: totalProfit,
|
Profit: totalProfit,
|
||||||
NetProfit: totalNetProfit,
|
NetProfit: totalNetProfit,
|
||||||
UnrealizedProfit: unrealizedProfit,
|
UnrealizedProfit: unrealizedProfit,
|
||||||
AverageCost: position.AverageCost,
|
|
||||||
FeeInUSD: totalProfit.Sub(totalNetProfit),
|
GrossProfit: grossProfit,
|
||||||
CurrencyFees: currencyFees,
|
GrossLoss: grossLoss,
|
||||||
|
|
||||||
|
AverageCost: position.AverageCost,
|
||||||
|
FeeInUSD: totalProfit.Sub(totalNetProfit),
|
||||||
|
CurrencyFees: currencyFees,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,14 @@ type AverageCostPnlReport struct {
|
||||||
Symbol string `json:"symbol"`
|
Symbol string `json:"symbol"`
|
||||||
Market types.Market `json:"market"`
|
Market types.Market `json:"market"`
|
||||||
|
|
||||||
NumTrades int `json:"numTrades"`
|
NumTrades int `json:"numTrades"`
|
||||||
Profit fixedpoint.Value `json:"profit"`
|
Profit fixedpoint.Value `json:"profit"`
|
||||||
NetProfit fixedpoint.Value `json:"netProfit"`
|
UnrealizedProfit fixedpoint.Value `json:"unrealizedProfit"`
|
||||||
UnrealizedProfit fixedpoint.Value `json:"unrealizedProfit"`
|
|
||||||
|
NetProfit fixedpoint.Value `json:"netProfit"`
|
||||||
|
GrossProfit fixedpoint.Value `json:"grossProfit"`
|
||||||
|
GrossLoss fixedpoint.Value `json:"grossLoss"`
|
||||||
|
|
||||||
AverageCost fixedpoint.Value `json:"averageCost"`
|
AverageCost fixedpoint.Value `json:"averageCost"`
|
||||||
BuyVolume fixedpoint.Value `json:"buyVolume,omitempty"`
|
BuyVolume fixedpoint.Value `json:"buyVolume,omitempty"`
|
||||||
SellVolume fixedpoint.Value `json:"sellVolume,omitempty"`
|
SellVolume fixedpoint.Value `json:"sellVolume,omitempty"`
|
||||||
|
|
|
@ -39,10 +39,16 @@ type SummaryReport struct {
|
||||||
InitialTotalBalances types.BalanceMap `json:"initialTotalBalances"`
|
InitialTotalBalances types.BalanceMap `json:"initialTotalBalances"`
|
||||||
FinalTotalBalances types.BalanceMap `json:"finalTotalBalances"`
|
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 is the profit aggregated from the symbol reports
|
||||||
TotalProfit fixedpoint.Value `json:"totalProfit,omitempty"`
|
TotalProfit fixedpoint.Value `json:"totalProfit,omitempty"`
|
||||||
TotalUnrealizedProfit fixedpoint.Value `json:"totalUnrealizedProfit,omitempty"`
|
TotalUnrealizedProfit fixedpoint.Value `json:"totalUnrealizedProfit,omitempty"`
|
||||||
|
|
||||||
|
TotalGrossProfit fixedpoint.Value `json:"totalGrossProfit,omitempty"`
|
||||||
|
TotalGrossLoss fixedpoint.Value `json:"totalGrossLoss,omitempty"`
|
||||||
|
|
||||||
SymbolReports []SessionSymbolReport `json:"symbolReports,omitempty"`
|
SymbolReports []SessionSymbolReport `json:"symbolReports,omitempty"`
|
||||||
|
|
||||||
Manifests Manifests `json:"manifests,omitempty"`
|
Manifests Manifests `json:"manifests,omitempty"`
|
||||||
|
@ -75,13 +81,21 @@ type SessionSymbolReport struct {
|
||||||
Manifests Manifests `json:"manifests,omitempty"`
|
Manifests Manifests `json:"manifests,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *SessionSymbolReport) InitialEquityValue() fixedpoint.Value {
|
||||||
|
return InQuoteAsset(r.InitialBalances, r.Market, r.StartPrice)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SessionSymbolReport) FinalEquityValue() fixedpoint.Value {
|
||||||
|
return InQuoteAsset(r.FinalBalances, r.Market, r.StartPrice)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *SessionSymbolReport) Print(wantBaseAssetBaseline bool) {
|
func (r *SessionSymbolReport) Print(wantBaseAssetBaseline bool) {
|
||||||
color.Green("%s %s PROFIT AND LOSS REPORT", r.Exchange, r.Symbol)
|
color.Green("%s %s PROFIT AND LOSS REPORT", r.Exchange, r.Symbol)
|
||||||
color.Green("===============================================")
|
color.Green("===============================================")
|
||||||
r.PnL.Print()
|
r.PnL.Print()
|
||||||
|
|
||||||
initQuoteAsset := inQuoteAsset(r.InitialBalances, r.Market, r.StartPrice)
|
initQuoteAsset := r.InitialEquityValue()
|
||||||
finalQuoteAsset := inQuoteAsset(r.FinalBalances, r.Market, r.LastPrice)
|
finalQuoteAsset := r.FinalEquityValue()
|
||||||
color.Green("INITIAL ASSET IN %s ~= %s %s (1 %s = %v)", r.Market.QuoteCurrency, r.Market.FormatQuantity(initQuoteAsset), r.Market.QuoteCurrency, r.Market.BaseCurrency, r.StartPrice)
|
color.Green("INITIAL ASSET IN %s ~= %s %s (1 %s = %v)", r.Market.QuoteCurrency, r.Market.FormatQuantity(initQuoteAsset), r.Market.QuoteCurrency, r.Market.BaseCurrency, r.StartPrice)
|
||||||
color.Green("FINAL ASSET IN %s ~= %s %s (1 %s = %v)", r.Market.QuoteCurrency, r.Market.FormatQuantity(finalQuoteAsset), r.Market.QuoteCurrency, r.Market.BaseCurrency, r.LastPrice)
|
color.Green("FINAL ASSET IN %s ~= %s %s (1 %s = %v)", r.Market.QuoteCurrency, r.Market.FormatQuantity(finalQuoteAsset), r.Market.QuoteCurrency, r.Market.BaseCurrency, r.LastPrice)
|
||||||
|
|
||||||
|
@ -186,8 +200,8 @@ func AddReportIndexRun(outputDirectory string, run Run) error {
|
||||||
return WriteReportIndex(outputDirectory, reportIndex)
|
return WriteReportIndex(outputDirectory, reportIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// inQuoteAsset converts all balances in quote asset
|
// InQuoteAsset converts all balances in quote asset
|
||||||
func inQuoteAsset(balances types.BalanceMap, market types.Market, price fixedpoint.Value) fixedpoint.Value {
|
func InQuoteAsset(balances types.BalanceMap, market types.Market, price fixedpoint.Value) fixedpoint.Value {
|
||||||
quote := balances[market.QuoteCurrency]
|
quote := balances[market.QuoteCurrency]
|
||||||
base := balances[market.BaseCurrency]
|
base := balances[market.BaseCurrency]
|
||||||
return base.Total().Mul(price).Add(quote.Total())
|
return base.Total().Mul(price).Add(quote.Total())
|
||||||
|
|
|
@ -493,7 +493,6 @@ var BacktestCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, session := range environ.Sessions() {
|
for _, session := range environ.Sessions() {
|
||||||
|
|
||||||
for symbol, trades := range session.Trades {
|
for symbol, trades := range session.Trades {
|
||||||
symbolReport, err := createSymbolReport(userConfig, session, symbol, trades.Trades)
|
symbolReport, err := createSymbolReport(userConfig, session, symbol, trades.Trades)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -504,6 +503,10 @@ var BacktestCmd = &cobra.Command{
|
||||||
summaryReport.SymbolReports = append(summaryReport.SymbolReports, *symbolReport)
|
summaryReport.SymbolReports = append(summaryReport.SymbolReports, *symbolReport)
|
||||||
summaryReport.TotalProfit = symbolReport.PnL.Profit
|
summaryReport.TotalProfit = symbolReport.PnL.Profit
|
||||||
summaryReport.TotalUnrealizedProfit = symbolReport.PnL.UnrealizedProfit
|
summaryReport.TotalUnrealizedProfit = symbolReport.PnL.UnrealizedProfit
|
||||||
|
summaryReport.InitialEquityValue = summaryReport.InitialEquityValue.Add(symbolReport.InitialEquityValue())
|
||||||
|
summaryReport.FinalEquityValue = summaryReport.FinalEquityValue.Add(symbolReport.FinalEquityValue())
|
||||||
|
summaryReport.TotalGrossProfit.Add(symbolReport.PnL.GrossProfit)
|
||||||
|
summaryReport.TotalGrossLoss.Add(symbolReport.PnL.GrossLoss)
|
||||||
|
|
||||||
// write report to a file
|
// write report to a file
|
||||||
if generatingReport {
|
if generatingReport {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user