mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
separate net profit and profit
This commit is contained in:
parent
20f02886de
commit
cca3284140
|
@ -107,18 +107,19 @@ func (p *Position) BindStream(stream types.Stream) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Position) AddTrades(trades []types.Trade) (fixedpoint.Value, bool) {
|
func (p *Position) AddTrades(trades []types.Trade) (fixedpoint.Value, fixedpoint.Value, bool) {
|
||||||
var totalProfitAmount fixedpoint.Value
|
var totalProfitAmount, totalNetProfit fixedpoint.Value
|
||||||
for _, trade := range trades {
|
for _, trade := range trades {
|
||||||
if profitAmount, profit := p.AddTrade(trade); profit {
|
if profit, netProfit, madeProfit := p.AddTrade(trade); madeProfit {
|
||||||
totalProfitAmount += profitAmount
|
totalProfitAmount += profit
|
||||||
|
totalNetProfit += netProfit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalProfitAmount, totalProfitAmount != 0
|
return totalProfitAmount, totalNetProfit, totalProfitAmount != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Position) AddTrade(t types.Trade) (fixedpoint.Value, bool) {
|
func (p *Position) AddTrade(t types.Trade) (profit fixedpoint.Value, netProfit fixedpoint.Value, madeProfit bool) {
|
||||||
price := fixedpoint.NewFromFloat(t.Price)
|
price := fixedpoint.NewFromFloat(t.Price)
|
||||||
quantity := fixedpoint.NewFromFloat(t.Quantity)
|
quantity := fixedpoint.NewFromFloat(t.Quantity)
|
||||||
quoteQuantity := fixedpoint.NewFromFloat(t.QuoteQuantity)
|
quoteQuantity := fixedpoint.NewFromFloat(t.QuoteQuantity)
|
||||||
|
@ -158,16 +159,19 @@ func (p *Position) AddTrade(t types.Trade) (fixedpoint.Value, bool) {
|
||||||
if p.Base < 0 {
|
if p.Base < 0 {
|
||||||
// handling short-to-long position
|
// handling short-to-long position
|
||||||
if p.Base+quantity > 0 {
|
if p.Base+quantity > 0 {
|
||||||
closingProfit := (p.AverageCost - price).Mul(-p.Base) - quoteFee
|
profit = (p.AverageCost - price).Mul(-p.Base)
|
||||||
|
netProfit = profit - quoteFee
|
||||||
p.Base += quantity
|
p.Base += quantity
|
||||||
p.Quote -= quoteQuantity
|
p.Quote -= quoteQuantity
|
||||||
p.AverageCost = price
|
p.AverageCost = price
|
||||||
return closingProfit, true
|
return profit, netProfit, true
|
||||||
} else {
|
} else {
|
||||||
// covering short position
|
// covering short position
|
||||||
p.Base += quantity
|
p.Base += quantity
|
||||||
p.Quote -= quoteQuantity
|
p.Quote -= quoteQuantity
|
||||||
return (p.AverageCost - price).Mul(quantity) - quoteFee, true
|
profit = (p.AverageCost - price).Mul(quantity)
|
||||||
|
netProfit = profit - quoteFee
|
||||||
|
return profit, netProfit, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,21 +179,24 @@ func (p *Position) AddTrade(t types.Trade) (fixedpoint.Value, bool) {
|
||||||
p.Base += quantity
|
p.Base += quantity
|
||||||
p.Quote -= quoteQuantity
|
p.Quote -= quoteQuantity
|
||||||
|
|
||||||
return 0, false
|
return 0, 0, false
|
||||||
|
|
||||||
case types.SideTypeSell:
|
case types.SideTypeSell:
|
||||||
if p.Base > 0 {
|
if p.Base > 0 {
|
||||||
// long-to-short
|
// long-to-short
|
||||||
if p.Base-quantity < 0 {
|
if p.Base-quantity < 0 {
|
||||||
closingProfit := (price - p.AverageCost).Mul(p.Base) - quoteFee
|
profit = (price - p.AverageCost).Mul(p.Base)
|
||||||
|
netProfit = profit - quoteFee
|
||||||
p.Base -= quantity
|
p.Base -= quantity
|
||||||
p.Quote += quoteQuantity
|
p.Quote += quoteQuantity
|
||||||
p.AverageCost = price
|
p.AverageCost = price
|
||||||
return closingProfit, true
|
return profit, netProfit, true
|
||||||
} else {
|
} else {
|
||||||
p.Base -= quantity
|
p.Base -= quantity
|
||||||
p.Quote += quoteQuantity
|
p.Quote += quoteQuantity
|
||||||
return (price - p.AverageCost).Mul(quantity) - quoteFee, true
|
profit = (price - p.AverageCost).Mul(quantity)
|
||||||
|
netProfit = profit - quoteFee
|
||||||
|
return profit, netProfit, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +205,8 @@ func (p *Position) AddTrade(t types.Trade) (fixedpoint.Value, bool) {
|
||||||
p.Base -= quantity
|
p.Base -= quantity
|
||||||
p.Quote += quoteQuantity
|
p.Quote += quoteQuantity
|
||||||
|
|
||||||
return 0, false
|
return 0, 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, false
|
return 0, 0, false
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ func TestPosition_ExchangeFeeRate_Short(t *testing.T) {
|
||||||
FeeCurrency: "BNB",
|
FeeCurrency: "BNB",
|
||||||
})
|
})
|
||||||
|
|
||||||
profit, madeProfit := pos.AddTrade(types.Trade{
|
profit, _, madeProfit := pos.AddTrade(types.Trade{
|
||||||
Exchange: types.ExchangeBinance,
|
Exchange: types.ExchangeBinance,
|
||||||
Price: 2000.0,
|
Price: 2000.0,
|
||||||
Quantity: 10.0,
|
Quantity: 10.0,
|
||||||
|
@ -83,7 +83,7 @@ func TestPosition_ExchangeFeeRate_Long(t *testing.T) {
|
||||||
FeeCurrency: "BNB",
|
FeeCurrency: "BNB",
|
||||||
})
|
})
|
||||||
|
|
||||||
profit, madeProfit := pos.AddTrade(types.Trade{
|
profit, _, madeProfit := pos.AddTrade(types.Trade{
|
||||||
Exchange: types.ExchangeBinance,
|
Exchange: types.ExchangeBinance,
|
||||||
Price: 4000.0,
|
Price: 4000.0,
|
||||||
Quantity: 10.0,
|
Quantity: 10.0,
|
||||||
|
@ -253,7 +253,7 @@ func TestPosition(t *testing.T) {
|
||||||
BaseCurrency: "BTC",
|
BaseCurrency: "BTC",
|
||||||
QuoteCurrency: "USDT",
|
QuoteCurrency: "USDT",
|
||||||
}
|
}
|
||||||
profitAmount, profit := pos.AddTrades(testcase.trades)
|
profitAmount, _, profit := pos.AddTrades(testcase.trades)
|
||||||
|
|
||||||
assert.Equal(t, testcase.expectedQuote, pos.Quote, "expectedQuote")
|
assert.Equal(t, testcase.expectedQuote, pos.Quote, "expectedQuote")
|
||||||
assert.Equal(t, testcase.expectedBase, pos.Base, "expectedBase")
|
assert.Equal(t, testcase.expectedBase, pos.Base, "expectedBase")
|
||||||
|
|
|
@ -391,9 +391,9 @@ func (s *Strategy) tradeUpdateHandler(trade types.Trade) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
profit, madeProfit := s.state.Position.AddTrade(trade)
|
profit, netProfit, madeProfit := s.state.Position.AddTrade(trade)
|
||||||
if madeProfit {
|
if madeProfit {
|
||||||
s.Notify("average cost profit: %f", profit.Float64())
|
s.Notify("%s average cost profit: %f, net profit =~ %f", s.Symbol, profit.Float64(), netProfit.Float64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,7 +536,7 @@ func (s *Strategy) handleTradeUpdate(trade types.Trade) {
|
||||||
s.state.HedgePosition.AtomicAdd(q)
|
s.state.HedgePosition.AtomicAdd(q)
|
||||||
s.state.AccumulatedVolume.AtomicAdd(fixedpoint.NewFromFloat(trade.Quantity))
|
s.state.AccumulatedVolume.AtomicAdd(fixedpoint.NewFromFloat(trade.Quantity))
|
||||||
|
|
||||||
if profit, madeProfit := s.state.Position.AddTrade(trade); madeProfit {
|
if profit, netProfit, madeProfit := s.state.Position.AddTrade(trade); madeProfit {
|
||||||
s.state.AccumulatedPnL.AtomicAdd(profit)
|
s.state.AccumulatedPnL.AtomicAdd(profit)
|
||||||
|
|
||||||
if profit < 0 {
|
if profit < 0 {
|
||||||
|
@ -552,11 +552,12 @@ func (s *Strategy) handleTradeUpdate(trade types.Trade) {
|
||||||
since = time.Unix(s.state.AccumulatedSince, 0).In(localTimeZone)
|
since = time.Unix(s.state.AccumulatedSince, 0).In(localTimeZone)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Notify("%s trade profit %s %f %s (%.3f%%), since %s accumulated net profit %f %s, accumulated loss %f %s",
|
s.Notify("%s trade profit %s %f %s (%.3f%%), net profit =~ %f %s, since %s accumulated net profit %f %s, accumulated loss %f %s",
|
||||||
s.Symbol,
|
s.Symbol,
|
||||||
pnlEmoji(profit),
|
pnlEmoji(profit),
|
||||||
profit.Float64(), s.state.Position.QuoteCurrency,
|
profit.Float64(), s.state.Position.QuoteCurrency,
|
||||||
profitMargin.Float64()*100.0,
|
profitMargin.Float64()*100.0,
|
||||||
|
netProfit.Float64(), s.state.Position.QuoteCurrency,
|
||||||
since.Format(time.RFC822),
|
since.Format(time.RFC822),
|
||||||
s.state.AccumulatedPnL.Float64(), s.state.Position.QuoteCurrency,
|
s.state.AccumulatedPnL.Float64(), s.state.Position.QuoteCurrency,
|
||||||
s.state.AccumulatedLoss.Float64(), s.state.Position.QuoteCurrency)
|
s.state.AccumulatedLoss.Float64(), s.state.Position.QuoteCurrency)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user