diff --git a/config/config.go b/config/config.go index c5583de8..1191eacc 100644 --- a/config/config.go +++ b/config/config.go @@ -1176,8 +1176,9 @@ func (c *Config) CheckLoggerConfig() error { } log.FileLoggingConfiguredCorrectly = true } - + log.RWM.Lock() log.GlobalLogConfig = &c.Logging + log.RWM.Unlock() logPath := filepath.Join(common.GetDefaultDataDir(runtime.GOOS), "logs") err := common.CreateDir(logPath) diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index 9844a401..f379cce9 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -16,6 +16,8 @@ import ( "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/request" "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" ) @@ -161,21 +163,33 @@ func (b *BTCMarkets) GetOrderbook(marketID string, level int64) (Orderbook, erro } // GetMarketCandles gets candles for specified currency pair -func (b *BTCMarkets) GetMarketCandles(marketID, timeWindow, from, to string, before, after, limit int64) ([]MarketCandle, error) { +func (b *BTCMarkets) GetMarketCandles(marketID string, timeWindow time.Duration, from, to time.Time, before, after, limit int64) (kline.Item, error) { if (before > 0) && (after >= 0) { - return nil, errors.New("BTCMarkets only supports either before or after, not both") + return kline.Item{}, errors.New("BTCMarkets only supports either before or after, not both") } - var marketCandles []MarketCandle var temp [][]string params := url.Values{} - if timeWindow != "" { - params.Set("timeWindow", timeWindow) + + var intervalStr string + switch timeWindow { + case kline.OneMin: + intervalStr = "1m" + case kline.OneHour: + intervalStr = "1h" + case kline.OneDay: + intervalStr = "1d" + default: + return kline.Item{}, errInvalidTimeInterval } - if from != "" { - params.Set("from", from) + + if timeWindow != 0 { + params.Set("timeWindow", intervalStr) } - if to != "" { - params.Set("to", to) + if !from.IsZero() { + params.Set("from", from.UTC().Format(time.RFC3339)) + } + if !to.IsZero() { + params.Set("to", to.UTC().Format(time.RFC3339)) } if before > 0 { params.Set("before", strconv.FormatInt(before, 10)) @@ -189,39 +203,46 @@ func (b *BTCMarkets) GetMarketCandles(marketID, timeWindow, from, to string, bef err := b.SendHTTPRequest(btcMarketsUnauthPath+marketID+btcMarketsCandles+params.Encode(), &temp) if err != nil { - return marketCandles, err + return kline.Item{}, err } - var tempData MarketCandle + ret := kline.Item{ + Exchange: b.Name, + Pair: currency.NewPairFromString(marketID), + Asset: asset.Spot, + Interval: timeWindow, + } + + var tempData kline.Candle var tempTime time.Time for x := range temp { tempTime, err = time.Parse(time.RFC3339, temp[x][0]) if err != nil { - return marketCandles, err + return kline.Item{}, err } tempData.Time = tempTime tempData.Open, err = strconv.ParseFloat(temp[x][1], 64) if err != nil { - return marketCandles, err + return kline.Item{}, err } tempData.High, err = strconv.ParseFloat(temp[x][2], 64) if err != nil { - return marketCandles, err + return kline.Item{}, err } tempData.Low, err = strconv.ParseFloat(temp[x][3], 64) if err != nil { - return marketCandles, err + return kline.Item{}, err } tempData.Close, err = strconv.ParseFloat(temp[x][4], 64) if err != nil { - return marketCandles, err + return kline.Item{}, err } tempData.Volume, err = strconv.ParseFloat(temp[x][5], 64) if err != nil { - return marketCandles, err + return kline.Item{}, err } - marketCandles = append(marketCandles, tempData) + ret.Candles = append(ret.Candles, tempData) } - return marketCandles, nil + return ret, nil } // GetTickers gets multiple tickers diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index 78d55b9d..c5c3be6f 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -1,14 +1,17 @@ package btcmarkets import ( + "errors" "fmt" "log" "os" "testing" + "time" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues" ) @@ -97,7 +100,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetMarketCandles(t *testing.T) { t.Parallel() - _, err := b.GetMarketCandles(BTCAUD, "", "", "", 0, 0, 5) + _, err := b.GetMarketCandles(BTCAUD, kline.OneHour, time.Now().UTC().Add(-time.Hour*24), time.Now().UTC(), -1, -1, -1) if err != nil { t.Error(err) } @@ -715,3 +718,17 @@ func TestWsOrders(t *testing.T) { t.Error(err) } } + +func TestBTCMarkets_GetHistoricCandles(t *testing.T) { + p := currency.NewPairFromString(BTCAUD) + _, err := b.GetHistoricCandles(p, asset.Spot, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.OneHour) + if err != nil { + t.Fatal(err) + } + _, err = b.GetHistoricCandles(p, asset.Spot, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.FifteenMin) + if err != nil { + if !errors.Is(err, errInvalidTimeInterval) { + t.Fatal(err) + } + } +} diff --git a/exchanges/btcmarkets/btcmarkets_types.go b/exchanges/btcmarkets/btcmarkets_types.go index 6fdb5fc0..d79f3b4a 100644 --- a/exchanges/btcmarkets/btcmarkets_types.go +++ b/exchanges/btcmarkets/btcmarkets_types.go @@ -1,6 +1,11 @@ package btcmarkets -import "time" +import ( + "errors" + "time" +) + +var errInvalidTimeInterval = errors.New("invalid time interval") // Market holds a tradable market instrument type Market struct { diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index b85f97f9..dd50de0b 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -745,5 +745,5 @@ func (b *BTCMarkets) ValidateCredentials() error { // GetHistoricCandles returns candles between a time period for a set time interval func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { - return kline.Item{}, common.ErrNotYetImplemented + return b.GetMarketCandles(pair.String(), interval, start, end, -1, -1, 0) } diff --git a/log/logger_types.go b/log/logger_types.go index ce5d9903..c18664aa 100644 --- a/log/logger_types.go +++ b/log/logger_types.go @@ -31,6 +31,9 @@ var ( // LogPath system path to store log files in LogPath string + + // RWM read/write mutex for logger + RWM = &sync.RWMutex{} ) // Config holds configuration settings loaded from bot config diff --git a/log/loggers.go b/log/loggers.go index 5a6dea53..2bcd4e54 100644 --- a/log/loggers.go +++ b/log/loggers.go @@ -168,6 +168,8 @@ func displayError(err error) { } func enabled() bool { + RWM.RLock() + defer RWM.RUnlock() if GlobalLogConfig.Enabled == nil { return false }