JKorf / Bybit.Net

A C# .netstandard client library for the Bybit REST and Websocket V5 API focusing on clear usage and models
https://jkorf.github.io/Bybit.Net/
91 stars 62 forks source link

api returning error when no data is present #190

Closed pavlexander closed 3 months ago

pavlexander commented 5 months ago

few issues with an API

issue 1

var endDt = DateTime.Parse("01/07/2021 00:00:00 AM");
endDt = DateTime.SpecifyKind(endDt, DateTimeKind.Utc);
var symbolName = "BTCUSDT";
var data = await client.SpotApiV3.ExchangeData.GetKlinesAsync(symbolName, KlineInterval.OneMonth, endTime: endDt);

returns error:

{[DeserializeError] [2] Deserialize JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Bybit.Net.Objects.Internal.BybitList`1[Bybit.Net.Objects.Models.Spot.v3.BybitSpotKlineV3]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'result', line 1, position 37. data: {
  "retCode": 0,
  "retMsg": "OK",
  "result": [],
  "retExtInfo": {},
  "time": 1706446045258
} {
  "retCode": 0,
  "retMsg": "OK",
  "result": [],
  "retExtInfo": {},
  "time": 1706446045258
}}

image

I think there is simply no data present/returned by the API, so the client should handle this gracefully as an empty list of whatever the data is returned, I think. Error should only be populated when there is an actual error with either an API request or other errors.

issue 2

because of issue 1 I started looking at other, more stable options, and found out that there are for some reason 3 api versions?

should the old versions be marked as obsolete maybe?

Regardless, I have tried running the same Klines endpoint with version 5 api (latest?):

var data2 = await client.V5Api.CommonSpotClient.GetKlinesAsync(symbolName, TimeSpan.FromDays(30), endTime: endDt);

but the issue I see here is that according to official documentation https://bybit-exchange.github.io/docs/v5/market/kline

the valid values for timespan are Kline interval. 1,3,5,15,30,60,120,240,360,720,D,M,W

when you use a type of the parameter TimeSpan, then it's no longer possible to specify the Month (M) as the input value. Months have variable number of days in them. It could be 29, 30, even 31. So it makes no sense so use the TimeSpan when working with klines/candles specifically.

after running the above query I see that the TimeSpan.FromDays(30) was actually converted to M value

https://api.bybit.com/v5/market/kline?category=spot&end=1625097600000&interval=M&symbol=BTCUSDT"

this is smart, but then what will I do if the exchange actually supports a 30 days period? Not sure if there is a point in overcomplicating things right now, but, if the current behavior translates the value of 30 to M then it should at least say so in the argument description I think..

image

so I would personally either change the parameter type, OR, simply update the existing parameter description with how the logic works in regards to Months etc.

JKorf commented 4 months ago

Hi, the SpotV1 endpoints are deprecated and will be removed. SpotV3 and V5Api still work, with V5 offering the same functionality as SpotV3. V5 is the 'new' API, so that should be used when creating new things.

You're currently using a common client implementation, which is a interface which allows for some common functionality between different exchanges. If you want to access all functionality from the Bybit API you should instead use the V5Api.ExchangeData endpoints. That will also solve you're issue with the timespan as it accepts an enum instead.

JKorf commented 3 months ago

For the first issue, this is an API problem. They change the json structure based on that there is no data