Merge pull request #1243 from bailantaotao/edwin/add-query-markets

FEATURE: pkg/exchange: add query market to bybit exchange
This commit is contained in:
bailantaotao 2023-07-24 21:52:31 +08:00 committed by GitHub
commit 157de4b2ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 158 additions and 22 deletions

View File

@ -10,27 +10,29 @@ import (
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Result
type InstrumentsInfo struct {
Category Category `json:"category"`
List []struct {
Symbol string `json:"symbol"`
BaseCoin string `json:"baseCoin"`
QuoteCoin string `json:"quoteCoin"`
Innovation string `json:"innovation"`
Status Status `json:"status"`
MarginTrading string `json:"marginTrading"`
LotSizeFilter struct {
BasePrecision fixedpoint.Value `json:"basePrecision"`
QuotePrecision fixedpoint.Value `json:"quotePrecision"`
MinOrderQty fixedpoint.Value `json:"minOrderQty"`
MaxOrderQty fixedpoint.Value `json:"maxOrderQty"`
MinOrderAmt fixedpoint.Value `json:"minOrderAmt"`
MaxOrderAmt fixedpoint.Value `json:"maxOrderAmt"`
} `json:"lotSizeFilter"`
Category Category `json:"category"`
List []Instrument `json:"list"`
}
PriceFilter struct {
TickSize fixedpoint.Value `json:"tickSize"`
} `json:"priceFilter"`
} `json:"list"`
type Instrument struct {
Symbol string `json:"symbol"`
BaseCoin string `json:"baseCoin"`
QuoteCoin string `json:"quoteCoin"`
Innovation string `json:"innovation"`
Status Status `json:"status"`
MarginTrading string `json:"marginTrading"`
LotSizeFilter struct {
BasePrecision fixedpoint.Value `json:"basePrecision"`
QuotePrecision fixedpoint.Value `json:"quotePrecision"`
MinOrderQty fixedpoint.Value `json:"minOrderQty"`
MaxOrderQty fixedpoint.Value `json:"maxOrderQty"`
MinOrderAmt fixedpoint.Value `json:"minOrderAmt"`
MaxOrderAmt fixedpoint.Value `json:"maxOrderAmt"`
} `json:"lotSizeFilter"`
PriceFilter struct {
TickSize fixedpoint.Value `json:"tickSize"`
} `json:"priceFilter"`
}
//go:generate GetRequest -url "/v5/market/instruments-info" -type GetInstrumentsInfoRequest -responseDataType .InstrumentsInfo
@ -39,8 +41,11 @@ type GetInstrumentsInfoRequest struct {
category Category `param:"category,query" validValues:"spot"`
symbol *string `param:"symbol,query"`
limit *uint64 `param:"limit,query"`
cursor *string `param:"cursor,query"`
// limit is invalid if category spot.
limit *uint64 `param:"limit,query"`
// cursor is invalid if category spot.
cursor *string `param:"cursor,query"`
}
func (c *RestClient) NewGetInstrumentsInfoRequest() *GetInstrumentsInfoRequest {

View File

@ -0,0 +1,53 @@
package bybit
import (
"math"
"github.com/c9s/bbgo/pkg/exchange/bybit/bybitapi"
"github.com/c9s/bbgo/pkg/types"
)
func toGlobalMarket(m bybitapi.Instrument) types.Market {
// sample:
//Symbol: BTCUSDT
//BaseCoin: BTC
//QuoteCoin: USDT
//Innovation: 0
//Status: Trading
//MarginTrading: both
//
//LotSizeFilter:
//{
// BasePrecision: 0.000001
// QuotePrecision: 0.00000001
// MinOrderQty: 0.000048
// MaxOrderQty: 71.73956243
// MinOrderAmt: 1
// MaxOrderAmt: 2000000
//}
//
//PriceFilter:
//{
// TickSize: 0.01
//}
return types.Market{
Symbol: m.Symbol,
LocalSymbol: m.Symbol,
PricePrecision: int(math.Log10(m.LotSizeFilter.QuotePrecision.Float64())),
VolumePrecision: int(math.Log10(m.LotSizeFilter.BasePrecision.Float64())),
QuoteCurrency: m.QuoteCoin,
BaseCurrency: m.BaseCoin,
MinNotional: m.LotSizeFilter.MinOrderAmt,
MinAmount: m.LotSizeFilter.MinOrderAmt,
// quantity
MinQuantity: m.LotSizeFilter.MinOrderQty,
MaxQuantity: m.LotSizeFilter.MaxOrderQty,
StepSize: m.LotSizeFilter.BasePrecision,
// price
MinPrice: m.LotSizeFilter.MinOrderAmt,
MaxPrice: m.LotSizeFilter.MaxOrderAmt,
TickSize: m.PriceFilter.TickSize,
}
}

View File

@ -0,0 +1,62 @@
package bybit
import (
"math"
"testing"
"github.com/stretchr/testify/assert"
"github.com/c9s/bbgo/pkg/exchange/bybit/bybitapi"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
func TestToGlobalMarket(t *testing.T) {
inst := bybitapi.Instrument{
Symbol: "BTCUSDT",
BaseCoin: "BTC",
QuoteCoin: "USDT",
Innovation: "0",
Status: bybitapi.StatusTrading,
MarginTrading: "both",
LotSizeFilter: struct {
BasePrecision fixedpoint.Value `json:"basePrecision"`
QuotePrecision fixedpoint.Value `json:"quotePrecision"`
MinOrderQty fixedpoint.Value `json:"minOrderQty"`
MaxOrderQty fixedpoint.Value `json:"maxOrderQty"`
MinOrderAmt fixedpoint.Value `json:"minOrderAmt"`
MaxOrderAmt fixedpoint.Value `json:"maxOrderAmt"`
}{
BasePrecision: fixedpoint.NewFromFloat(0.000001),
QuotePrecision: fixedpoint.NewFromFloat(0.00000001),
MinOrderQty: fixedpoint.NewFromFloat(0.000048),
MaxOrderQty: fixedpoint.NewFromFloat(71.73956243),
MinOrderAmt: fixedpoint.NewFromInt(1),
MaxOrderAmt: fixedpoint.NewFromInt(2000000),
},
PriceFilter: struct {
TickSize fixedpoint.Value `json:"tickSize"`
}{
TickSize: fixedpoint.NewFromFloat(0.01),
},
}
exp := types.Market{
Symbol: inst.Symbol,
LocalSymbol: inst.Symbol,
PricePrecision: int(math.Log10(inst.LotSizeFilter.QuotePrecision.Float64())),
VolumePrecision: int(math.Log10(inst.LotSizeFilter.BasePrecision.Float64())),
QuoteCurrency: inst.QuoteCoin,
BaseCurrency: inst.BaseCoin,
MinNotional: inst.LotSizeFilter.MinOrderAmt,
MinAmount: inst.LotSizeFilter.MinOrderAmt,
MinQuantity: inst.LotSizeFilter.MinOrderQty,
MaxQuantity: inst.LotSizeFilter.MaxOrderQty,
StepSize: inst.LotSizeFilter.BasePrecision,
MinPrice: inst.LotSizeFilter.MinOrderAmt,
MaxPrice: inst.LotSizeFilter.MaxOrderAmt,
TickSize: inst.PriceFilter.TickSize,
}
assert.Equal(t, toGlobalMarket(inst), exp)
}

View File

@ -1,6 +1,8 @@
package bybit
import (
"context"
"github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/exchange/bybit/bybitapi"
@ -43,3 +45,17 @@ func (e *Exchange) Name() types.ExchangeName {
func (e *Exchange) PlatformFeeCurrency() string {
return ""
}
func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
instruments, err := e.client.NewGetInstrumentsInfoRequest().Do(ctx)
if err != nil {
return nil, err
}
marketMap := types.MarketMap{}
for _, s := range instruments.List {
marketMap.Add(toGlobalMarket(s))
}
return marketMap, nil
}