all: implement stats tracker

- rename Add() to AddProfit() or AddTrade() so that we can apply
  interface here
This commit is contained in:
c9s 2023-08-29 16:12:31 +08:00
parent 3dca9aaf98
commit 4a3b0bc368
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
10 changed files with 94 additions and 11 deletions

View File

@ -170,7 +170,7 @@ func (e *GeneralOrderExecutor) BindTradeStats(tradeStats *types.TradeStats) {
return
}
tradeStats.Add(profit)
tradeStats.AddProfit(profit)
})
}
@ -181,7 +181,7 @@ func (e *GeneralOrderExecutor) BindProfitStats(profitStats *types.ProfitStats) {
return
}
profitStats.AddProfit(*profit)
profitStats.AddProfit(profit)
if !e.disableNotify {
Notify(profit)

View File

@ -338,7 +338,7 @@ var BacktestCmd = &cobra.Command{
if profit == nil {
return
}
tradeStats.Add(profit)
tradeStats.AddProfit(profit)
})
tradeStatsMap[usedSymbol] = tradeStats

View File

@ -84,7 +84,7 @@ func (p *ProfitStatsTracker) Rotate() {
}
func (p *ProfitStatsTracker) AddProfit(profit types.Profit) {
(*p.CurrentProfitStats).AddProfit(profit)
(*p.CurrentProfitStats).AddProfit(&profit)
}
func (p *ProfitStatsTracker) AddTrade(trade types.Trade) {

View File

@ -0,0 +1,83 @@
package report
import (
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/core"
"github.com/c9s/bbgo/pkg/types"
)
type TradeAdder interface {
AddTrade(trade *types.Trade)
}
type ProfitAdder interface {
AddProfit(trade *types.Profit)
}
// StatsCollector is the v2 profit stats tracker
type StatsCollector struct {
Market types.Market `json:"market"`
Interval types.Interval `json:"interval"`
Window int `json:"window"`
CurrentProfitStats *types.ProfitStats `json:"profitStats"`
AccumulatedProfitStats *types.ProfitStats `json:"accumulatedProfitStats"`
HistoryProfitStats []types.ProfitStats `json:"historyProfitStats"`
CurrentTradeStats *types.TradeStats `json:"tradeStats"`
AccumulatedTradeStats *types.TradeStats `json:"accumulatedTradeStats"`
HistoryTradeStats []types.TradeStats `json:"historyTradeStats"`
tradeCollector *core.TradeCollector
}
func NewStatsCollector(market types.Market, interval types.Interval, window int, tradeCollector *core.TradeCollector) *StatsCollector {
return &StatsCollector{
Market: market,
Interval: interval,
Window: window,
CurrentProfitStats: types.NewProfitStats(market),
CurrentTradeStats: types.NewTradeStats(market.Symbol),
AccumulatedProfitStats: types.NewProfitStats(market),
AccumulatedTradeStats: types.NewTradeStats(market.Symbol),
tradeCollector: tradeCollector,
}
}
func (c *StatsCollector) Subscribe(session *bbgo.ExchangeSession) {
session.Subscribe(types.KLineChannel, c.Market.Symbol, types.SubscribeOptions{Interval: c.Interval})
}
func (c *StatsCollector) Bind(session *bbgo.ExchangeSession) {
c.tradeCollector.OnProfit(func(trade types.Trade, profit *types.Profit) {
if profit != nil {
c.CurrentProfitStats.AddProfit(profit)
c.AccumulatedProfitStats.AddProfit(profit)
}
c.CurrentProfitStats.AddTrade(trade)
c.AccumulatedProfitStats.AddTrade(trade)
c.CurrentTradeStats.AddProfit(profit)
c.AccumulatedTradeStats.AddProfit(profit)
})
// Rotate profitStats slice
session.MarketDataStream.OnKLineClosed(types.KLineWith(c.Market.Symbol, c.Interval, func(k types.KLine) {
// p.Rotate()
}))
}
// Rotate the tracker to make a new ProfitStats to record the profits
func (c *StatsCollector) Rotate() {
c.HistoryProfitStats = append(c.HistoryProfitStats, *c.CurrentProfitStats)
c.HistoryTradeStats = append(c.HistoryTradeStats, *c.CurrentTradeStats)
/*
*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:]
}
*/
}

View File

@ -831,9 +831,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
if madeProfit {
p := s.Position.NewProfit(trade, profit, netProfit)
s.Environment.RecordPosition(s.Position, trade, &p)
s.TradeStats.Add(&p)
s.TradeStats.AddProfit(&p)
s.ProfitStats.AddTrade(trade)
s.ProfitStats.AddProfit(p)
s.ProfitStats.AddProfit(&p)
bbgo.Notify(&p)
bbgo.Notify(s.ProfitStats)
}

View File

@ -193,7 +193,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
p.StrategyInstanceID = instanceID
bbgo.Notify(&p)
s.ProfitStats.AddProfit(p)
s.ProfitStats.AddProfit(&p)
bbgo.Notify(&s.ProfitStats)
s.Environment.RecordPosition(s.Position, trade, &p)

View File

@ -1096,7 +1096,7 @@ func (s *Strategy) allocateOrderExecutor(ctx context.Context, session *bbgo.Exch
if profit, netProfit, madeProfit := s.NeutralPosition.AddTrade(trade); madeProfit {
p := s.NeutralPosition.NewProfit(trade, profit, netProfit)
s.ProfitStats.AddProfit(p)
s.ProfitStats.AddProfit(&p)
}
})
return orderExecutor

View File

@ -809,7 +809,7 @@ func (s *Strategy) CrossRun(
p.Strategy = ID
p.StrategyInstanceID = instanceID
bbgo.Notify(&p)
s.ProfitStats.AddProfit(p)
s.ProfitStats.AddProfit(&p)
s.Environment.RecordPosition(s.Position, trade, &p)
}

View File

@ -216,7 +216,7 @@ func (s *ProfitStats) Init(market Market) {
}
}
func (s *ProfitStats) AddProfit(profit Profit) {
func (s *ProfitStats) AddProfit(profit *Profit) {
if s.IsOver24Hours() {
s.ResetToday(profit.TradedAt)
}

View File

@ -240,7 +240,7 @@ func (s *TradeStats) CsvRecords() [][]string {
}
}
func (s *TradeStats) Add(profit *Profit) {
func (s *TradeStats) AddProfit(profit *Profit) {
if s.Symbol != "" && profit.Symbol != s.Symbol {
return
}