Skip to content

Commit b6a7fe4

Browse files
authored
Bybit - Fix QuantityStepSize = 0 for Spot (#847)
* Adjust metadata logic * Update examples
1 parent eed5ea1 commit b6a7fe4

File tree

2 files changed

+93
-105
lines changed

2 files changed

+93
-105
lines changed

src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs

Lines changed: 80 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -424,108 +424,86 @@ protected internal override async Task<
424424
> OnGetMarketSymbolsMetadataAsync()
425425
{
426426
/*
427-
{
428-
"ret_code": 0,
429-
"ret_msg": "OK",
430-
"ext_code": "",
431-
"ext_info": "",
432-
"result": [
433-
{
434-
"name": "BTCUSD",
435-
"base_currency": "BTC",
436-
"quote_currency": "USD",
437-
"price_scale": 2,
438-
"taker_fee": "0.00075",
439-
"maker_fee": "-0.00025",
440-
"leverage_filter": {
441-
"min_leverage": 1,
442-
"max_leverage": 100,
443-
"leverage_step": "0.01"
444-
},
445-
"price_filter": {
446-
"min_price": "0.5",
447-
"max_price": "999999.5",
448-
"tick_size": "0.5"
449-
},
450-
"lot_size_filter": {
451-
"max_trading_qty": 1000000,
452-
"min_trading_qty": 1,
453-
"qty_step": 1
454-
}
455-
},
456-
{
457-
"name": "ETHUSD",
458-
"base_currency": "ETH",
459-
"quote_currency": "USD",
460-
"price_scale": 2,
461-
"taker_fee": "0.00075",
462-
"maker_fee": "-0.00025",
463-
"leverage_filter": {
464-
"min_leverage": 1,
465-
"max_leverage": 50,
466-
"leverage_step": "0.01"
467-
},
468-
"price_filter": {
469-
"min_price": "0.05",
470-
"max_price": "99999.95",
471-
"tick_size": "0.05"
472-
},
473-
"lot_size_filter": {
474-
"max_trading_qty": 1000000,
475-
"min_trading_qty": 1,
476-
"qty_step": 1
477-
}
478-
},
479-
{
480-
"name": "EOSUSD",
481-
"base_currency": "EOS",
482-
"quote_currency": "USD",
483-
"price_scale": 3,
484-
"taker_fee": "0.00075",
485-
"maker_fee": "-0.00025",
486-
"leverage_filter": {
487-
"min_leverage": 1,
488-
"max_leverage": 50,
489-
"leverage_step": "0.01"
490-
},
491-
"price_filter": {
492-
"min_price": "0.001",
493-
"max_price": "1999.999",
494-
"tick_size": "0.001"
495-
},
496-
"lot_size_filter": {
497-
"max_trading_qty": 1000000,
498-
"min_trading_qty": 1,
499-
"qty_step": 1
500-
}
501-
},
502-
{
503-
"name": "XRPUSD",
504-
"base_currency": "XRP",
505-
"quote_currency": "USD",
506-
"price_scale": 4,
507-
"taker_fee": "0.00075",
508-
"maker_fee": "-0.00025",
509-
"leverage_filter": {
510-
"min_leverage": 1,
511-
"max_leverage": 50,
512-
"leverage_step": "0.01"
513-
},
514-
"price_filter": {
515-
"min_price": "0.0001",
516-
"max_price": "199.9999",
517-
"tick_size": "0.0001"
518-
},
519-
"lot_size_filter": {
520-
"max_trading_qty": 1000000,
521-
"min_trading_qty": 1,
522-
"qty_step": 1
523-
}
524-
}
525-
],
526-
"time_now": "1581411225.414179"
527-
}}
528-
*/
427+
* Spot:
428+
{
429+
"retCode": 0,
430+
"retMsg": "OK",
431+
"result": {
432+
"category": "spot",
433+
"list": [
434+
{
435+
"symbol": "BTCUSDT",
436+
"baseCoin": "BTC",
437+
"quoteCoin": "USDT",
438+
"innovation": "0",
439+
"status": "Trading",
440+
"marginTrading": "utaOnly",
441+
"lotSizeFilter": {
442+
"basePrecision": "0.000001",
443+
"quotePrecision": "0.00000001",
444+
"minOrderQty": "0.000048",
445+
"maxOrderQty": "71.73956243",
446+
"minOrderAmt": "1",
447+
"maxOrderAmt": "4000000"
448+
},
449+
"priceFilter": {
450+
"tickSize": "0.01"
451+
},
452+
"riskParameters": {
453+
"limitParameter": "0.03",
454+
"marketParameter": "0.03"
455+
}
456+
},
457+
...
458+
*/
459+
460+
/*
461+
* Linear:
462+
{
463+
"retCode": 0,
464+
"retMsg": "OK",
465+
"result": {
466+
"category": "linear",
467+
"list": [
468+
{
469+
"symbol": "10000000AIDOGEUSDT",
470+
"contractType": "LinearPerpetual",
471+
"status": "Trading",
472+
"baseCoin": "10000000AIDOGE",
473+
"quoteCoin": "USDT",
474+
"launchTime": "1709542899000",
475+
"deliveryTime": "0",
476+
"deliveryFeeRate": "",
477+
"priceScale": "6",
478+
"leverageFilter": {
479+
"minLeverage": "1",
480+
"maxLeverage": "12.50",
481+
"leverageStep": "0.01"
482+
},
483+
"priceFilter": {
484+
"minPrice": "0.000001",
485+
"maxPrice": "1.999998",
486+
"tickSize": "0.000001"
487+
},
488+
"lotSizeFilter": {
489+
"maxOrderQty": "25000000",
490+
"minOrderQty": "100",
491+
"qtyStep": "100",
492+
"postOnlyMaxOrderQty": "25000000",
493+
"maxMktOrderQty": "5000000",
494+
"minNotionalValue": "5"
495+
},
496+
"unifiedMarginTrade": true,
497+
"fundingInterval": 480,
498+
"settleCoin": "USDT",
499+
"copyTrading": "none",
500+
"upperFundingRate": "0.03",
501+
"lowerFundingRate": "-0.03",
502+
"isPreListing": false,
503+
"preListingInfo": null
504+
},
505+
...
506+
*/
529507

530508
List<ExchangeMarket> markets = new List<ExchangeMarket>();
531509
JToken allSymbols = CheckRetCode(

src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitV5Base.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,21 @@ protected internal override async Task<
159159
{
160160
var priceFilter = marketJson["priceFilter"];
161161
var sizeFilter = marketJson["lotSizeFilter"];
162-
bool isInverse = MarketCategory == MarketCategory.Inverse;
162+
163163
var market = new ExchangeMarket()
164164
{
165165
MarketSymbol = marketJson["symbol"].ToStringInvariant(),
166166
BaseCurrency = marketJson["baseCoin"].ToStringInvariant(),
167167
QuoteCurrency = marketJson["quoteCoin"].ToStringInvariant(),
168-
QuantityStepSize = sizeFilter["qtyStep"].ConvertInvariant<decimal>(),
169168
MinPrice = priceFilter["minPrice"].ConvertInvariant<decimal>(),
170169
MaxPrice = priceFilter["maxPrice"].ConvertInvariant<decimal>(),
171170
PriceStepSize = priceFilter["tickSize"].ConvertInvariant<decimal>(),
172171
IsActive =
173172
marketJson["status"] == null
174173
|| marketJson["status"].ToStringLowerInvariant() == "trading"
175174
};
176-
if (isInverse)
175+
176+
if (MarketCategory == MarketCategory.Inverse)
177177
{
178178
market.MinTradeSizeInQuoteCurrency = sizeFilter[
179179
"minOrderQty"
@@ -187,6 +187,16 @@ protected internal override async Task<
187187
market.MinTradeSize = sizeFilter["minOrderQty"].ConvertInvariant<decimal>();
188188
market.MaxTradeSize = sizeFilter["maxOrderQty"].ConvertInvariant<decimal>();
189189
}
190+
191+
if (MarketCategory == MarketCategory.Spot)
192+
{
193+
market.QuantityStepSize = sizeFilter["basePrecision"].ConvertInvariant<decimal>();
194+
}
195+
else
196+
{
197+
market.QuantityStepSize = sizeFilter["qtyStep"].ConvertInvariant<decimal>();
198+
}
199+
190200
markets.Add(market);
191201
}
192202
return markets;

0 commit comments

Comments
 (0)