bbgo_origin/pkg/datasource/csvsource/read_klines.go
2024-07-09 15:28:30 +08:00

60 lines
1.5 KiB
Go

package csvsource
import (
"encoding/csv"
"io/fs"
"os"
"path/filepath"
"time"
"github.com/c9s/bbgo/pkg/types"
)
// KLineReader is an interface for reading candlesticks.
type KLineReader interface {
Read(interval time.Duration) (types.KLine, error)
ReadAll(interval time.Duration) ([]types.KLine, error)
}
// ReadKLinesFromCSV reads all the .csv files in a given directory or a single file into a slice of KLines.
// Wraps a default CSVKLineReader with Binance decoder for convenience.
// For finer grained memory management use the base kline reader.
func ReadKLinesFromCSV(path string, interval time.Duration) ([]types.KLine, error) {
return ReadKLinesFromCSVWithDecoder(path, interval, MakeCSVKLineReader(NewBinanceCSVKLineReader))
}
// ReadKLinesFromCSVWithDecoder permits using a custom CSVKLineReader.
func ReadKLinesFromCSVWithDecoder(path string, interval time.Duration, maker MakeCSVKLineReader) ([]types.KLine, error) {
var klines []types.KLine
err := filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
if filepath.Ext(path) != ".csv" {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
//nolint:errcheck // Read ops only so safe to ignore err return
defer file.Close()
reader := maker(csv.NewReader(file))
newKlines, err := reader.ReadAll(interval)
if err != nil {
return err
}
klines = append(klines, newKlines...)
return nil
})
if err != nil {
return nil, err
}
return klines, nil
}