ftx: add basic exchange order execution limits for lower bound (#725)

* ftx: add basic exchange order execution limits for lower bound

* ftx/binance: conform to standard logger output

* ftx: fix field from SizeIncrement -> MinProvideSize

* limits: fix whoopsie

* limit: add tests

* ftx: fix comment
This commit is contained in:
Ryan O'Hara-Reid
2021-07-29 09:15:02 +10:00
committed by GitHub
parent a6e158ab0c
commit 9ea72f2193
7 changed files with 163 additions and 22 deletions

View File

@@ -17,6 +17,7 @@ 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/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
)
@@ -1378,3 +1379,46 @@ func (f *FTX) SubaccountTransfer(coin currency.Code, source, destination string,
}
return &resp.Data, nil
}
// FetchExchangeLimits fetches spot order execution limits
func (f *FTX) FetchExchangeLimits() ([]order.MinMaxLevel, error) {
data, err := f.GetMarkets()
if err != nil {
return nil, err
}
var limits []order.MinMaxLevel
for x := range data {
if !data[x].Enabled {
continue
}
var cp currency.Pair
var a asset.Item
switch data[x].MarketType {
case "future":
a = asset.Futures
cp, err = currency.NewPairFromString(data[x].Name)
if err != nil {
return nil, err
}
case "spot":
a = asset.Spot
cp, err = currency.NewPairFromStrings(data[x].BaseCurrency, data[x].QuoteCurrency)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unhandled data type %s, cannot process exchange limit",
data[x].MarketType)
}
limits = append(limits, order.MinMaxLevel{
Pair: cp,
Asset: a,
StepPrice: data[x].PriceIncrement,
StepAmount: data[x].SizeIncrement,
MinAmount: data[x].MinProvideSize,
})
}
return limits, nil
}

View File

@@ -1679,3 +1679,29 @@ func TestStakeRequest(t *testing.T) {
t.Error(err)
}
}
func TestUpdateOrderExecutionLimits(t *testing.T) {
err := f.UpdateOrderExecutionLimits("")
if err != nil {
t.Fatal(err)
}
cp := currency.NewPair(currency.BTC, currency.USD)
limit, err := f.GetOrderExecutionLimits(asset.Spot, cp)
if err != nil {
t.Fatal(err)
}
err = limit.Conforms(33000, 0.00001, order.Limit)
if !errors.Is(err, order.ErrAmountBelowMin) {
t.Fatalf("expected error %v but received %v",
order.ErrAmountBelowMin,
err)
}
err = limit.Conforms(33000, 0.0001, order.Limit)
if !errors.Is(err, nil) {
t.Fatalf("expected error %v but received %v",
nil,
err)
}
}

View File

@@ -55,24 +55,27 @@ type LendingInfoData struct {
// MarketData stores market data
type MarketData struct {
Name string `json:"name"`
BaseCurrency string `json:"baseCurrency"`
QuoteCurrency string `json:"quoteCurrency"`
MarketType string `json:"type"`
Underlying string `json:"underlying"`
Change1h float64 `json:"change1h"`
Change24h float64 `json:"change24h"`
ChangeBod float64 `json:"changeBod"`
QuoteVolume24h float64 `json:"quoteVolume24h"`
Enabled bool `json:"enabled"`
Ask float64 `json:"ask"`
Bid float64 `json:"bid"`
Last float64 `json:"last"`
USDVolume24h float64 `json:"volumeUSD24h"`
MinProvideSize float64 `json:"minProvideSize"`
PriceIncrement float64 `json:"priceIncrement"`
SizeIncrement float64 `json:"sizeIncrement"`
Restricted bool `json:"restricted"`
Name string `json:"name"`
BaseCurrency string `json:"baseCurrency"`
QuoteCurrency string `json:"quoteCurrency"`
MarketType string `json:"type"`
Underlying string `json:"underlying"`
Change1h float64 `json:"change1h"`
Change24h float64 `json:"change24h"`
ChangeBod float64 `json:"changeBod"`
QuoteVolume24h float64 `json:"quoteVolume24h"`
Enabled bool `json:"enabled"`
Ask float64 `json:"ask"`
Bid float64 `json:"bid"`
Last float64 `json:"last"`
USDVolume24h float64 `json:"volumeUSD24h"`
MinProvideSize float64 `json:"minProvideSize"`
PriceIncrement float64 `json:"priceIncrement"`
SizeIncrement float64 `json:"sizeIncrement"`
Restricted bool `json:"restricted"`
PostOnly bool `json:"postOnly"`
Price float64 `json:"price"`
HighLeverageFeeExempt bool `json:"highLeverageFeeExempt"`
}
// OData stores orderdata in orderbook

View File

@@ -218,11 +218,19 @@ func (f *FTX) Run() {
f.PrintEnabledPairs()
}
err := f.UpdateOrderExecutionLimits("")
if err != nil {
log.Errorf(log.ExchangeSys,
"%s failed to set exchange order execution limits. Err: %v",
f.Name,
err)
}
if !f.GetEnabledFeatures().AutoPairUpdates {
return
}
err := f.UpdateTradablePairs(false)
err = f.UpdateTradablePairs(false)
if err != nil {
log.Errorf(log.ExchangeSys,
"%s failed to update tradable pairs. Err: %s",
@@ -1113,3 +1121,12 @@ func (f *FTX) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, e
ret.SortCandlesByTimestamp(false)
return ret, nil
}
// UpdateOrderExecutionLimits sets exchange executions for a required asset type
func (f *FTX) UpdateOrderExecutionLimits(_ asset.Item) error {
limits, err := f.FetchExchangeLimits()
if err != nil {
return fmt.Errorf("cannot update exchange execution limits: %w", err)
}
return f.LoadLimits(limits)
}