Skip to content

opnx-github/opnx-api-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Java Opnx API

opnx-api-client is a lightweight Java library, providing complete API coverage, and supporting synchronous and asynchronous requests, as well as event streaming using WebSockets.

Features

  • Support for synchronous and asynchronous REST requests to all endpoints.
  • Support for User Data, Trade, and Depth event streaming

Installation

  1. Install library into your Maven's local repository by running mvn install
  2. Add the following Maven dependency to your project's pom.xml:
    <dependency>
      <groupId>com.opnx.api</groupId>
      <artifactId>opnx-api-client</artifactId>
      <version>1.0.0</version>
    </dependency>

Alternatively, you can clone this repository and run the examples

Examples

Getting Started

There are three main client classes that can be used to interact with the API:

  1. OpnxApiRestClient a synchronous/blocking Opnx API client;
  2. OpnxApiAsyncRestClient an asynchronous/non-blocking Opnx API client;
  3. OpnxApiWebSocketClient a data streaming client using Opnx WebSocket API.

These can be instantiated through the corresponding factory method of OpnxApiClientFactory. To use the client in the staging environment set the parameter to true, and set it to false to access the live environment.

 OpnxApiClientFactory factory = OpnxApiClientFactory.newInstance("API_KEY", "API_KEY_SECRET",true);
 OpnxApiRestClient client = factory.newRestClient();

Another way to access the live environment is to simply only pass your Api Key and Secret

 OpnxApiClientFactory factory = OpnxApiClientFactory.newInstance("API_KEY", "API_KEY_SECRET");
 OpnxApiRestClient client = factory.newRestClient();

If the client only needs to access endpoints which do not require additional authentication, then these parameters are optional.

Once the client is instantiated, it is possible to start making requests to the API.

GET /v3/account

OpnxV3RestResponse<List<AccountInfoV3Resp>> accountInfo = client.getAccountInfo(Arrays.asList("13670979-1621913298587", "PERMISSIONLESS_165"));
System.out.println(JSONObject.toJSONString(accountInfo));
View Response
{
    "success": true,
    "data": [
        {
            "accountId": "21213",
            "name": "main",
            "accountType": "LINEAR",
            "balances": [
                {
                    "asset": "BTC",
                    "total": "2.823",
                    "available": "2.823",
                    "reserved": "0",
                    "lastUpdatedAt": "1593627415234"
                },
                {
                    "asset": "FLEX",
                    "total": "1585.890",
                    "available": "325.890",
                    "reserved": "1260.0",
                    "lastUpdatedAt": "1593627415123"
                }
            ],
            "positions": [
                {
                    "marketCode": "FLEX-oUSD-SWAP-LIN", 
                    "baseAsset": "FLEX", 
                    "counterAsset": "oUSD", 
                    "position": "11411.1", 
                    "entryPrice": "3.590", 
                    "markPrice": "6.360", 
                    "positionPnl": "31608.7470", 
                    "estLiquidationPrice": "2.59", 
                    "lastUpdatedAt": "1637876701404",
                }
            ],
            "collateral": "1231231",
            "notionalPositionSize": "50000.0",
            "portfolioVarMargin": "500",
            "maintenanceMargin": "1231",
            "marginRatio": "12.3179",
            "liquidating": false,
            "feeTier": "6",
            "createdAt": "1611665624601"
        }
    ]
}

GET /v3/account/names

OpnxV3RestResponse<List<SubAccountInfoV3Resp>> subAccounts = client.getSubAccounts();
System.out.println(JSONObject.toJSONString(subAccounts));
View Response
{
    "success": true,
    "data":  [  {
                    "accountId": "21213",
                    "name": "Test 1"
                }, 
                {
                    "accountId": "21214",
                    "name": "Test 2"
              }
          ] 
}

GET /v3/positions

OpnxV3RestResponse<List<PositionsV3Resp>> accountPositions = client.getAccountPositions(Arrays.asList("13670979-1621913298587", "test_opnx_api"), "BTC-oUSD-SWAP-LIN");
System.out.println(JSONObject.toJSONString(accountPositions));
View Response
{
    "data": [
        {
            "accountId": "165",
            "name": "main",
            "positions": [
                {
                    "baseAsset": "BTC",
                    "counterAsset": "oUSD",
                    "entryPrice": "22938.97488422",
                    "estLiquidationPrice": "12208536.690",
                    "lastUpdatedAt": "1677024022627",
                    "markPrice": "23571.790",
                    "marketCode": "BTC-oUSD-SWAP-LIN",
                    "position": "-1.795000000",
                    "positionPnl": "-1135.90313282510000000"
                }
            ]
        }
    ],
    "success": true
}

GET /v3/exchange-trades

 OpnxV3RestResponse<List<PublicTradesV3Resp>> publicTrades = client.getPublicTrades("BTC-oUSD-SWAP-LIN", 6L, null, null);
 System.out.println(JSONObject.toJSONString(publicTrades));
View Response
{
    "success": true,
    "data": [
        {
            "marketCode": "BTC-oUSD-SWAP-LIN",
            "matchPrice": "9600.00000" ,
            "matchQuantity": "0.100000" ,
            "side": "BUY" ,
            "matchType": "TAKER" ,
            "matchedAt": "1662207330439" 
        }
    ]
}

GET /v3/candles

OpnxV3RestResponse<List<CandlesV3Resp>> candles = client.getCandles("BTC-oUSD-SWAP-LIN", "60s", 10L, null, null);
System.out.println(JSONObject.toJSONString(candles));
View Response
{
    "data": [
        {
            "close": "23565.09200000",
            "currencyVolume": "0",
            "high": "23566.45300000",
            "low": "23563.03600000",
            "open": "23563.50900000",
            "openedAt": "1677486180000",
            "volume": "0"
        },
        {
            "close": "23563.40800000",
            "currencyVolume": "0",
            "high": "23568.46400000",
            "low": "23561.99400000",
            "open": "23568.46400000",
            "openedAt": "1677486120000",
            "volume": "0"
        },
        {
            "close": "23568.88200000",
            "currencyVolume": "0",
            "high": "23573.66000000",
            "low": "23568.88200000",
            "open": "23570.14800000",
            "openedAt": "1677486060000",
            "volume": "0"
        },
        {
            "close": "23570.20300000",
            "currencyVolume": "0",
            "high": "23574.24700000",
            "low": "23570.20300000",
            "open": "23572.48200000",
            "openedAt": "1677486000000",
            "volume": "0"
        }
    ],
    "success": true,
    "timeframe": "60s"
}

Asynchronous requests

To make an asynchronous request it is necessary to use the OpnxApiAsyncRestClient, and call the method with the same name as in the synchronous version, but passing a callback OpnxApiCallback that handles the response whenever it arrives.

GET /v3/trades

 client.getPublicTrades("FLEX-USDT", 6L, null, null,response -> System.out.println(JSONObject.toJSONString(response)));
View Response
{
    "success": true,
    "data": [
                {
                    "orderId": "160067484555913076",
                    "clientOrderId": "123",
                    "matchId": "160067484555913077",
                    "marketCode": "FLEX-USDT",
                    "side": "SELL",
                    "matchedQuantity": "0.1",
                    "matchPrice": "0.065",
                    "total": "0.0065",  
                    "leg1Price'": "0.0065",         
                    "leg2Price": "0.0065",          
                    "orderMatchType": "TAKER",
                    "feeAsset": "FLEX",
                    "fee":"0.0096",
                    "source": "10",
                    "matchedAt": "1595514663626"

               }
            ]
}

GET /v3/markets

 client.getMarketsByMarketCode("BTC-oUSD-SWAP-LIN", response -> System.out.println(JSONObject.toJSONString(response)));
View Response
{
    "data": [
        {
            "base": "BTC",
            "counter": "oUSD",
            "indexPrice": "23385.460",
            "lastUpdatedAt": "1677485772175",
            "listedAt": "1608621449015",
            "lowerPriceBound": "11784.567",
            "markPrice": "23569.135",
            "marketCode": "BTC-oUSD-SWAP-LIN",
            "minSize": "0.001",
            "name": "BTC/USDT Perp",
            "referencePair": "BTC/USDT",
            "tickSize": "0.001",
            "type": "FUTURE",
            "upperPriceBound": "35078.190"
        }
    ],
    "success": true
}

GET /v3/tickers

 client.getTickersByMarketCode("BTC-oUSD-SWAP-LIN", response -> System.out.println(JSONObject.toJSONString(response)));
View Response
{
    "data": [
        {
            "currencyVolume24h": "0",
            "high24h": "23680.460",
            "lastTradedPrice": "23644.95",
            "lastTradedQuantity": "0.001",
            "lastUpdatedAt": "1677485905039",
            "low24h": "23140.760",
            "markPrice": "23569.916",
            "marketCode": "BTC-oUSD-SWAP-LIN",
            "open24h": "23160.130",
            "openInterest": "0",
            "volume24h": "0"
        }
    ],
    "success": true
}

WebSocket Requests

There are two main ways to use it, one is to use the command without authenticating, and the other is to use the command after authenticating.

Subscribe to order book depth without authentication

    OpnxApiClientFactory factory = OpnxApiClientFactory.newInstance(true,true);
    OpnxApiWebSocketClient webSocketClient = factory.newWebSocketClient();
    String subscribeMessage = getSubscribeDepthCMD("BTC-USDT-REPO-LIN");
    OpnxApiWebSocketListener<DepthEvent> listener = new OpnxApiWebSocketListener<>((result,listenerParam) -> {
        if(result != null){
            System.out.println("result ..."+ result.toString());
        }
    }, DepthEvent.class,subscribeMessage);
    webSocketClient.onDepthUpdateEvent(listener);
    System.out.println("websocket send msg: "+subscribeMessage);
View Response
{
    "table": "depth",
    "data": {
        "seqNum": 2166539633781384,
        "asks": [
            [
                19024.0,
                1.0
            ],
            [
                19205.0,
                4.207
            ],
            [
                19395.0,
                8.414
            ]
        ],
        "bids": [
            [
                18986.0,
                1.0
            ],
            [
                18824.0,
                4.207
            ],
            [
                18634.0,
                8.414
            ]
        ],
        "checksum": 3475315026,
        "marketCode": "BTC-oUSD-SWAP-LIN",
        "timestamp": 1665454814328
    },
    "action": "partial"
}

Authenticate the connection (login) to place an order

Multiple callbacks can be placed in callbackAndEventMap to handle the responses of different events. It should be noted that when the same event is placed, the more recent callbacks placed will overwrite the older callbacks, meaning the first callback placed will not be called.
You need to place an order in the login callback method body, because your order requests need to be authenticated.
    OpnxApiClientFactory factory = OpnxApiClientFactory.newInstance(true,true);
    OpnxApiWebSocketClient webSocketClient = factory.newWebSocketClient();
    String loginMessage = JSON.toJSONString(getLoginCMD());
    String limitOrderCMD = getLimitOrderCMD("BTC-USDT-REPO-LIN", 1, BigDecimal.ONE, OrderSide.BUY.name());
    Map<String, CallbackAndEvent> callbackAndEventMap = new HashMap<>();
    placeLimitOrder(callbackAndEventMap);
    CallbackAndEvent<LoginEvent> loginCallbackAndEvent = new CallbackAndEvent();
    loginCallbackAndEvent.setCallback((result,listenerParam) -> {
        if(result != null && result instanceof LoginEvent){
            System.out.println();
            System.out.println("result ..." + result.toString());
            System.out.println("result ..." + result.getEvent());
            System.out.println();
            isLogin = true;
            if(isLogin){
                listenerParam.send(limitOrderCMD);
            }
        }
    });
    loginCallbackAndEvent.setEventClass(LoginEvent.class,callbackAndEventMap);

    MultipleCallbacksWebSocketListener loginListener = new MultipleCallbacksWebSocketListener(callbackAndEventMap,loginMessage);
    webSocketClient.createNewWebSocket(loginListener);
View Response
{
  "event": "placeorder",
  "submitted": True,
  "tag": "123",
  "timestamp": "1592491945248",
  "data": {
            "clientOrderId": 1,
            "marketCode": "BTC-oUSD-SWAP-LIN",
            "side": "BUY",
            "orderType": "LIMIT",
            "quantity": "1.5",
            "timeInForce": "GTC",
            "orderId": "1000000700008",
            "price": "9431.48",
            "source": 0
          }
}

More examples

An extensive set of examples, covering most aspects of the API, can be found at https://github.com/opnx-github/opnx-api-client/tree/main/src/test/java/com/opnx/api/client/examples

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages