mirror of
https://github.com/c9s/bbgo.git
synced 2024-09-20 08:11:08 +00:00
add exchange field in the table so that we can reuse the kline objects for backtest
This commit is contained in:
parent
4b0bab31fb
commit
6bd3573287
|
@ -36,6 +36,22 @@ riskControls:
|
|||
minBaseAssetBalance: 0.1
|
||||
maxOrderAmount: 100.0
|
||||
|
||||
backtest:
|
||||
# for testing max draw down (MDD) at 03-12
|
||||
# see here for more details
|
||||
# https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp
|
||||
startTime: "2020-01-01"
|
||||
symbols:
|
||||
- BTCUSDT
|
||||
account:
|
||||
makerCommission: 15
|
||||
takerCommission: 15
|
||||
buyerCommission: 0
|
||||
sellerCommission: 0
|
||||
balances:
|
||||
BTC: 0.1
|
||||
USDT: 10000.0
|
||||
|
||||
exchangeStrategies:
|
||||
- on: binance
|
||||
buyandhold:
|
||||
|
|
|
@ -43,6 +43,22 @@ riskControls:
|
|||
minBaseAssetBalance: 0.0
|
||||
maxOrderAmount: 200.0
|
||||
|
||||
backtest:
|
||||
# for testing max draw down (MDD) at 03-12
|
||||
# see here for more details
|
||||
# https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp
|
||||
startTime: "2020-01-01"
|
||||
symbols:
|
||||
- BTCUSDT
|
||||
account:
|
||||
makerCommission: 15
|
||||
takerCommission: 15
|
||||
buyerCommission: 0
|
||||
sellerCommission: 0
|
||||
balances:
|
||||
BTC: 0.1
|
||||
USDT: 10000.0
|
||||
|
||||
exchangeStrategies:
|
||||
- on: max
|
||||
grid:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
CREATE TABLE `klines`
|
||||
(
|
||||
`gid` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
`exchange` VARCHAR(10) NOT NULL,
|
||||
`start_time` DATETIME(3) NOT NULL,
|
||||
`end_time` DATETIME(3) NOT NULL,
|
||||
`interval` VARCHAR(3) NOT NULL,
|
||||
|
@ -26,7 +26,7 @@ CREATE TABLE `binance_klines` LIKE `klines`;
|
|||
CREATE TABLE `max_klines` LIKE `klines`;
|
||||
|
||||
-- +goose Down
|
||||
DROP INDEX klines_start_time_symbol_interval ON `klines`;
|
||||
DROP INDEX `klines_end_time_symbol_interval` ON `klines`;
|
||||
DROP TABLE `binance_klines`;
|
||||
DROP TABLE `okex_klines`;
|
||||
DROP TABLE `max_klines`;
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
type Exchange struct {
|
||||
sourceExchange types.ExchangeName
|
||||
sourceName types.ExchangeName
|
||||
publicExchange types.Exchange
|
||||
srv *service.BacktestService
|
||||
startTime time.Time
|
||||
|
@ -30,8 +30,8 @@ type Exchange struct {
|
|||
doneC chan struct{}
|
||||
}
|
||||
|
||||
func NewExchange(sourceExchange types.ExchangeName, srv *service.BacktestService, config *bbgo.Backtest) *Exchange {
|
||||
ex, err := newPublicExchange(sourceExchange)
|
||||
func NewExchange(sourceName types.ExchangeName, srv *service.BacktestService, config *bbgo.Backtest) *Exchange {
|
||||
ex, err := newPublicExchange(sourceName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ func NewExchange(sourceExchange types.ExchangeName, srv *service.BacktestService
|
|||
account.UpdateBalances(balances)
|
||||
|
||||
e := &Exchange{
|
||||
sourceExchange: sourceExchange,
|
||||
sourceName: sourceName,
|
||||
publicExchange: ex,
|
||||
srv: srv,
|
||||
config: config,
|
||||
|
@ -171,7 +171,14 @@ func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap,
|
|||
}
|
||||
|
||||
func (e Exchange) QueryKLines(ctx context.Context, symbol string, interval types.Interval, options types.KLineQueryOptions) ([]types.KLine, error) {
|
||||
return e.publicExchange.QueryKLines(ctx, symbol, interval, options)
|
||||
if options.EndTime != nil {
|
||||
return e.srv.QueryKLinesBackward(e.sourceName, symbol, interval, *options.EndTime)
|
||||
}
|
||||
if options.StartTime != nil {
|
||||
return e.srv.QueryKLinesForward(e.sourceName, symbol, interval, *options.StartTime)
|
||||
}
|
||||
|
||||
return nil, errors.New("endTime or startTime can not be nil")
|
||||
}
|
||||
|
||||
func (e Exchange) QueryTrades(ctx context.Context, symbol string, options *types.TradeQueryOptions) ([]types.Trade, error) {
|
||||
|
|
|
@ -83,6 +83,38 @@ func (s *BacktestService) QueryLast(ex types.ExchangeName, symbol string, interv
|
|||
return nil, rows.Err()
|
||||
}
|
||||
|
||||
func (s *BacktestService) QueryKLinesForward(exchange types.ExchangeName, symbol string, interval types.Interval, startTime time.Time) ([]types.KLine, error) {
|
||||
sql := "SELECT * FROM `binance_klines` WHERE `end_time` >= :startTime AND `symbol` = :symbol AND `interval` = :interval ORDER BY end_time ASC"
|
||||
sql = strings.ReplaceAll(sql, "binance_klines", exchange.String()+"_klines")
|
||||
|
||||
rows, err := s.DB.NamedQuery(sql, map[string]interface{}{
|
||||
"startTime": startTime,
|
||||
"symbol": symbol,
|
||||
"interval": interval,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.scanRows(rows)
|
||||
}
|
||||
|
||||
func (s *BacktestService) QueryKLinesBackward(exchange types.ExchangeName, symbol string, interval types.Interval, endTime time.Time) ([]types.KLine, error) {
|
||||
sql := "SELECT * FROM `binance_klines` WHERE `end_time` <= :endTime AND `symbol` = :symbol AND `interval` = :interval ORDER BY end_time ASC"
|
||||
sql = strings.ReplaceAll(sql, "binance_klines", exchange.String()+"_klines")
|
||||
|
||||
rows, err := s.DB.NamedQuery(sql, map[string]interface{}{
|
||||
"endTime": endTime,
|
||||
"symbol": symbol,
|
||||
"interval": interval,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.scanRows(rows)
|
||||
}
|
||||
|
||||
func (s *BacktestService) QueryKLinesCh(since time.Time, exchange types.Exchange, symbols []string, intervals []types.Interval) (chan types.KLine, chan error) {
|
||||
sql := "SELECT * FROM `binance_klines` WHERE `end_time` >= :since AND `symbol` IN (:symbols) AND `interval` IN (:intervals) ORDER BY end_time ASC"
|
||||
sql = strings.ReplaceAll(sql, "binance_klines", exchange.Name().String()+"_klines")
|
||||
|
@ -160,8 +192,8 @@ func (s *BacktestService) Insert(kline types.KLine) error {
|
|||
return errors.New("kline.Exchange field should not be empty")
|
||||
}
|
||||
|
||||
sql := "INSERT INTO `binance_klines` (`start_time`, `end_time`, `symbol`, `interval`, `open`, `high`, `low`, `close`, `closed`, `volume`)" +
|
||||
"VALUES (:start_time, :end_time, :symbol, :interval, :open, :high, :low, :close, :closed, :volume)"
|
||||
sql := "INSERT INTO `binance_klines` (`exchange`, `start_time`, `end_time`, `symbol`, `interval`, `open`, `high`, `low`, `close`, `closed`, `volume`)" +
|
||||
"VALUES (:exchange, :start_time, :end_time, :symbol, :interval, :open, :high, :low, :close, :closed, :volume)"
|
||||
sql = strings.ReplaceAll(sql, "binance_klines", kline.Exchange+"_klines")
|
||||
|
||||
_, err := s.DB.NamedExec(sql, kline)
|
||||
|
|
|
@ -46,7 +46,7 @@ type KLineQueryOptions struct {
|
|||
// KLine uses binance's kline as the standard structure
|
||||
type KLine struct {
|
||||
GID uint64 `json:"gid" db:"gid"`
|
||||
Exchange string `json:"exchange"`
|
||||
Exchange string `json:"exchange" db:"exchange"`
|
||||
|
||||
Symbol string `json:"symbol" db:"symbol"`
|
||||
|
||||
|
@ -62,9 +62,9 @@ type KLine struct {
|
|||
Volume float64 `json:"volume" db:"volume"`
|
||||
QuoteVolume float64 `json:"quoteVolume" db:"quote_volume"`
|
||||
|
||||
LastTradeID uint64 `json:"lastTradeID" db:"last_trade_id"`
|
||||
LastTradeID uint64 `json:"lastTradeID" db:"last_trade_id"`
|
||||
NumberOfTrades uint64 `json:"numberOfTrades" db:"num_trades"`
|
||||
Closed bool `json:"closed" db:"closed"`
|
||||
Closed bool `json:"closed" db:"closed"`
|
||||
}
|
||||
|
||||
func (k KLine) GetStartTime() time.Time {
|
||||
|
|
Loading…
Reference in New Issue
Block a user