fix fee calculation

This commit is contained in:
c9s 2020-08-05 18:49:32 +08:00
parent c8849e76a1
commit 78be592fee

View File

@ -31,10 +31,11 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
var trades = c.Trades var trades = c.Trades
var bidVolume = 0.0 var bidVolume = 0.0
var bidAmount = 0.0 var bidAmount = 0.0
var bidFee = 0.0
var askVolume = 0.0 var askVolume = 0.0
var askFee = 0.0
var feeUSD = 0.0
var bidFeeUSD = 0.0
var feeRate = 0.0015 var feeRate = 0.0015
var currencyFees = map[string]float64{} var currencyFees = map[string]float64{}
@ -49,13 +50,21 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
// since we use USDT as the quote currency, we simply check if it matches the currency symbol // since we use USDT as the quote currency, we simply check if it matches the currency symbol
if strings.HasPrefix(trade.Symbol, trade.FeeCurrency) { if strings.HasPrefix(trade.Symbol, trade.FeeCurrency) {
bidVolume -= trade.Fee bidVolume -= trade.Fee
bidFee += trade.Price * trade.Fee feeUSD += trade.Price * trade.Fee
if trade.IsBuyer {
bidFeeUSD += trade.Price * trade.Fee
}
} else if trade.FeeCurrency == "USDT" { } else if trade.FeeCurrency == "USDT" {
bidFee += trade.Fee feeUSD += trade.Fee
if trade.IsBuyer {
bidFeeUSD += trade.Fee
}
} }
} else if trade.FeeCurrency == c.TradingFeeCurrency { } else {
bidVolume -= trade.Fee if trade.FeeCurrency == c.TradingFeeCurrency {
bidVolume -= trade.Fee
}
} }
if _, ok := currencyFees[trade.FeeCurrency]; !ok { if _, ok := currencyFees[trade.FeeCurrency]; !ok {
@ -64,9 +73,9 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
currencyFees[trade.FeeCurrency] += trade.Fee currencyFees[trade.FeeCurrency] += trade.Fee
} }
log.Infof("average bid price = (total amount %f + total fee %f) / volume %f", bidAmount, bidFee, bidVolume) log.Infof("average bid price = (total amount %f + total feeUSD %f) / volume %f", bidAmount, bidFeeUSD, bidVolume)
profit := 0.0 profit := 0.0
averageBidPrice := (bidAmount + bidFee) / bidVolume averageBidPrice := (bidAmount + bidFeeUSD) / bidVolume
for _, t := range trades { for _, t := range trades {
if t.Symbol != c.Symbol { if t.Symbol != c.Symbol {
@ -79,19 +88,11 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
profit += (t.Price - averageBidPrice) * t.Quantity profit += (t.Price - averageBidPrice) * t.Quantity
askVolume += t.Quantity askVolume += t.Quantity
// since we use USDT as the quote currency, we simply check if it matches the currency symbol
if strings.HasPrefix(t.Symbol, t.FeeCurrency) {
askFee += t.Price * t.Fee
} else if t.FeeCurrency == "USDT" {
askFee += t.Fee
}
} }
profit -= askFee profit -= feeUSD
stock := bidVolume - askVolume stock := bidVolume - askVolume
futureFee := 0.0
if stock > 0 { if stock > 0 {
_ = feeRate _ = feeRate
// stockFee := c.CurrentPrice * feeRate * stock // stockFee := c.CurrentPrice * feeRate * stock
@ -99,8 +100,6 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
// futureFee += stockFee // futureFee += stockFee
} }
fee := bidFee + askFee + futureFee
return &ProfitAndLossReport{ return &ProfitAndLossReport{
Symbol: c.Symbol, Symbol: c.Symbol,
StartTime: c.StartTime, StartTime: c.StartTime,
@ -110,11 +109,11 @@ func (c *ProfitAndLossCalculator) Calculate() *ProfitAndLossReport {
BidVolume: bidVolume, BidVolume: bidVolume,
AskVolume: askVolume, AskVolume: askVolume,
Stock: stock, Stock: stock,
Profit: profit, Profit: profit,
AverageBidPrice: averageBidPrice, AverageBidCost: averageBidPrice,
FeeUSD: fee, FeeUSD: feeUSD,
CurrencyFees: currencyFees, CurrencyFees: currencyFees,
} }
} }
@ -123,22 +122,23 @@ type ProfitAndLossReport struct {
StartTime time.Time StartTime time.Time
Symbol string Symbol string
NumTrades int NumTrades int
Profit float64 Profit float64
AverageBidPrice float64 AverageBidCost float64
BidVolume float64 BidVolume float64
AskVolume float64 AskVolume float64
FeeUSD float64 FeeUSD float64
Stock float64 Stock float64
CurrencyFees map[string]float64 CurrencyFees map[string]float64
} }
func (report ProfitAndLossReport) Print() { func (report ProfitAndLossReport) Print() {
log.Infof("trades since: %v", report.StartTime) log.Infof("trades since: %v", report.StartTime)
log.Infof("average bid price: %s", USD.FormatMoneyFloat64(report.AverageBidPrice)) log.Infof("average bid cost: %s", USD.FormatMoneyFloat64(report.AverageBidCost))
log.Infof("total bid volume: %f", report.BidVolume) log.Infof("total bid volume: %f", report.BidVolume)
log.Infof("total ask volume: %f", report.AskVolume) log.Infof("total ask volume: %f", report.AskVolume)
log.Infof("stock: %f", report.Stock) log.Infof("stock: %f", report.Stock)
log.Infof("fee (USD): %f", report.FeeUSD)
log.Infof("current price: %s", USD.FormatMoneyFloat64(report.CurrentPrice)) log.Infof("current price: %s", USD.FormatMoneyFloat64(report.CurrentPrice))
log.Infof("profit: %s", USD.FormatMoneyFloat64(report.Profit)) log.Infof("profit: %s", USD.FormatMoneyFloat64(report.Profit))
log.Infof("currency fees:") log.Infof("currency fees:")
@ -170,8 +170,9 @@ func (report ProfitAndLossReport) SlackAttachment() slack.Attachment {
Fields: []slack.AttachmentField{ Fields: []slack.AttachmentField{
{Title: "Symbol", Value: report.Symbol, Short: true}, {Title: "Symbol", Value: report.Symbol, Short: true},
{Title: "Profit", Value: USD.FormatMoney(report.Profit), Short: true}, {Title: "Profit", Value: USD.FormatMoney(report.Profit), Short: true},
{Title: "Fee (USD)", Value: USD.FormatMoney(report.FeeUSD), Short: true},
{Title: "Current Price", Value: USD.FormatMoney(report.CurrentPrice), Short: true}, {Title: "Current Price", Value: USD.FormatMoney(report.CurrentPrice), Short: true},
{Title: "Average Bid Price", Value: USD.FormatMoney(report.AverageBidPrice), Short: true}, {Title: "Average Bid Cost", Value: USD.FormatMoney(report.AverageBidCost), Short: true},
{Title: "Number of Trades", Value: strconv.Itoa(report.NumTrades), Short: true}, {Title: "Number of Trades", Value: strconv.Itoa(report.NumTrades), Short: true},
{Title: "Stock", Value: strconv.FormatFloat(report.Stock, 'f', 8, 64), Short: true}, {Title: "Stock", Value: strconv.FormatFloat(report.Stock, 'f', 8, 64), Short: true},
}, },