Files
gocryptotrader/exchanges/kline/kline_test.go
Andrew 4a736fb335 (Exchange) Add GetHistoricCandles() & GetHistoricCandlesEx() support to exchanges (#479)
* implemented binance and bitfinex GetHistoricCandles wrapper methods)

* coinbene supported added

* after and before clean up

* gateio wrapper completed

* merged upstream/master

* Added bsaic KlineIntervalSupported() method

* Converted binance fixed test

* WIP

* new KlineConvertToExchangeStandardString method added

* end of day WIP

* WIP

* end of day WIP started migration of trade history

* added kline support to hitbtc huobi lbank

* added exchangehistory to all supported exchanges started work on coinbase 300 candles/request method

* end of day WIP

* removed unused ta and misc changes to flag ready for review

* yobit cleanup

* revert coinbase changES

* general code clean up and added zb support

* poloniex support added

* renamed method to FormatExchangeKlineInterval other misc fixes

* linter fixes

* linter fixes

* removed verbose

* fixed poloniex test coverage

* revert poloniex mock data

* regenerated poloniex mock data

* a very verbose clean up

* binance mock clean up

* removed unneeded t.Log()

* setting verbose to true to debug CI issue

* first pass changes addressed

* common.ErrNotYetImplemented implemented :D

* comments added

* WIP-addressed exchange requests and reverted previous GetExchangeHistory changes

* WIP-addressed exchange requests and reverted previous GetExchangeHistory changes

* increased test coverage added kraken support

* OKGroup support completed started work on address GetExchangeHistory feedback and migrating to own PR under https://github.com/xtda/gocryptotrader/tree/exchange_history

* convert zb ratelimits

* gofmt run on okcoin

* increased delay on rate limit

* gofmt package

* fixed panic with coinbene and bithumb if conversion fails

* very broken end of day WIP

* added support for GetHistoricCandlesEx to coinbase and binance

* gofmt package

* coinbase, btcmarkets, zb ex wrapper function added

* added all exchange support for ex regenerated mock data

* update bithumb to return wrapper method

* gofmt package

* end of day started work on changes

* reworked test coverage added okgroup support general fixes/change requests addressed

* Added OneMonth

* limit checks on supportedexchanges

* reverted getexchangehistory

* reworked binance tesT

* added workaround for kraken panic

* renamed command to extended removed interval check on non-implemented commands

* added wrapperconfig back

* increased test coverage for FormatExchangeKlineInterval

* WIP

* increased test coverage for FormatExchangeKlineInterval bitfinex/gateio/huobi

* linter fixes

* zb kraken lbank coinbene btcmarkets support added

* removed verbose

* OK group support for other asset types added

* swapped margin to use spot endpoint

* index support added test coverage added for asset types

* added asset type to okcoin test

* gofmt

* add asset to extended method

* removed verbose

* add support for coinbene swap increase test coverage

* removed verbose

* small clean up of okgroup wrapper functions

* verbose to troubleshoot CI issues

* removed verbose

* added error check reverted coinbasechanges

* readme updated

* removed unused start/finish started work on decoupling api requests from kline package

* restructured coinbene, bithumb methods, added bitstamp support

* kraken time fix

* BTCMarkets restructure

* typo fix

* removed test for futures due to contact changing

* added start/end date to extended method over range

* converted to assettranslator

* removed verbose

* removed invalid char

* reverted incorrectly removed return

* added import

* further template updates

* macos hates my keyboard :D

* misc canges

* x -> i

* removed verbose

* updated fixCasing to allocate var before checks

* removed time conversion

* sort all outgoing kline candles

* fixCasing fix

* after/before checks added

* added parallel to test

* logic check on BTCmarkets

* removed unused param, used correct iterator

* converted HitBTC to use time.Time

* add iszero false check to candle times

* updated resultlimit to 5000

* new line added

* added comment to exported const

* use configured ratelimit

* fixed pair for test

* panic fixed WIP on fixCasing

* fixCasing rework, started work on readme docs

* enable rate limiter for wrapper issues tool

* docs updated

* removed err from return and formatted currency

* updated Yobit supported status

* Updated HitBTC to use onehour candles due to test exeuction times

* added further details to gctcli output

* added link to docs

* added link to tempalte

* disable FTX websocket in config_example

* fix poloneix

* regenerated poloniex mock data

* removed recording flag
2020-07-08 10:51:54 +10:00

304 lines
5.9 KiB
Go

package kline
import (
"math/rand"
"strings"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
)
func TestValidateData(t *testing.T) {
err := validateData(nil)
if err == nil {
t.Error("error cannot be nil")
}
var empty []order.TradeHistory
err = validateData(empty)
if err == nil {
t.Error("error cannot be nil")
}
tn := time.Now()
trade1 := []order.TradeHistory{
{Timestamp: tn.Add(2 * time.Minute), TID: "2"},
{Timestamp: tn.Add(time.Minute), TID: "1"},
{Timestamp: tn.Add(3 * time.Minute), TID: "3"},
}
err = validateData(trade1)
if err == nil {
t.Error("error cannot be nil")
}
trade2 := []order.TradeHistory{
{Timestamp: tn.Add(2 * time.Minute), TID: "2", Amount: 1, Price: 0},
}
err = validateData(trade2)
if err == nil {
t.Error("error cannot be nil")
}
trade3 := []order.TradeHistory{
{TID: "2", Amount: 1, Price: 0},
}
err = validateData(trade3)
if err == nil {
t.Error("error cannot be nil")
}
trade4 := []order.TradeHistory{
{Timestamp: tn.Add(2 * time.Minute), TID: "2", Amount: 1, Price: 1000},
{Timestamp: tn.Add(time.Minute), TID: "1", Amount: 1, Price: 1001},
{Timestamp: tn.Add(3 * time.Minute), TID: "3", Amount: 1, Price: 1001.5},
}
err = validateData(trade4)
if err != nil {
t.Error(err)
}
if trade4[0].TID != "1" || trade4[1].TID != "2" || trade4[2].TID != "3" {
t.Error("trade history sorted incorrectly")
}
}
func TestCreateKline(t *testing.T) {
c, err := CreateKline(nil,
OneMin,
currency.NewPair(currency.BTC, currency.USD),
asset.Spot,
"Binance")
if err == nil {
t.Fatal("error cannot be nil")
}
var trades []order.TradeHistory
rand.Seed(time.Now().Unix())
for i := 0; i < 24000; i++ {
trades = append(trades, order.TradeHistory{
Timestamp: time.Now().Add((time.Duration(rand.Intn(10)) * time.Minute) +
(time.Duration(rand.Intn(10)) * time.Second)),
TID: crypto.HexEncodeToString([]byte(string(i))),
Amount: float64(rand.Intn(20)) + 1,
Price: 1000 + float64(rand.Intn(1000)),
})
}
c, err = CreateKline(trades,
0,
currency.NewPair(currency.BTC, currency.USD),
asset.Spot,
"Binance")
if err == nil {
t.Fatal("error cannot be nil")
}
c, err = CreateKline(trades,
OneMin,
currency.NewPair(currency.BTC, currency.USD),
asset.Spot,
"Binance")
if err != nil {
t.Fatal(err)
}
if len(c.Candles) == 0 {
t.Fatal("no data returned, expecting a lot.")
}
}
func TestKlineWord(t *testing.T) {
if OneDay.Word() != "oneday" {
t.Fatalf("unexpected result: %v", OneDay.Word())
}
}
func TestKlineDuration(t *testing.T) {
if OneDay.Duration() != time.Hour*24 {
t.Fatalf("unexpected result: %v", OneDay.Duration())
}
}
func TestKlineShort(t *testing.T) {
if OneDay.Short() != "24h" {
t.Fatalf("unexpected result: %v", OneDay.Short())
}
}
func TestDurationToWord(t *testing.T) {
testCases := []struct {
name string
interval Interval
}{
{
"OneMin",
OneMin,
},
{
"ThreeMin",
ThreeMin,
},
{
"FiveMin",
FiveMin,
},
{
"TenMin",
TenMin,
},
{
"FifteenMin",
FifteenMin,
},
{
"ThirtyMin",
ThirtyMin,
},
{
"OneHour",
OneHour,
},
{
"TwoHour",
TwoHour,
},
{
"FourHour",
FourHour,
},
{
"SixHour",
SixHour,
},
{
"EightHour",
OneHour * 8,
},
{
"TwelveHour",
TwelveHour,
},
{
"OneDay",
OneDay,
},
{
"ThreeDay",
ThreeDay,
},
{
"FifteenDay",
FifteenDay,
},
{
"OneWeek",
OneWeek,
},
{
"TwoWeek",
TwoWeek,
},
{
"OneMonth",
OneMonth,
},
{
"notfound",
Interval(time.Hour * 1337),
},
}
for x := range testCases {
test := testCases[x]
t.Run(test.name, func(t *testing.T) {
v := durationToWord(test.interval)
if !strings.EqualFold(v, test.name) {
t.Fatalf("%v: received %v expected %v", test.name, v, test.name)
}
})
}
}
func TestKlineErrors(t *testing.T) {
v := ErrorKline{
Interval: OneYear,
}
if v.Error() != "oneyear interval unsupported by exchange" {
t.Fatal("unexpected error returned")
}
if v.Unwrap().Error() != "8760h0m0s interval unsupported by exchange" {
t.Fatal("unexpected error returned")
}
}
func TestTotalCandlesPerInterval(t *testing.T) {
end := time.Now()
start := end.AddDate(-1, 0, 0)
v := TotalCandlesPerInterval(start, end, OneYear)
if v != 1 {
t.Fatalf("unexpected result expected 1 received %v", v)
}
v = TotalCandlesPerInterval(start, end, FifteenDay)
if v != 24 {
t.Fatalf("unexpected result expected 24 received %v", v)
}
}
func TestCalcDateRanges(t *testing.T) {
start := time.Unix(1546300800, 0)
end := time.Unix(1577836799, 0)
v := CalcDateRanges(start, end, OneMin, 300)
if v[0].Start.Unix() != time.Unix(1546300800, 0).Unix() {
t.Fatalf("unexpected result received %v", v[0].Start.Unix())
}
v = CalcDateRanges(time.Now(), time.Now().AddDate(0, 0, 1), OneDay, 100)
if len(v) != 1 {
t.Fatal("expected CalcDateRanges() with a Candle count lower than limit to return 1 result")
}
}
func TestItem_SortCandlesByTimestamp(t *testing.T) {
var tempKline = Item{
Exchange: "testExchange",
Pair: currency.NewPair(currency.BTC, currency.USDT),
Asset: asset.Spot,
Interval: OneDay,
}
for x := 0; x < 100; x++ {
y := rand.Float64()
tempKline.Candles = append(tempKline.Candles,
Candle{
Time: time.Now().AddDate(0, 0, -x),
Open: y,
High: y + float64(x),
Low: y - float64(x),
Close: y,
Volume: y,
})
}
tempKline.SortCandlesByTimestamp(false)
if tempKline.Candles[0].Time.After(tempKline.Candles[1].Time) {
t.Fatal("expected kline.Candles to be in descending order")
}
tempKline.SortCandlesByTimestamp(true)
if tempKline.Candles[0].Time.Before(tempKline.Candles[1].Time) {
t.Fatal("expected kline.Candles to be in ascending order")
}
}