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) {
|
||||
var totalProfitAmount fixedpoint.Value
|
||||
func (p *Position) AddTrades(trades []types.Trade) (fixedpoint.Value, fixedpoint.Value, bool) {
|
||||
var totalProfitAmount, totalNetProfit fixedpoint.Value
|
||||
for _, trade := range trades {
|
||||
if profitAmount, profit := p.AddTrade(trade); profit {
|
||||
totalProfitAmount += profitAmount
|
||||
if profit, netProfit, madeProfit := p.AddTrade(trade); madeProfit {
|
||||
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)
|
||||
quantity := fixedpoint.NewFromFloat(t.Quantity)
|
||||
quoteQuantity := fixedpoint.NewFromFloat(t.QuoteQuantity)
|
||||
|
@ -158,16 +159,19 @@ func (p *Position) AddTrade(t types.Trade) (fixedpoint.Value, bool) {
|
|||
if p.Base < 0 {
|
||||
// handling short-to-long position
|
||||
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.Quote -= quoteQuantity
|
||||
p.AverageCost = price
|
||||
return closingProfit, true
|
||||
return profit, netProfit, true
|
||||
} else {
|
||||
// covering short position
|
||||
p.Base += quantity
|
||||
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.Quote -= quoteQuantity
|
||||
|
||||
return 0, false
|
||||
return 0, 0, false
|
||||
|
||||
case types.SideTypeSell:
|
||||
if p.Base > 0 {
|
||||
// long-to-short
|
||||
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.Quote += quoteQuantity
|
||||
p.AverageCost = price
|
||||
return closingProfit, true
|
||||
return profit, netProfit, true
|
||||
} else {
|
||||
p.Base -= quantity
|
||||
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.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",
|
||||
})
|
||||
|
||||
profit, madeProfit := pos.AddTrade(types.Trade{
|
||||
profit, _, madeProfit := pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
Price: 2000.0,
|
||||
Quantity: 10.0,
|
||||
|
@ -83,7 +83,7 @@ func TestPosition_ExchangeFeeRate_Long(t *testing.T) {
|
|||
FeeCurrency: "BNB",
|
||||
})
|
||||
|
||||
profit, madeProfit := pos.AddTrade(types.Trade{
|
||||
profit, _, madeProfit := pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
Price: 4000.0,
|
||||
Quantity: 10.0,
|
||||
|
@ -253,7 +253,7 @@ func TestPosition(t *testing.T) {
|
|||
BaseCurrency: "BTC",
|
||||
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.expectedBase, pos.Base, "expectedBase")
|
||||
|
|
|
@ -391,9 +391,9 @@ func (s *Strategy) tradeUpdateHandler(trade types.Trade) {
|
|||
return
|
||||
}
|
||||
|
||||
profit, madeProfit := s.state.Position.AddTrade(trade)
|
||||
profit, netProfit, madeProfit := s.state.Position.AddTrade(trade)
|
||||
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.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)
|
||||
|
||||
if profit < 0 {
|
||||
|
@ -552,11 +552,12 @@ func (s *Strategy) handleTradeUpdate(trade types.Trade) {
|
|||
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,
|
||||
pnlEmoji(profit),
|
||||
profit.Float64(), s.state.Position.QuoteCurrency,
|
||||
profitMargin.Float64()*100.0,
|
||||
netProfit.Float64(), s.state.Position.QuoteCurrency,
|
||||
since.Format(time.RFC822),
|
||||
s.state.AccumulatedPnL.Float64(), s.state.Position.QuoteCurrency,
|
||||
s.state.AccumulatedLoss.Float64(), s.state.Position.QuoteCurrency)
|
||||
|
|
Loading…
Reference in New Issue
Block a user