bbgo_origin/pkg/accounting/pnl/avg_cost.go

102 lines
2.4 KiB
Go
Raw Normal View History

package pnl
import (
2021-02-06 04:32:21 +00:00
"time"
log "github.com/sirupsen/logrus"
2021-12-04 18:16:48 +00:00
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type AverageCostCalculator struct {
TradingFeeCurrency string
2021-12-04 18:16:48 +00:00
Market types.Market
}
2020-10-22 07:57:50 +00:00
func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, currentPrice float64) *AverageCostPnlReport {
// copy trades, so that we can truncate it.
var bidVolume = 0.0
var askVolume = 0.0
var feeUSD = 0.0
2020-10-24 08:32:54 +00:00
if len(trades) == 0 {
return &AverageCostPnlReport{
2021-12-05 17:05:33 +00:00
Symbol: symbol,
Market: c.Market,
LastPrice: currentPrice,
NumTrades: 0,
BuyVolume: bidVolume,
SellVolume: askVolume,
FeeInUSD: feeUSD,
2020-10-24 08:32:54 +00:00
}
}
var currencyFees = map[string]float64{}
var position = types.NewPositionFromMarket(c.Market)
position.SetFeeRate(types.ExchangeFee{
2021-12-04 18:16:48 +00:00
// binance vip 0 uses 0.075%
MakerFeeRate: fixedpoint.NewFromFloat(0.075 * 0.01),
TakerFeeRate: fixedpoint.NewFromFloat(0.075 * 0.01),
})
// TODO: configure the exchange fee rate here later
// position.SetExchangeFeeRate()
var totalProfit fixedpoint.Value
var totalNetProfit fixedpoint.Value
var tradeIDs = map[uint64]types.Trade{}
for _, trade := range trades {
if _, exists := tradeIDs[trade.ID]; exists {
log.Warnf("duplicated trade: %+v", trade)
continue
}
if trade.Symbol != symbol {
continue
}
profit, netProfit, madeProfit := position.AddTrade(trade)
if madeProfit {
totalProfit += profit
totalNetProfit += netProfit
}
if trade.IsBuyer {
bidVolume += trade.Quantity
} else {
askVolume += trade.Quantity
}
if _, ok := currencyFees[trade.FeeCurrency]; !ok {
2021-12-04 18:16:48 +00:00
currencyFees[trade.FeeCurrency] = trade.Fee
} else {
currencyFees[trade.FeeCurrency] += trade.Fee
}
tradeIDs[trade.ID] = trade
}
unrealizedProfit := (fixedpoint.NewFromFloat(currentPrice) - position.AverageCost).Mul(position.GetBase())
2020-10-16 02:21:37 +00:00
return &AverageCostPnlReport{
2021-12-05 17:05:33 +00:00
Symbol: symbol,
Market: c.Market,
LastPrice: currentPrice,
NumTrades: len(trades),
StartTime: time.Time(trades[0].Time),
2020-11-10 06:18:27 +00:00
BuyVolume: bidVolume,
SellVolume: askVolume,
Stock: position.GetBase().Float64(),
2021-12-04 18:16:48 +00:00
Profit: totalProfit,
NetProfit: totalNetProfit,
UnrealizedProfit: unrealizedProfit,
2021-12-05 17:05:33 +00:00
AverageCost: position.AverageCost.Float64(),
2021-12-04 18:16:48 +00:00
FeeInUSD: (totalProfit - totalNetProfit).Float64(),
CurrencyFees: currencyFees,
}
}