package main import ( "encoding/csv" "flag" "fmt" "os" "path/filepath" "strconv" "strings" "github.com/banbox/banbot/biz" "github.com/banbox/banbot/config" "github.com/banbox/banbot/core" "github.com/banbox/banbot/orm" ) var columns = []string{ "timestamp", "open", "high", "low", "close", "volume", "quote", "buy_volume", "trade_num", } func main() { configPath := flag.String("config", "", "banbot config path") dataDir := flag.String("data-dir", "", "banbot data directory") pairs := flag.String("pairs", "", "comma-separated symbols") startMS := flag.Int64("start-ms", 0, "inclusive start timestamp in milliseconds") endMS := flag.Int64("end-ms", 0, "exclusive end timestamp in milliseconds") timeframe := flag.String("timeframe", "8h", "bar timeframe (8h or 1d)") outDir := flag.String("out-dir", "", "CSV output directory") flag.Parse() if (*timeframe != "8h" && *timeframe != "1d") || *configPath == "" || *dataDir == "" || *pairs == "" || *outDir == "" || *startMS <= 0 || *endMS <= *startMS { flag.Usage() os.Exit(2) } args := &config.CmdArgs{ Configs: config.ArrString{*configPath}, DataDir: *dataDir, NoDefault: true, RawPairs: *pairs, TimeStart: strconv.FormatInt(*startMS, 10), TimeEnd: strconv.FormatInt(*endMS, 10), LogLevel: "error", } if err := biz.SetupComs(args); err != nil { fail(err) } defer core.RunExitCalls() if err := os.MkdirAll(*outDir, 0o755); err != nil { fail(err) } for _, rawPair := range strings.Split(*pairs, ",") { pair := strings.TrimSpace(rawPair) if pair == "" { continue } exs, err := orm.GetExSymbolCur(pair) if err != nil { fail(err) } _, rows, err := orm.GetSeries(exs, *timeframe, *startMS, *endMS, 0, false) if err != nil { fail(err) } name := fmt.Sprintf("%d_%s.csv", exs.ID, strings.NewReplacer("/", "_", ":", "_").Replace(pair)) if err := writeCSV(filepath.Join(*outDir, name), rows, exs); err != nil { fail(err) } } } func writeCSV(path string, rows []*orm.DataSeries, exs *orm.ExSymbol) error { file, err := os.Create(path) if err != nil { return err } defer file.Close() writer := csv.NewWriter(file) if err := writer.Write(columns); err != nil { return err } for _, row := range rows { bar, err := row.OHLCV(exs) if err != nil { return err } values := []string{ strconv.FormatInt(bar.Time, 10), strconv.FormatFloat(bar.Open, 'f', -1, 64), strconv.FormatFloat(bar.High, 'f', -1, 64), strconv.FormatFloat(bar.Low, 'f', -1, 64), strconv.FormatFloat(bar.Close, 'f', -1, 64), strconv.FormatFloat(bar.Volume, 'f', -1, 64), strconv.FormatFloat(bar.Quote, 'f', -1, 64), strconv.FormatFloat(bar.BuyVolume, 'f', -1, 64), strconv.FormatInt(bar.TradeNum, 10), } if err := writer.Write(values); err != nil { return err } } writer.Flush() return writer.Error() } func fail(err error) { fmt.Fprintln(os.Stderr, err) os.Exit(1) }