feature/profitTracker: prototype

This commit is contained in:
Andy Cheng 2023-06-16 14:56:22 +08:00
parent 1da94f55e9
commit d5e194ca80
No known key found for this signature in database
GPG Key ID: 936427CF651A9D28
3 changed files with 75 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package bbgo
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/c9s/bbgo/pkg/report"
"strings" "strings"
"time" "time"
@ -162,6 +163,10 @@ func (e *GeneralOrderExecutor) BindProfitStats(profitStats *types.ProfitStats) {
}) })
} }
func (e *GeneralOrderExecutor) BindProfitTracker(profitTracker *report.ProfitTracker) {
profitTracker.Bind(e.tradeCollector, e.session)
}
func (e *GeneralOrderExecutor) Bind() { func (e *GeneralOrderExecutor) Bind() {
e.activeMakerOrders.BindStream(e.session.UserDataStream) e.activeMakerOrders.BindStream(e.session.UserDataStream)
e.orderStore.BindStream(e.session.UserDataStream) e.orderStore.BindStream(e.session.UserDataStream)

View File

@ -0,0 +1,63 @@
package report
import (
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type ProfitTracker struct {
types.IntervalWindow
market types.Market
profitStatsSlice []*types.ProfitStats
currentProfitStats **types.ProfitStats
}
// InitOld is for backward capability. ps is the ProfitStats of the strategy, market is the strategy market
func (p *ProfitTracker) InitOld(ps **types.ProfitStats, market types.Market) {
p.market = market
if *ps == nil {
*ps = types.NewProfitStats(p.market)
}
p.currentProfitStats = ps
p.profitStatsSlice = append(p.profitStatsSlice, *ps)
}
// Init initialize the tracker with the given market
func (p *ProfitTracker) Init(market types.Market) {
p.market = market
*p.currentProfitStats = types.NewProfitStats(p.market)
p.profitStatsSlice = append(p.profitStatsSlice, *p.currentProfitStats)
}
func (p *ProfitTracker) Bind(tradeCollector *bbgo.TradeCollector, session *bbgo.ExchangeSession) {
// TODO: Register kline close callback
tradeCollector.OnProfit(func(trade types.Trade, profit *types.Profit) {
p.AddProfit(*profit)
})
tradeCollector.OnTrade(func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
})
session.MarketDataStream.OnKLineClosed(types.KLineWith(p.market.Symbol, p.Interval, func(kline types.KLine) {
}))
}
// Rotate the tracker to make a new ProfitStats to record the profits
func (p *ProfitTracker) Rotate() {
*p.currentProfitStats = types.NewProfitStats(p.market)
p.profitStatsSlice = append(p.profitStatsSlice, *p.currentProfitStats)
// Truncate
if len(p.profitStatsSlice) > p.Window {
p.profitStatsSlice = p.profitStatsSlice[len(p.profitStatsSlice)-p.Window:]
}
}
func (p *ProfitTracker) AddProfit(profit types.Profit) {
(*p.currentProfitStats).AddProfit(profit)
}

View File

@ -164,6 +164,9 @@ type ProfitStats struct {
TodayGrossProfit fixedpoint.Value `json:"todayGrossProfit,omitempty"` TodayGrossProfit fixedpoint.Value `json:"todayGrossProfit,omitempty"`
TodayGrossLoss fixedpoint.Value `json:"todayGrossLoss,omitempty"` TodayGrossLoss fixedpoint.Value `json:"todayGrossLoss,omitempty"`
TodaySince int64 `json:"todaySince,omitempty"` TodaySince int64 `json:"todaySince,omitempty"`
startTime time.Time
endTime time.Time
} }
func NewProfitStats(market Market) *ProfitStats { func NewProfitStats(market Market) *ProfitStats {
@ -182,6 +185,8 @@ func NewProfitStats(market Market) *ProfitStats {
TodayGrossProfit: fixedpoint.Zero, TodayGrossProfit: fixedpoint.Zero,
TodayGrossLoss: fixedpoint.Zero, TodayGrossLoss: fixedpoint.Zero,
TodaySince: 0, TodaySince: 0,
startTime: time.Now().UTC(),
endTime: time.Now().UTC(),
} }
} }
@ -223,6 +228,8 @@ func (s *ProfitStats) AddProfit(profit Profit) {
s.AccumulatedGrossLoss = s.AccumulatedGrossLoss.Add(profit.Profit) s.AccumulatedGrossLoss = s.AccumulatedGrossLoss.Add(profit.Profit)
s.TodayGrossLoss = s.TodayGrossLoss.Add(profit.Profit) s.TodayGrossLoss = s.TodayGrossLoss.Add(profit.Profit)
} }
s.endTime = profit.TradedAt.UTC()
} }
func (s *ProfitStats) AddTrade(trade Trade) { func (s *ProfitStats) AddTrade(trade Trade) {