trade/pkg/ctl/download.go
2024-06-26 00:19:25 +08:00

164 lines
4.1 KiB
Go

package ctl
import (
"fmt"
"time"
"git.qtrade.icu/coin-quant/exchange"
"git.qtrade.icu/coin-quant/trade/pkg/process/dbstore"
"git.qtrade.icu/coin-quant/trademodel"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
type DataDownload struct {
exchange string
start time.Time
end time.Time
binSize string
symbol string
running bool
stop chan bool
bInit bool
db *dbstore.DBStore
cfg *viper.Viper
isAuto bool
}
// NewDataDownloadAuto constructor of DataDownload
func NewDataDownloadAuto(cfg *viper.Viper, db *dbstore.DBStore, exchange, symbol, binSize string) (d *DataDownload) {
d = new(DataDownload)
d.cfg = cfg
d.exchange = exchange
d.symbol = symbol
d.binSize = binSize
d.db = db
d.isAuto = true
return
}
// NewDataDownload constructor of DataDownload
func NewDataDownload(cfg *viper.Viper, db *dbstore.DBStore, exchange, symbol, binSize string, start time.Time, end time.Time) (d *DataDownload) {
d = new(DataDownload)
d.cfg = cfg
d.start = start
d.end = end
d.exchange = exchange
d.symbol = symbol
d.binSize = binSize
d.db = db
return
}
func (d *DataDownload) SetBinSize(binSize string) {
d.binSize = binSize
}
// Start start backtest
func (d *DataDownload) Start() (err error) {
d.running = true
go d.Run()
return
}
// Stop stop backtest
func (d *DataDownload) Stop() (err error) {
d.stop <- true
return
}
func (d *DataDownload) AutoRun() (err error) {
tbl := d.db.GetKlineTbl(d.exchange, d.symbol, d.binSize)
var invalidTime time.Time
var tmTemp, start time.Time
start = time.Now()
tmTemp = tbl.GetNewest()
if tmTemp == invalidTime {
err = fmt.Errorf("no start found in db,you must set start time")
return
}
// log.Info(k, "temp time newest:", tmTemp)
if tmTemp.Sub(start) < 0 {
start = tmTemp.Add(-time.Minute)
}
end := time.Now()
log.Debugf("autorun start:%s, end:%s", start, end)
err = d.download(start, end)
return
}
// Run run backtest and wait for finish
func (d *DataDownload) Run() (err error) {
if d.isAuto {
err = d.AutoRun()
} else {
err = d.download(d.start, d.end)
}
return
}
func (d *DataDownload) download(start, end time.Time) (err error) {
log.Info("begin download candle:", start, end, d.symbol, d.binSize)
exchangeType := viper.GetString(fmt.Sprintf("exchanges.%s.name", d.exchange))
fmt.Println(d.exchange, exchangeType)
ex, err := exchange.NewExchange(exchangeType, exchange.WrapViper(d.cfg), d.exchange)
if err != nil {
return
}
tbl := d.db.GetKlineTbl(d.exchange, d.symbol, d.binSize)
klines, errChan := exchange.KlineChan(ex, d.symbol, d.binSize, start, end)
var t time.Time
cache := make([]interface{}, 1024)
i := 0
for v := range klines {
cache[i] = v
i++
t = time.Now()
if i >= 1024 {
err = tbl.WriteDatas(cache)
if err != nil {
fmt.Printf("write %s - %s error: %s\n", cache[0].(*trademodel.Candle).Time(), cache[i-1].(*trademodel.Candle).Time(), err.Error())
log.Errorf("%s write error: %s value: %#v %s", time.Now().Format(time.RFC3339), time.Since(t), v, err.Error())
return
} else {
fmt.Printf("write %s - %s success\n", cache[0].(*trademodel.Candle).Time(), cache[i-1].(*trademodel.Candle).Time())
}
i = 0
}
// log.Infof("%s write finish: %s len: %d ", time.Now().Format(time.RFC3339), time.Since(t), len(v))
}
if i > 0 {
err = tbl.WriteDatas(cache[0:i])
if err != nil {
fmt.Printf("write %s - %s error: %s\n", cache[0].(*trademodel.Candle).Time(), cache[i-1].(*trademodel.Candle).Time(), err.Error())
log.Errorf("%s write error: %s value: %#v %s", time.Now().Format(time.RFC3339), time.Since(t), len(cache), err.Error())
return
} else {
fmt.Printf("write %s - %s success\n", cache[0].(*trademodel.Candle).Time(), cache[i-1].(*trademodel.Candle).Time())
}
}
err = <-errChan
// log.Debugf("%s-%s %s %s %s data total %d stored\n", gStart,
// lastStart,
// d.source,
// d.symbol,
// d.binSize,
// total)
return
}
// Progress return the progress of current backtest
func (d *DataDownload) Progress() (progress int) {
return d.Progress()
}
// Result return the result of current backtest
// must call after end of the backtest
func (d *DataDownload) Result() (err error) {
return
}