futures: Implement GetLatestFundingRates across exchanges (#1339)

* adds funding rate implementations and improvements

* merge fixes x1

* lint

* kucoin funding rates func make

* migrate sync-manager to keys

* some kucoin work

* adds some kucoin wrapper funcs

* ehhh, todo

* kucoin position

* start of orders

* adds the kucoin tests yay

* multiplier

* nits, EWS includes order limits

* NotYetImplemented, IsPerp improvements, cleaning

* lint, test fix, huobi time

* fixes issues, improves testing

* fixes linters I WRECKED

* local lint but remote lint, lint, lint, lint

* fixes err

* skip CI

* lint

* Supported rates, binance endpoints

* fixes weird mocktest problems

* no, CZ is invalid

* fixes some new EWS test errors
This commit is contained in:
Scott
2023-11-03 10:01:32 +10:00
committed by GitHub
parent f9437dbd08
commit 70690d9a04
78 changed files with 4088 additions and 527 deletions

View File

@@ -42,17 +42,19 @@ var (
// ErrMarketAmountExceedsStep is when the amount is not divisible by its
// step for a market order
ErrMarketAmountExceedsStep = errors.New("market order amount exceeds step limit")
// ErrCannotValidateAsset is thrown when the asset is not loaded
ErrCannotValidateAsset = errors.New("cannot check limit, asset not loaded")
// ErrCannotValidateBaseCurrency is thrown when the base currency is not loaded
ErrCannotValidateBaseCurrency = errors.New("cannot check limit, base currency not loaded")
// ErrCannotValidateQuoteCurrency is thrown when the quote currency is not loaded
ErrCannotValidateQuoteCurrency = errors.New("cannot check limit, quote currency not loaded")
errCannotValidateAsset = errors.New("cannot check limit, asset not loaded")
errCannotValidateBaseCurrency = errors.New("cannot check limit, base currency not loaded")
errCannotValidateQuoteCurrency = errors.New("cannot check limit, quote currency not loaded")
errExchangeLimitAsset = errors.New("exchange limits not found for asset")
errExchangeLimitBase = errors.New("exchange limits not found for base currency")
errExchangeLimitQuote = errors.New("exchange limits not found for quote currency")
errCannotLoadLimit = errors.New("cannot load limit, levels not supplied")
errInvalidPriceLevels = errors.New("invalid price levels, cannot load limits")
errInvalidAmountLevels = errors.New("invalid amount levels, cannot load limits")
errInvalidQuoteLevels = errors.New("invalid quote levels, cannot load limits")
errExchangeLimitBase = errors.New("exchange limits not found for base currency")
errExchangeLimitQuote = errors.New("exchange limits not found for quote currency")
errCannotLoadLimit = errors.New("cannot load limit, levels not supplied")
errInvalidPriceLevels = errors.New("invalid price levels, cannot load limits")
errInvalidAmountLevels = errors.New("invalid amount levels, cannot load limits")
errInvalidQuoteLevels = errors.New("invalid quote levels, cannot load limits")
)
// ExecutionLimits defines minimum and maximum values in relation to
@@ -171,7 +173,7 @@ func (e *ExecutionLimits) GetOrderExecutionLimits(a asset.Item, cp currency.Pair
m1, ok := e.m[a]
if !ok {
return MinMaxLevel{}, fmt.Errorf("%w %v", errExchangeLimitAsset, a)
return MinMaxLevel{}, fmt.Errorf("%w %v", ErrCannotValidateAsset, a)
}
m2, ok := m1[cp.Base.Item]
@@ -200,17 +202,17 @@ func (e *ExecutionLimits) CheckOrderExecutionLimits(a asset.Item, cp currency.Pa
m1, ok := e.m[a]
if !ok {
return errCannotValidateAsset
return ErrCannotValidateAsset
}
m2, ok := m1[cp.Base.Item]
if !ok {
return errCannotValidateBaseCurrency
return ErrCannotValidateBaseCurrency
}
limit, ok := m2[cp.Quote.Item]
if !ok {
return errCannotValidateQuoteCurrency
return ErrCannotValidateQuoteCurrency
}
err := limit.Conforms(price, amount, orderType)

View File

@@ -166,8 +166,8 @@ func TestGetOrderExecutionLimits(t *testing.T) {
}
_, err = e.GetOrderExecutionLimits(asset.Futures, ltcusd)
if !errors.Is(err, errExchangeLimitAsset) {
t.Fatalf("expected error %v but received %v", errExchangeLimitAsset, err)
if !errors.Is(err, ErrCannotValidateAsset) {
t.Fatalf("expected error %v but received %v", ErrCannotValidateAsset, err)
}
_, err = e.GetOrderExecutionLimits(asset.Spot, ltcusd)
@@ -218,18 +218,18 @@ func TestCheckLimit(t *testing.T) {
}
err = e.CheckOrderExecutionLimits(asset.Futures, ltcusd, 1337, 1337, Limit)
if !errors.Is(err, errCannotValidateAsset) {
t.Fatalf("expected error %v but received %v", errCannotValidateAsset, err)
if !errors.Is(err, ErrCannotValidateAsset) {
t.Fatalf("expected error %v but received %v", ErrCannotValidateAsset, err)
}
err = e.CheckOrderExecutionLimits(asset.Spot, ltcusd, 1337, 1337, Limit)
if !errors.Is(err, errCannotValidateBaseCurrency) {
t.Fatalf("expected error %v but received %v", errCannotValidateBaseCurrency, err)
if !errors.Is(err, ErrCannotValidateBaseCurrency) {
t.Fatalf("expected error %v but received %v", ErrCannotValidateBaseCurrency, err)
}
err = e.CheckOrderExecutionLimits(asset.Spot, btcltc, 1337, 1337, Limit)
if !errors.Is(err, errCannotValidateQuoteCurrency) {
t.Fatalf("expected error %v but received %v", errCannotValidateQuoteCurrency, err)
if !errors.Is(err, ErrCannotValidateQuoteCurrency) {
t.Fatalf("expected error %v but received %v", ErrCannotValidateQuoteCurrency, err)
}
err = e.CheckOrderExecutionLimits(asset.Spot, btcusd, 1337, 9, Limit)

View File

@@ -1417,7 +1417,7 @@ func TestMatchFilter(t *testing.T) {
if err != nil {
t.Fatal(err)
}
filters := map[int]Filter{
filters := map[int]*Filter{
0: {},
1: {Exchange: "Binance"},
2: {InternalOrderID: id},
@@ -1460,13 +1460,13 @@ func TestMatchFilter(t *testing.T) {
// empty filter tests
emptyFilter := filters[0]
for _, o := range orders {
if !o.MatchFilter(&emptyFilter) {
if !o.MatchFilter(emptyFilter) {
t.Error("empty filter should match everything")
}
}
tests := map[int]struct {
f Filter
f *Filter
o Detail
expectedResult bool
}{
@@ -1515,7 +1515,7 @@ func TestMatchFilter(t *testing.T) {
tt := tt
t.Run(fmt.Sprintf("%v", num), func(t *testing.T) {
t.Parallel()
if tt.o.MatchFilter(&tt.f) != tt.expectedResult {
if tt.o.MatchFilter(tt.f) != tt.expectedResult {
t.Errorf("tests[%v] failed", num)
}
})