service: add kline partial sync

This commit is contained in:
c9s 2022-06-04 19:15:11 +08:00
parent bf4d8d345e
commit 425f8674d2
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 83 additions and 2 deletions

View File

@ -364,7 +364,30 @@ func (s *BacktestService) SyncPartial(ctx context.Context, ex types.Exchange, sy
if err != nil { if err != nil {
return err return err
} }
_ = timeRanges
// there are few cases:
// t1 == since && t2 == until
if since.Before(t1.Time()) {
// shift slice
timeRanges = append([]TimeRange{
{Start: since.Add(-2 * time.Second), End: t1.Time()}, // include since
}, timeRanges...)
}
if t2.Time().Before(until) {
timeRanges = append(timeRanges, TimeRange{
Start: t2.Time(),
End: until.Add(2 * time.Second), // include until
})
}
for _, timeRange := range timeRanges {
err = s.SyncKLineByInterval(ctx, ex, symbol, types.Interval1h, timeRange.Start.Add(time.Second), timeRange.End.Add(-time.Second))
if err != nil {
return err
}
}
return nil return nil
} }

View File

@ -13,7 +13,65 @@ import (
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
func TestBacktestService(t *testing.T) { func TestBacktestService_SyncPartial(t *testing.T) {
db, err := prepareDB(t)
if err != nil {
t.Fatal(err)
}
defer db.Close()
ctx := context.Background()
dbx := sqlx.NewDb(db.DB, "sqlite3")
ex, err := exchange.NewPublic(types.ExchangeBinance)
assert.NoError(t, err)
service := &BacktestService{DB: dbx}
symbol := "BTCUSDT"
now := time.Now()
startTime1 := now.AddDate(0, 0, -7).Truncate(time.Hour)
endTime1 := now.AddDate(0, 0, -6).Truncate(time.Hour)
startTime2 := now.AddDate(0, 0, -5).Truncate(time.Hour)
endTime2 := now.AddDate(0, 0, -4).Truncate(time.Hour)
// kline query is exclusive
err = service.SyncKLineByInterval(ctx, ex, symbol, types.Interval1h, startTime1.Add(-time.Second), endTime1.Add(time.Second))
assert.NoError(t, err)
err = service.SyncKLineByInterval(ctx, ex, symbol, types.Interval1h, startTime2.Add(-time.Second), endTime2.Add(time.Second))
assert.NoError(t, err)
timeRanges, err := service.FindMissingTimeRanges(ctx, ex, symbol, types.Interval1h, startTime1, endTime2)
assert.NoError(t, err)
assert.NotEmpty(t, timeRanges)
t.Run("fill missing time ranges", func(t *testing.T) {
err = service.SyncPartial(ctx, ex, symbol, types.Interval1h, startTime1, endTime2)
assert.NoError(t, err, "sync partial should not return error")
timeRanges2, err := service.FindMissingTimeRanges(ctx, ex, symbol, types.Interval1h, startTime1, endTime2)
assert.NoError(t, err)
assert.Empty(t, timeRanges2)
})
t.Run("extend time ranges", func(t *testing.T) {
startTime3 := startTime1.AddDate(0, 0, -3)
endTime3 := endTime2.AddDate(0, 0, 3)
err = service.SyncPartial(ctx, ex, symbol, types.Interval1h, startTime3, endTime3)
assert.NoError(t, err, "sync partial should not return error")
timeRanges3, err := service.FindMissingTimeRanges(ctx, ex, symbol, types.Interval1h, startTime3, endTime3)
assert.NoError(t, err)
assert.Empty(t, timeRanges3)
})
}
func TestBacktestService_FindMissingTimeRanges(t *testing.T) {
db, err := prepareDB(t) db, err := prepareDB(t)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)