@@ -27,18 +27,29 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
27
27
// CCAPI_LOGGER_FATAL(std::string("e.what() = ") + e.what());
28
28
// }
29
29
// #endif
30
- this ->getRecentTradesTarget = " /spot/v3/public/quote/trades " ;
31
- this ->getHistoricalTradesTarget = " /spot/v3/public/quote/trades" ;
32
- this ->getRecentCandlesticksTarget = " /spot/v3/public/quote /kline" ;
33
- this ->getHistoricalCandlesticksTarget = " /spot/v3/public/quote/kline" ;
34
- this ->getMarketDepthTarget = " /spot/v3/public/quote/depth " ;
35
- this ->getInstrumentsTarget = " /spot/v3/public/symbols " ;
30
+ this ->getRecentTradesTarget = " /v5/market/recent-trade " ;
31
+ // this->getHistoricalTradesTarget = "/spot/v3/public/quote/trades";
32
+ this ->getRecentCandlesticksTarget = " /v5/market /kline" ;
33
+ // this->getHistoricalCandlesticksTarget = "/spot/v3/public/quote/kline";
34
+ this ->getMarketDepthTarget = " /v5/market/orderbook " ;
35
+ this ->getInstrumentsTarget = " /v5/market/instruments-info " ;
36
36
}
37
37
virtual ~MarketDataServiceBybit () {}
38
38
#ifndef CCAPI_EXPOSE_INTERNAL
39
39
40
40
protected:
41
41
#endif
42
+ std::string convertCandlestickIntervalSecondsToInterval (int intervalSeconds) {
43
+ std::string interval;
44
+ if (intervalSeconds < 86400 ) {
45
+ interval = std::to_string (intervalSeconds / 60 );
46
+ } else if (intervalSeconds == 86400 ) {
47
+ interval = " D" ;
48
+ } else {
49
+ interval = " W" ;
50
+ }
51
+ return interval;
52
+ }
42
53
void prepareSubscriptionDetail (std::string& channelId, std::string& symbolId, const std::string& field, const WsConnection& wsConnection,
43
54
const Subscription& subscription, const std::map<std::string, std::string> optionMap) override {
44
55
auto marketDepthRequested = std::stoi (optionMap.at (CCAPI_MARKET_DEPTH_MAX));
@@ -49,8 +60,8 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
49
60
channelId = CCAPI_WEBSOCKET_BYBIT_CHANNEL_DEPTH;
50
61
}
51
62
} else if (field == CCAPI_CANDLESTICK) {
52
- std::string interval =
53
- this ->convertCandlestickIntervalSecondsToInterval (std::stoi (optionMap. at (CCAPI_CANDLESTICK_INTERVAL_SECONDS)), " s " , " m " , " h " , " d " , " w " );
63
+ int intervalSeconds = std::stoi (optionMap. at (CCAPI_CANDLESTICK_INTERVAL_SECONDS));
64
+ std::string interval = this ->convertCandlestickIntervalSecondsToInterval (intervalSeconds );
54
65
std::string toReplace = " {interval}" ;
55
66
channelId.replace (channelId.find (toReplace), toReplace.length (), interval);
56
67
}
@@ -245,6 +256,7 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
245
256
this ->appendParam (queryString, param,
246
257
{
247
258
{CCAPI_LIMIT, " limit" },
259
+ {CCAPI_INSTRUMENT_TYPE, " category" },
248
260
});
249
261
this ->appendSymbolId (queryString, symbolId, " symbol" );
250
262
req.target (target + " ?" + queryString);
@@ -259,13 +271,14 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
259
271
{
260
272
{CCAPI_CANDLESTICK_INTERVAL_SECONDS, " interval" },
261
273
{CCAPI_LIMIT, " limit" },
262
- {CCAPI_START_TIME_SECONDS, " startTime" },
263
- {CCAPI_END_TIME_SECONDS, " endTime" },
274
+ {CCAPI_START_TIME_SECONDS, " start" },
275
+ {CCAPI_END_TIME_SECONDS, " end" },
276
+ {CCAPI_INSTRUMENT_TYPE, " category" },
264
277
},
265
278
{
266
279
{CCAPI_CANDLESTICK_INTERVAL_SECONDS,
267
280
[that = shared_from_base<MarketDataServiceBybit>()](const std::string& input) {
268
- return that->convertCandlestickIntervalSecondsToInterval (std::stoi (input), " " , " m " , " h " , " d " , " w " );
281
+ return that->convertCandlestickIntervalSecondsToInterval (std::stoi (input));
269
282
}},
270
283
{CCAPI_START_TIME_SECONDS, [that = shared_from_base<MarketDataServiceBybit>()](
271
284
const std::string& input) { return that->convertParamTimeSecondsToTimeMilliseconds (input); }},
@@ -283,32 +296,37 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
283
296
this ->appendParam (queryString, param,
284
297
{
285
298
{CCAPI_LIMIT, " limit" },
299
+ {CCAPI_INSTRUMENT_TYPE, " category" },
286
300
});
287
301
this ->appendSymbolId (queryString, symbolId, " symbol" );
288
302
req.target (target + " ?" + queryString);
289
303
} break ;
290
- case Request::Operation::GET_INSTRUMENT: {
291
- req.method (http::verb::get);
292
- auto target = this ->getInstrumentsTarget ;
293
- req.target (target);
294
- } break ;
304
+ case Request::Operation::GET_INSTRUMENT:
295
305
case Request::Operation::GET_INSTRUMENTS: {
296
306
req.method (http::verb::get);
297
307
auto target = this ->getInstrumentsTarget ;
298
- req.target (target);
308
+ std::string queryString;
309
+ const std::map<std::string, std::string> param = request.getFirstParamWithDefault ();
310
+ this ->appendParam (queryString, param,
311
+ {
312
+ {CCAPI_LIMIT, " limit" },
313
+ {CCAPI_INSTRUMENT_TYPE, " category" },
314
+ });
315
+ this ->appendSymbolId (queryString, symbolId, " symbol" );
316
+ req.target (target + " ?" + queryString);
299
317
} break ;
300
318
default :
301
319
this ->convertRequestForRestCustom (req, request, now, symbolId, credential);
302
320
}
303
321
}
304
322
void extractInstrumentInfo (Element& element, const rj::Value& x) {
305
- element.insert (CCAPI_INSTRUMENT, x[" name " ].GetString ());
323
+ element.insert (CCAPI_INSTRUMENT, x[" symbol " ].GetString ());
306
324
element.insert (CCAPI_BASE_ASSET, x[" baseCoin" ].GetString ());
307
325
element.insert (CCAPI_QUOTE_ASSET, x[" quoteCoin" ].GetString ());
308
- element.insert (CCAPI_ORDER_PRICE_INCREMENT, x[" minPricePrecision " ].GetString ());
309
- element.insert (CCAPI_ORDER_QUANTITY_INCREMENT, x[" basePrecision" ].GetString ());
310
- element.insert (CCAPI_ORDER_QUANTITY_MIN, x[" minTradeQty " ].GetString ());
311
- element.insert (CCAPI_ORDER_PRICE_TIMES_QUANTITY_MIN, x[" minTradeAmt " ].GetString ());
326
+ element.insert (CCAPI_ORDER_PRICE_INCREMENT, x[" priceFilter " ][ " tickSize " ].GetString ());
327
+ element.insert (CCAPI_ORDER_QUANTITY_INCREMENT, x[" lotSizeFilter " ][ " basePrecision" ].GetString ());
328
+ element.insert (CCAPI_ORDER_QUANTITY_MIN, x[" lotSizeFilter " ][ " minOrderQty " ].GetString ());
329
+ element.insert (CCAPI_ORDER_PRICE_TIMES_QUANTITY_MIN, x[" lotSizeFilter " ][ " minOrderAmt " ].GetString ());
312
330
}
313
331
void convertTextMessageToMarketDataMessage (const Request& request, const std::string& textMessage, const TimePoint& timeReceived, Event& event,
314
332
std::vector<MarketDataMessage>& marketDataMessageList) override {
@@ -323,8 +341,9 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
323
341
marketDataMessage.tp = UtilTime::makeTimePointFromMilliseconds (std::stoll (x[" time" ].GetString ()));
324
342
MarketDataMessage::TypeForDataPoint dataPoint;
325
343
dataPoint.insert ({MarketDataMessage::DataFieldType::PRICE, UtilString::normalizeDecimalString (std::string (x[" price" ].GetString ()))});
326
- dataPoint.insert ({MarketDataMessage::DataFieldType::SIZE, UtilString::normalizeDecimalString (std::string (x[" qty" ].GetString ()))});
327
- dataPoint.insert ({MarketDataMessage::DataFieldType::IS_BUYER_MAKER, x[" isBuyerMaker" ].GetString () ? " 0" : " 1" });
344
+ dataPoint.insert ({MarketDataMessage::DataFieldType::SIZE, UtilString::normalizeDecimalString (std::string (x[" size" ].GetString ()))});
345
+ dataPoint.insert ({MarketDataMessage::DataFieldType::TRADE_ID, std::string (x[" execId" ].GetString ())});
346
+ dataPoint.insert ({MarketDataMessage::DataFieldType::IS_BUYER_MAKER, std::string (x[" side" ].GetString ()) == " buy" ? " 1" : " 0" });
328
347
marketDataMessage.data [MarketDataMessage::DataType::TRADE].emplace_back (std::move (dataPoint));
329
348
marketDataMessageList.emplace_back (std::move (marketDataMessage));
330
349
}
@@ -334,13 +353,14 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
334
353
for (const auto & x : document[" result" ][" list" ].GetArray ()) {
335
354
MarketDataMessage marketDataMessage;
336
355
marketDataMessage.type = MarketDataMessage::Type::MARKET_DATA_EVENTS_CANDLESTICK;
337
- marketDataMessage.tp = UtilTime::makeTimePointFromMilliseconds (std::stoll (x[" t " ].GetString ()));
356
+ marketDataMessage.tp = UtilTime::makeTimePointFromMilliseconds (std::stoll (x[0 ].GetString ()));
338
357
MarketDataMessage::TypeForDataPoint dataPoint;
339
- dataPoint.insert ({MarketDataMessage::DataFieldType::OPEN_PRICE, x[" o" ].GetString ()});
340
- dataPoint.insert ({MarketDataMessage::DataFieldType::HIGH_PRICE, x[" h" ].GetString ()});
341
- dataPoint.insert ({MarketDataMessage::DataFieldType::LOW_PRICE, x[" l" ].GetString ()});
342
- dataPoint.insert ({MarketDataMessage::DataFieldType::CLOSE_PRICE, x[" c" ].GetString ()});
343
- dataPoint.insert ({MarketDataMessage::DataFieldType::VOLUME, x[" v" ].GetString ()});
358
+ dataPoint.insert ({MarketDataMessage::DataFieldType::OPEN_PRICE, x[1 ].GetString ()});
359
+ dataPoint.insert ({MarketDataMessage::DataFieldType::HIGH_PRICE, x[2 ].GetString ()});
360
+ dataPoint.insert ({MarketDataMessage::DataFieldType::LOW_PRICE, x[3 ].GetString ()});
361
+ dataPoint.insert ({MarketDataMessage::DataFieldType::CLOSE_PRICE, x[4 ].GetString ()});
362
+ dataPoint.insert ({MarketDataMessage::DataFieldType::VOLUME, x[5 ].GetString ()});
363
+ dataPoint.insert ({MarketDataMessage::DataFieldType::QUOTE_VOLUME, x[6 ].GetString ()});
344
364
marketDataMessage.data [MarketDataMessage::DataType::CANDLESTICK].emplace_back (std::move (dataPoint));
345
365
marketDataMessageList.emplace_back (std::move (marketDataMessage));
346
366
}
@@ -349,14 +369,14 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
349
369
MarketDataMessage marketDataMessage;
350
370
marketDataMessage.type = MarketDataMessage::Type::MARKET_DATA_EVENTS_MARKET_DEPTH;
351
371
const rj::Value& result = document[" result" ];
352
- marketDataMessage.tp = UtilTime::makeTimePointFromMilliseconds (std::stoll (result[" time " ].GetString ()));
353
- for (const auto & x : result[" bids " ].GetArray ()) {
372
+ marketDataMessage.tp = UtilTime::makeTimePointFromMilliseconds (std::stoll (result[" ts " ].GetString ()));
373
+ for (const auto & x : result[" b " ].GetArray ()) {
354
374
MarketDataMessage::TypeForDataPoint dataPoint;
355
375
dataPoint.insert ({MarketDataMessage::DataFieldType::PRICE, x[0 ].GetString ()});
356
376
dataPoint.insert ({MarketDataMessage::DataFieldType::SIZE, x[1 ].GetString ()});
357
377
marketDataMessage.data [MarketDataMessage::DataType::BID].emplace_back (std::move (dataPoint));
358
378
}
359
- for (const auto & x : result[" asks " ].GetArray ()) {
379
+ for (const auto & x : result[" a " ].GetArray ()) {
360
380
MarketDataMessage::TypeForDataPoint dataPoint;
361
381
dataPoint.insert ({MarketDataMessage::DataFieldType::PRICE, x[0 ].GetString ()});
362
382
dataPoint.insert ({MarketDataMessage::DataFieldType::SIZE, x[1 ].GetString ()});
@@ -369,7 +389,7 @@ class MarketDataServiceBybit : public MarketDataServiceBybitBase {
369
389
message.setTimeReceived (timeReceived);
370
390
message.setType (this ->requestOperationToMessageTypeMap .at (request.getOperation ()));
371
391
for (const auto & x : document[" result" ][" list" ].GetArray ()) {
372
- if (std::string (x[" name " ].GetString ()) == request.getInstrument ()) {
392
+ if (std::string (x[" symbol " ].GetString ()) == request.getInstrument ()) {
373
393
Element element;
374
394
this ->extractInstrumentInfo (element, x);
375
395
message.setElementList ({element});
0 commit comments