mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 14:55:16 +00:00
rewrite trade profit handling
This commit is contained in:
parent
6fec30d79c
commit
5db4e11167
|
@ -22,6 +22,7 @@ import (
|
|||
"gopkg.in/tucnak/telebot.v2"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/cmd/cmdutil"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/interact"
|
||||
"github.com/c9s/bbgo/pkg/notifier/slacknotifier"
|
||||
"github.com/c9s/bbgo/pkg/notifier/telegramnotifier"
|
||||
|
@ -596,16 +597,21 @@ func (environ *Environment) RecordPosition(position *types.Position, trade types
|
|||
position.StrategyInstanceID = profit.StrategyInstanceID
|
||||
}
|
||||
|
||||
if err := environ.PositionService.Insert(position, trade, profit.Profit); err != nil {
|
||||
log.WithError(err).Errorf("can not insert position record")
|
||||
}
|
||||
|
||||
if profit != nil {
|
||||
if err := environ.PositionService.Insert(position, trade, profit.Profit); err != nil {
|
||||
log.WithError(err).Errorf("can not insert position record")
|
||||
}
|
||||
if err := environ.ProfitService.Insert(*profit); err != nil {
|
||||
log.WithError(err).Errorf("can not insert profit record: %+v", profit)
|
||||
}
|
||||
} else {
|
||||
if err := environ.PositionService.Insert(position, trade, fixedpoint.Zero); err != nil {
|
||||
log.WithError(err).Errorf("can not insert position record")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if:
|
||||
// 1) we are not using sync
|
||||
// 2) and not sync-ing trades from the user data stream
|
||||
|
|
|
@ -23,7 +23,7 @@ type TradeCollector struct {
|
|||
doneTrades map[types.TradeKey]struct{}
|
||||
|
||||
recoverCallbacks []func(trade types.Trade)
|
||||
tradeCallbacks []func(trade types.Trade)
|
||||
tradeCallbacks []func(trade types.Trade, profit, netProfit fixedpoint.Value)
|
||||
positionUpdateCallbacks []func(position *types.Position)
|
||||
profitCallbacks []func(trade types.Trade, profit, netProfit fixedpoint.Value)
|
||||
}
|
||||
|
@ -108,10 +108,10 @@ func (c *TradeCollector) Process() bool {
|
|||
if c.orderStore.Exists(trade.OrderID) {
|
||||
c.doneTrades[key] = struct{}{}
|
||||
if profit, netProfit, madeProfit := c.position.AddTrade(trade); madeProfit {
|
||||
c.EmitTrade(trade)
|
||||
c.EmitTrade(trade, fixedpoint.Zero, fixedpoint.Zero)
|
||||
c.EmitProfit(trade, profit, netProfit)
|
||||
} else {
|
||||
c.EmitTrade(trade)
|
||||
c.EmitTrade(trade, fixedpoint.Zero, fixedpoint.Zero)
|
||||
}
|
||||
positionChanged = true
|
||||
return true
|
||||
|
@ -139,10 +139,10 @@ func (c *TradeCollector) processTrade(trade types.Trade) bool {
|
|||
}
|
||||
|
||||
if profit, netProfit, madeProfit := c.position.AddTrade(trade); madeProfit {
|
||||
c.EmitTrade(trade)
|
||||
c.EmitTrade(trade, fixedpoint.Zero, fixedpoint.Zero)
|
||||
c.EmitProfit(trade, profit, netProfit)
|
||||
} else {
|
||||
c.EmitTrade(trade)
|
||||
c.EmitTrade(trade, fixedpoint.Zero, fixedpoint.Zero)
|
||||
}
|
||||
c.EmitPositionUpdate(c.position)
|
||||
c.doneTrades[key] = struct{}{}
|
||||
|
|
|
@ -17,13 +17,13 @@ func (c *TradeCollector) EmitRecover(trade types.Trade) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *TradeCollector) OnTrade(cb func(trade types.Trade)) {
|
||||
func (c *TradeCollector) OnTrade(cb func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value)) {
|
||||
c.tradeCallbacks = append(c.tradeCallbacks, cb)
|
||||
}
|
||||
|
||||
func (c *TradeCollector) EmitTrade(trade types.Trade) {
|
||||
func (c *TradeCollector) EmitTrade(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
|
||||
for _, cb := range c.tradeCallbacks {
|
||||
cb(trade)
|
||||
cb(trade, profit, netProfit)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -566,22 +566,26 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
s.orderStore.BindStream(session.UserDataStream)
|
||||
|
||||
s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.state.Position, s.orderStore)
|
||||
s.tradeCollector.OnProfit(func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
|
||||
log.Infof("generated profit: %v", profit)
|
||||
p := s.state.Position.NewProfit(trade, profit, netProfit)
|
||||
p.Strategy = ID
|
||||
p.StrategyInstanceID = instanceID
|
||||
s.Environment.RecordPosition(s.state.Position, trade, &p)
|
||||
|
||||
s.state.ProfitStats.AddProfit(p)
|
||||
s.Notify(&p)
|
||||
s.tradeCollector.OnProfit(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
|
||||
s.Notify(&s.state.ProfitStats)
|
||||
})
|
||||
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade) {
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
|
||||
s.Notifiability.Notify(trade)
|
||||
s.state.ProfitStats.AddTrade(trade)
|
||||
s.Environment.RecordPosition(s.state.Position, trade, nil)
|
||||
|
||||
if profit.Compare(fixedpoint.Zero) == 0 {
|
||||
s.Environment.RecordPosition(s.state.Position, trade, nil)
|
||||
} else {
|
||||
log.Infof("%s generated profit: %v", s.Symbol, profit)
|
||||
p := s.state.Position.NewProfit(trade, profit, netProfit)
|
||||
p.Strategy = ID
|
||||
p.StrategyInstanceID = instanceID
|
||||
s.state.ProfitStats.AddProfit(p)
|
||||
s.Notify(&p)
|
||||
|
||||
s.Environment.RecordPosition(s.state.Position, trade, &p)
|
||||
}
|
||||
})
|
||||
|
||||
s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
|
||||
|
|
|
@ -605,7 +605,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
|
||||
s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.state.Position, s.orderStore)
|
||||
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade) {
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
|
||||
s.Notifiability.Notify(trade)
|
||||
s.state.ProfitStats.AddTrade(trade)
|
||||
})
|
||||
|
|
|
@ -38,6 +38,7 @@ type Strategy struct {
|
|||
*bbgo.Graceful
|
||||
*bbgo.Notifiability
|
||||
*bbgo.Persistence
|
||||
Environment *bbgo.Environment
|
||||
|
||||
Symbol string `json:"symbol"`
|
||||
|
||||
|
@ -745,12 +746,12 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
|||
s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.state.Position, s.orderStore)
|
||||
|
||||
if s.NotifyTrade {
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade) {
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
|
||||
s.Notifiability.Notify(trade)
|
||||
})
|
||||
}
|
||||
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade) {
|
||||
s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
|
||||
c := trade.PositionChange()
|
||||
if trade.Exchange == s.sourceSession.ExchangeName {
|
||||
s.state.CoveredPosition = s.state.CoveredPosition.Add(c)
|
||||
|
@ -758,25 +759,25 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
|||
|
||||
s.state.ProfitStats.AddTrade(trade)
|
||||
|
||||
if profit.Compare(fixedpoint.Zero) == 0 {
|
||||
s.Environment.RecordPosition(s.state.Position, trade, nil)
|
||||
} else {
|
||||
log.Infof("%s generated profit: %v", s.Symbol, profit)
|
||||
|
||||
p := s.state.Position.NewProfit(trade, profit, netProfit)
|
||||
p.Strategy = ID
|
||||
p.StrategyInstanceID = instanceID
|
||||
s.Notify(&p)
|
||||
s.state.ProfitStats.AddProfit(p)
|
||||
|
||||
s.Environment.RecordPosition(s.state.Position, trade, &p)
|
||||
}
|
||||
|
||||
if err := s.SaveState(); err != nil {
|
||||
log.WithError(err).Error("save state error")
|
||||
}
|
||||
})
|
||||
s.tradeCollector.OnProfit(func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
|
||||
p := types.Profit{
|
||||
Symbol: s.Symbol,
|
||||
Profit: profit,
|
||||
NetProfit: netProfit,
|
||||
QuoteQuantity: trade.QuoteQuantity,
|
||||
ProfitMargin: profit.Div(trade.QuoteQuantity),
|
||||
NetProfitMargin: netProfit.Div(trade.QuoteQuantity),
|
||||
QuoteCurrency: s.state.Position.QuoteCurrency,
|
||||
BaseCurrency: s.state.Position.BaseCurrency,
|
||||
TradedAt: trade.Time.Time(),
|
||||
}
|
||||
s.state.ProfitStats.AddProfit(p)
|
||||
s.Notify(&p)
|
||||
})
|
||||
|
||||
s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
|
||||
s.Notifiability.Notify(position)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user