mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
OKX: Support exchange order limits (#1186)
* OKX: Support exchange order limits Adds support for PriceStepIncrementSize and MinAmount limits * OKX: Test UpdateOrderExecutionLimits on all assets * OKX: Added asset types for order limit tests
This commit is contained in:
@@ -1847,6 +1847,63 @@ func TestUpdateTradablePairs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type limitTest struct {
|
||||
pair currency.Pair
|
||||
step float64
|
||||
min float64
|
||||
}
|
||||
|
||||
tests := map[asset.Item][]limitTest{
|
||||
asset.Spot: {
|
||||
{currency.NewPair(currency.ETH, currency.USDT), 0.01, 0.0001},
|
||||
{currency.NewPair(currency.BTC, currency.USDT), 0.1, 0.00001},
|
||||
},
|
||||
asset.Margin: {
|
||||
{currency.NewPair(currency.ETH, currency.USDT), 0.01, 0.0001},
|
||||
{currency.NewPair(currency.ETH, currency.BTC), 0.00001, 0.0001},
|
||||
},
|
||||
}
|
||||
|
||||
for _, a := range []asset.Item{asset.PerpetualSwap, asset.Futures, asset.Options} {
|
||||
pairs, err := ok.FetchTradablePairs(context.Background(), a)
|
||||
if err != nil {
|
||||
t.Errorf("Error fetching dated %s pairs for test: %v", a, err)
|
||||
}
|
||||
stepIncr := 0.1
|
||||
if a == asset.Options {
|
||||
stepIncr = 0.0005
|
||||
}
|
||||
|
||||
tests[a] = []limitTest{{pairs[0], stepIncr, 1}}
|
||||
}
|
||||
|
||||
for _, a := range ok.GetAssetTypes(false) {
|
||||
if err := ok.UpdateOrderExecutionLimits(context.Background(), a); err != nil {
|
||||
t.Error("Okx UpdateOrderExecutionLimits() error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, tt := range tests[a] {
|
||||
limits, err := ok.GetOrderExecutionLimits(a, tt.pair)
|
||||
if err != nil {
|
||||
t.Errorf("Okx GetOrderExecutionLimits() error during TestUpdateOrderExecutionLimits; Asset: %s Pair: %s Err: %v", a, tt.pair, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if got := limits.PriceStepIncrementSize; got != tt.step {
|
||||
t.Errorf("Okx UpdateOrderExecutionLimits wrong PriceStepIncrementSize; Asset: %s Pair: %s Expected: %v Got: %v", a, tt.pair, tt.step, got)
|
||||
}
|
||||
|
||||
if got := limits.MinAmount; got != tt.min {
|
||||
t.Errorf("Okx UpdateOrderExecutionLimits wrong MinAmount; Pair: %s Expected: %v Got: %v", tt.pair, tt.min, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
if _, err := ok.UpdateTicker(context.Background(), currency.NewPair(currency.BTC, currency.USDT), asset.Spot); err != nil {
|
||||
|
||||
@@ -262,15 +262,23 @@ func (ok *Okx) Run(ctx context.Context) {
|
||||
ok.PrintEnabledPairs()
|
||||
}
|
||||
|
||||
if !ok.GetEnabledFeatures().AutoPairUpdates {
|
||||
return
|
||||
assetTypes := ok.GetAssetTypes(false)
|
||||
for i := range assetTypes {
|
||||
if err := ok.UpdateOrderExecutionLimits(ctx, assetTypes[i]); err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s failed to set exchange order execution limits. Err: %v",
|
||||
ok.Name,
|
||||
err)
|
||||
}
|
||||
}
|
||||
err := ok.UpdateTradablePairs(ctx, false)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s failed to update tradable pairs. Err: %s",
|
||||
ok.Name,
|
||||
err)
|
||||
|
||||
if ok.GetEnabledFeatures().AutoPairUpdates {
|
||||
if err := ok.UpdateTradablePairs(ctx, false); err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s failed to update tradable pairs. Err: %s",
|
||||
ok.Name,
|
||||
err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,46 +289,7 @@ func (ok *Okx) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, erro
|
||||
|
||||
// FetchTradablePairs returns a list of the exchanges tradable pairs
|
||||
func (ok *Okx) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) {
|
||||
if !ok.SupportsAsset(a) {
|
||||
return nil, fmt.Errorf("asset type of %s is not supported by %s", a, ok.Name)
|
||||
}
|
||||
var insts []Instrument
|
||||
var err error
|
||||
switch a {
|
||||
case asset.Spot:
|
||||
insts, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeSpot,
|
||||
})
|
||||
case asset.Futures:
|
||||
insts, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeFutures,
|
||||
})
|
||||
case asset.PerpetualSwap:
|
||||
insts, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeSwap,
|
||||
})
|
||||
case asset.Options:
|
||||
var underlyings []string
|
||||
underlyings, err = ok.GetPublicUnderlyings(context.Background(), okxInstTypeOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for x := range underlyings {
|
||||
var instruments []Instrument
|
||||
instruments, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeOption,
|
||||
Underlying: underlyings[x],
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
insts = append(insts, instruments...)
|
||||
}
|
||||
case asset.Margin:
|
||||
insts, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeMargin,
|
||||
})
|
||||
}
|
||||
insts, err := ok.getInstrumentsForAsset(ctx, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -353,6 +322,33 @@ func (ok *Okx) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateOrderExecutionLimits sets exchange execution order limits for an asset type
|
||||
func (ok *Okx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error {
|
||||
insts, err := ok.getInstrumentsForAsset(ctx, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(insts) == 0 {
|
||||
return errNoInstrumentFound
|
||||
}
|
||||
limits := make([]order.MinMaxLevel, len(insts))
|
||||
for x := range insts {
|
||||
pair, err := currency.NewPairFromString(insts[x].InstrumentID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
limits[x] = order.MinMaxLevel{
|
||||
Pair: pair,
|
||||
Asset: a,
|
||||
PriceStepIncrementSize: insts[x].TickSize.Float64(),
|
||||
MinAmount: insts[x].MinimumOrderSize.Float64(),
|
||||
}
|
||||
}
|
||||
|
||||
return ok.LoadLimits(limits)
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (ok *Okx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) {
|
||||
format, err := ok.GetPairFormat(a, false)
|
||||
@@ -1466,3 +1462,49 @@ func (ok *Okx) GetAvailableTransferChains(ctx context.Context, cryptocurrency cu
|
||||
}
|
||||
return chains, nil
|
||||
}
|
||||
|
||||
// getInstrumentsForOptions returns the instruments for options asset type
|
||||
func (ok *Okx) getInstrumentsForOptions(ctx context.Context) ([]Instrument, error) {
|
||||
underlyings, err := ok.GetPublicUnderlyings(context.Background(), okxInstTypeOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var insts []Instrument
|
||||
for x := range underlyings {
|
||||
var instruments []Instrument
|
||||
instruments, err = ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: okxInstTypeOption,
|
||||
Underlying: underlyings[x],
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
insts = append(insts, instruments...)
|
||||
}
|
||||
return insts, nil
|
||||
}
|
||||
|
||||
// getInstrumentsForAsset returns the instruments for an asset type
|
||||
func (ok *Okx) getInstrumentsForAsset(ctx context.Context, a asset.Item) ([]Instrument, error) {
|
||||
if !ok.SupportsAsset(a) {
|
||||
return nil, fmt.Errorf("asset type of %s is not supported by %s", a, ok.Name)
|
||||
}
|
||||
|
||||
var instType string
|
||||
switch a {
|
||||
case asset.Options:
|
||||
return ok.getInstrumentsForOptions(ctx)
|
||||
case asset.Spot:
|
||||
instType = okxInstTypeSpot
|
||||
case asset.Futures:
|
||||
instType = okxInstTypeFutures
|
||||
case asset.PerpetualSwap:
|
||||
instType = okxInstTypeSwap
|
||||
case asset.Margin:
|
||||
instType = okxInstTypeMargin
|
||||
}
|
||||
|
||||
return ok.GetInstruments(ctx, &InstrumentsFetchParams{
|
||||
InstrumentType: instType,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user