knowm / XChange

XChange is a Java library providing a streamlined API for interacting with 60+ Bitcoin and Altcoin exchanges providing a consistent interface for trading and accessing market data.
http://knowm.org/open-source/xchange/
MIT License
3.85k stars 1.94k forks source link

Bybit V5 #4771

Closed damiano1996 closed 8 months ago

damiano1996 commented 1 year ago

Bybit V5 API

Upgrade to API v5 for Bybit.

Example

ExchangeSpecification exchangeSpecification =
    new BybitExchange().getDefaultExchangeSpecification();

exchangeSpecification.setApiKey(System.getenv("apiKey"));
exchangeSpecification.setSecretKey(System.getenv("secretKey"));
exchangeSpecification.setExchangeSpecificParametersItem(
    SPECIFIC_PARAM_ACCOUNT_TYPE, BybitAccountType.UNIFIED); // or FUND

BybitExchange bybitExchange =
    (BybitExchange) ExchangeFactory.INSTANCE.createExchange(exchangeSpecification);

System.out.println(bybitExchange.getAccountService().getAccountInfo().getWallets());
System.out.println(
    bybitExchange.getMarketDataService().getTicker(CurrencyPair.BTC_USD, BybitCategory.LINEAR));

System.out.println(bybitExchange.getExchangeMetaData().getInstruments());

System.out.println(
    bybitExchange
        .getTradeService()
        .placeMarketOrder(
            new MarketOrder(OrderType.BID, new BigDecimal("50.00"), CurrencyPair.BTC_USDT)));

System.out.println(bybitExchange.getTradeService().getOrder(""));
rizer1980 commented 9 months ago

please approve this PR i need it for work with bybit stream api...

rizer1980 commented 9 months ago

@damiano1996 can you add to remoteInit() exchangeMetaData linear instruments too ?

rizer1980 commented 9 months ago

Hello @damiano1996 As I understand, you are now using the names of currencies, the same as those inside the buybit API: marketDataService.getTicker(CurrencyPair.BTC_USD, BybitCategory.INVERSE);

I think it’s worth it in the case of linear contract. for compatibility,make names of instruments in xchange style, like this:

    Instrument inst = new FuturesContract("BTC/USDT/PERP");
    marketDataService.getTicker(inst, BybitCategory.LINEAR);

since it is now implemented in Okx, Binance and others... perhaps even in this case there will be no need for(BybitCategory.)

what do you think?

damiano1996 commented 9 months ago

Hi @rizer1980, thanks for your feedbacks. I'll look into it in the next days.

damiano1996 commented 9 months ago

Hi @rizer1980 I updated the code following your suggestions. Now you can get tickers as below:

ExchangeSpecification exchangeSpecification =
    new BybitExchange().getDefaultExchangeSpecification();

exchangeSpecification.setApiKey(System.getenv("apiKey"));
exchangeSpecification.setSecretKey(System.getenv("secretKey"));
exchangeSpecification.setExchangeSpecificParametersItem(
    SPECIFIC_PARAM_ACCOUNT_TYPE, BybitAccountType.UNIFIED); // or FUND

BybitExchange bybitExchange =
    (BybitExchange) ExchangeFactory.INSTANCE.createExchange(exchangeSpecification);

System.out.println(
    "Wallets: " + bybitExchange.getAccountService().getAccountInfo().getWallets());
System.out.println(
    "Ticker: "
        + bybitExchange
            .getMarketDataService()
            .getTicker(new FuturesContract(CurrencyPair.BTC_USD, "PERP")));

System.out.println("Instruments:");
bybitExchange
    .getExchangeMetaData()
    .getInstruments()
    .forEach(
        (instrument, instrumentMetaData) ->
            System.out.println(instrument + " -> " + instrumentMetaData));

String marketSpotOrderId =
    bybitExchange
        .getTradeService()
        .placeMarketOrder(
            new MarketOrder(OrderType.BID, new BigDecimal("10"), CurrencyPair.BTC_USDT));
System.out.println("Market SPOT order id: " + marketSpotOrderId);

System.out.println("Orders: " + bybitExchange.getTradeService().getOrder(marketSpotOrderId));

Now, Bybit categories are inferred from the instrument type. Eg. Market orders as above are converted to spot.

I tried to execute a limit order using FuturesContract, but I'm receiving an invalid symbol error from Bybit. I can't get if it is an issue with my account, because requests are as in the documentation... Can you try with your account and let me know if it works? Thanks in advance.

rizer1980 commented 8 months ago

Hi @damiano1996 Thanks for the changes. I would like to note that the code structure is very thoughtful! I did some tests and it looks great. But encountered the same error as you: {"retCode":10001,"retMsg":"params error: symbol invalid","result":{},"retExtInfo":{},"time":1705148559824} If wee check retCode 10001 in documentation, we get "There was a problem with the value passed to the API" or "params error" in another place. However, this did not bring me any closer to solving the problem. Tried BTC and ETH, changed the amount (qty)...

I think sooner or later we will figure this out.

rizer1980 commented 8 months ago

Hi @damiano1996 Found some issues. By the way, these (LinearFutures,LinearPerpetual,InversePerpetual InverseFutures) and make my head spin.

Sample, based on filter "baseCoin": "ETH"

https://api.bybit.com/v5/market/instruments-info?category=linear We get 9 instruments (ETHPERP,ETHUSDT,ETH-02FEB24,ETH-19JAN24,ETH-23FEB24,ETH-26JAN24,ETH-27SEP24,ETH-28JUN24,ETH-29MAR24) In exchangeMetaData.getInstruments() we get in result 3

  1. ETH/USDT/PERP(LinearPerpetual)
  2. ETH/USDC/SWAP(LinearFutures)
  3. ETH/USDC/PERP(LinearPerpetual)

https://api.bybit.com/v5/market/instruments-info?category=inverse get 3 (ETHUSD,ETHUSDH24,ETHUSDM24) In exchangeMetaData.getInstruments() we get in result 2

  1. ETH/USD/PERP(InversePerpetual)
  2. ETH/USD/SWAP(InverseFutures)

I'm at a loss as to how to correctly name these missing instruments. (

damiano1996 commented 8 months ago

Hi @rizer1980 , sorry for late answer. I fixed the issue by exploiting the prompt variable of the FuturesContract. Now, it returns all the instruments, but I'm still getting the error of params error: symbol invalid. I'll find out in the coming days.

rizer1980 commented 8 months ago

@douggie Can you merge, please.

marcelv3612 commented 8 months ago

Can anyone confirm that this is, in fact, working?

I am getting the params error: symbol invalid as @damiano1996 mentioned above. I get it even when I execute the underlying call to ByBit with the symbol format that ByBit has in its official documentation, as can be seen in the following screenshots:

image image
rizer1980 commented 8 months ago

Spot - works.

String marketSpotOrderId =
        exchange
            .getTradeService()
            .placeMarketOrder(
                new MarketOrder(OrderType.BID, new BigDecimal("5"), CurrencyPair.BTC_USDT));
    System.out.println("Market SPOT order id: " + marketSpotOrderId);
marcelv3612 commented 8 months ago

I confirm that Spot functionality is operational.

For the Futures issue, I've filed a new bug report here: Issue #4822