mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-15 03:23:52 +00:00
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package xdepthmaker
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
"github.com/c9s/bbgo/pkg/exchange/batch"
|
|
"github.com/c9s/bbgo/pkg/types"
|
|
)
|
|
|
|
type ProfitFixerConfig struct {
|
|
TradesSince types.Time `json:"tradesSince,omitempty"`
|
|
}
|
|
|
|
// ProfitFixer implements a trade history based profit fixer
|
|
type ProfitFixer struct {
|
|
market types.Market
|
|
|
|
sessions map[string]types.ExchangeTradeHistoryService
|
|
}
|
|
|
|
func NewProfitFixer(market types.Market) *ProfitFixer {
|
|
return &ProfitFixer{
|
|
market: market,
|
|
sessions: make(map[string]types.ExchangeTradeHistoryService),
|
|
}
|
|
}
|
|
|
|
func (f *ProfitFixer) AddExchange(sessionName string, service types.ExchangeTradeHistoryService) {
|
|
f.sessions[sessionName] = service
|
|
}
|
|
|
|
func (f *ProfitFixer) batchQueryTrades(
|
|
ctx context.Context,
|
|
service types.ExchangeTradeHistoryService,
|
|
symbol string,
|
|
since time.Time,
|
|
) ([]types.Trade, error) {
|
|
|
|
now := time.Now()
|
|
q := &batch.TradeBatchQuery{ExchangeTradeHistoryService: service}
|
|
trades, err := q.QueryTrades(ctx, symbol, &types.TradeQueryOptions{
|
|
StartTime: &since,
|
|
EndTime: &now,
|
|
})
|
|
|
|
return trades, err
|
|
}
|
|
|
|
func (f *ProfitFixer) Fix(ctx context.Context, since time.Time) (*types.ProfitStats, error) {
|
|
stats := types.NewProfitStats(f.market)
|
|
|
|
var mu sync.Mutex
|
|
var allTrades = make([]types.Trade, 0, 1000)
|
|
|
|
g, subCtx := errgroup.WithContext(ctx)
|
|
for _, service := range f.sessions {
|
|
g.Go(func() error {
|
|
trades, err := f.batchQueryTrades(subCtx, service, f.market.Symbol, since)
|
|
if err != nil {
|
|
log.WithError(err).Errorf("unable to batch query trades for fixer")
|
|
return err
|
|
}
|
|
|
|
mu.Lock()
|
|
allTrades = append(allTrades, trades...)
|
|
mu.Unlock()
|
|
return nil
|
|
})
|
|
}
|
|
|
|
if err := g.Wait(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
allTrades = types.SortTradesAscending(allTrades)
|
|
for _, trade := range allTrades {
|
|
stats.AddTrade(trade)
|
|
}
|
|
|
|
return stats, nil
|
|
}
|