diff --git a/README.md b/README.md index 4ab03fe..c9e2437 100644 --- a/README.md +++ b/README.md @@ -342,7 +342,22 @@ SmartAPI is a set of REST-like APIs that expose many capabilities required to bu /** Logout user and kill the session. */ JSONObject jsonObject = smartConnect.logout(); } - + +/** Margin data. */ +public void getMarginDetails(SmartConnect smartConnect) throws SmartAPIException, IOException { + List marginParamsList = new ArrayList<>(); + MarginParams marginParams = new MarginParams(); + marginParams.quantity = 1; + marginParams.token = "12740"; + marginParams.exchange = Constants.EXCHANGE_NSE; + marginParams.productType = Constants.PRODUCT_DELIVERY; + marginParams.price = 0.0; + marginParams.tradeType = Constants.TRADETYPE_BUY; + + marginParamsList.add(marginParams); + JSONObject jsonObject = smartConnect.getMarginDetails(marginParamsList); + System.out.println(jsonObject); + } ``` For more details, take a look at Examples.java in the sample directory. diff --git a/dist/smartapi-java-2.2.0.jar b/dist/smartapi-java-2.2.0.jar index 2194b48..e76e415 100644 Binary files a/dist/smartapi-java-2.2.0.jar and b/dist/smartapi-java-2.2.0.jar differ diff --git a/src/main/java/com/angelbroking/smartapi/Routes.java b/src/main/java/com/angelbroking/smartapi/Routes.java index b032986..f27f905 100644 --- a/src/main/java/com/angelbroking/smartapi/Routes.java +++ b/src/main/java/com/angelbroking/smartapi/Routes.java @@ -47,6 +47,7 @@ public Routes() { put("api.candle.data", "/rest/secure/angelbroking/historical/v1/getCandleData"); put("api.search.script.data", "/rest/secure/angelbroking/order/v1/searchScrip"); put("api.market.data", "/rest/secure/angelbroking/market/v1/quote"); + put("api.margin.batch", "/rest/secure/angelbroking/margin/v1/batch"); } }; } diff --git a/src/main/java/com/angelbroking/smartapi/SmartConnect.java b/src/main/java/com/angelbroking/smartapi/SmartConnect.java index 75cbf93..f16289f 100644 --- a/src/main/java/com/angelbroking/smartapi/SmartConnect.java +++ b/src/main/java/com/angelbroking/smartapi/SmartConnect.java @@ -3,12 +3,7 @@ import com.angelbroking.smartapi.http.SessionExpiryHook; import com.angelbroking.smartapi.http.SmartAPIRequestHandler; import com.angelbroking.smartapi.http.exceptions.SmartAPIException; -import com.angelbroking.smartapi.models.Gtt; -import com.angelbroking.smartapi.models.GttParams; -import com.angelbroking.smartapi.models.Order; -import com.angelbroking.smartapi.models.OrderParams; -import com.angelbroking.smartapi.models.TokenSet; -import com.angelbroking.smartapi.models.User; +import com.angelbroking.smartapi.models.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.json.JSONArray; @@ -804,6 +799,45 @@ public JSONObject logout() { return null; } } - + + /** + * Get Margin Data. + * + * @param marginParams is margin data params. + * @return returns the response of margin data. + */ + public JSONObject getMarginDetails(List marginParams) throws IOException, SmartAPIException { + try { + JSONArray positionsArray = new JSONArray(); + + for (MarginParams params : marginParams) { + JSONObject position = new JSONObject(); + position.put("exchange", params.exchange); + position.put("qty",params.quantity); + position.put("price", params.price ); + position.put("productType", params.productType); + position.put("token", params.token ); + position.put("tradeType", params.tradeType); + positionsArray.put(position); + } + + JSONObject requestBody = new JSONObject(); + requestBody.put("positions", positionsArray); + + String url = routes.get("api.margin.batch"); + JSONObject response = smartAPIRequestHandler.postRequest(this.apiKey, url, requestBody, accessToken); + return response; + }catch (SmartAPIException ex) { + log.error("{} while fetching margin data {}", SMART_API_EXCEPTION_OCCURRED, ex.toString()); + throw new SmartAPIException(String.format("%s while fetching margin data %s", SMART_API_EXCEPTION_ERROR_MSG, ex)); + } catch (IOException ex) { + log.error("{} while fetching margin data {}", IO_EXCEPTION_OCCURRED, ex.getMessage()); + throw new IOException(String.format("%s while fetching margin data %s", IO_EXCEPTION_ERROR_MSG, ex.getMessage())); + } catch (JSONException ex) { + log.error("{} while fetching margin data {}", JSON_EXCEPTION_OCCURRED, ex.getMessage()); + throw new JSONException(String.format("%s while fetching margin data %s", JSON_EXCEPTION_ERROR_MSG, ex.getMessage())); + + } + } } diff --git a/src/main/java/com/angelbroking/smartapi/models/MarginParams.java b/src/main/java/com/angelbroking/smartapi/models/MarginParams.java new file mode 100644 index 0000000..a5a8f25 --- /dev/null +++ b/src/main/java/com/angelbroking/smartapi/models/MarginParams.java @@ -0,0 +1,38 @@ +package com.angelbroking.smartapi.models; + +/** + * A wrapper class for margin params to get the margin using smartAPI margin url + */ + +public class MarginParams { + + /** + * Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). + */ + public String exchange; + + /** + * Quantity to transact + */ + public Integer quantity; + + + public Double price; + + /** + * producttype code (NRML, MIS, CNC, NRML, MARGIN, BO, CO). + */ + public String productType; + + /** + * symboltoken of the instrument. + */ + public String token; + + /** + * Buy or Sell + */ + public String tradeType; + + +} diff --git a/src/main/java/com/angelbroking/smartapi/sample/APITest.java b/src/main/java/com/angelbroking/smartapi/sample/APITest.java index 8413453..76c82ea 100644 --- a/src/main/java/com/angelbroking/smartapi/sample/APITest.java +++ b/src/main/java/com/angelbroking/smartapi/sample/APITest.java @@ -101,6 +101,9 @@ public static void main(String[] args) throws SmartAPIException { /* System.out.println("logout"); */ examples.logout(smartConnect); + /* System.out.println("Margin Details"); */ + examples.getMarginDetails(smartConnect); + /* SmartAPITicker */ String clientId = ""; User user = smartConnect.generateSession("", "", ""); diff --git a/src/main/java/com/angelbroking/smartapi/sample/Examples.java b/src/main/java/com/angelbroking/smartapi/sample/Examples.java index 421a0c1..9750700 100644 --- a/src/main/java/com/angelbroking/smartapi/sample/Examples.java +++ b/src/main/java/com/angelbroking/smartapi/sample/Examples.java @@ -2,11 +2,7 @@ import com.angelbroking.smartapi.SmartConnect; import com.angelbroking.smartapi.http.exceptions.SmartAPIException; -import com.angelbroking.smartapi.models.Gtt; -import com.angelbroking.smartapi.models.GttParams; -import com.angelbroking.smartapi.models.Order; -import com.angelbroking.smartapi.models.OrderParams; -import com.angelbroking.smartapi.models.User; +import com.angelbroking.smartapi.models.*; import com.angelbroking.smartapi.smartTicker.SmartWSOnConnect; import com.angelbroking.smartapi.smartTicker.SmartWSOnDisconnect; import com.angelbroking.smartapi.smartTicker.SmartWSOnError; @@ -414,4 +410,19 @@ public void logout(SmartConnect smartConnect) throws SmartAPIException, IOExcept JSONObject jsonObject = smartConnect.logout(); } + /** Margin data. */ + public void getMarginDetails(SmartConnect smartConnect) throws SmartAPIException, IOException { + List marginParamsList = new ArrayList<>(); + MarginParams marginParams = new MarginParams(); + marginParams.quantity = 1; + marginParams.token = "12740"; + marginParams.exchange = Constants.EXCHANGE_NSE; + marginParams.productType = Constants.PRODUCT_DELIVERY; + marginParams.price = 0.0; + marginParams.tradeType = Constants.TRADETYPE_BUY; + + marginParamsList.add(marginParams); + JSONObject jsonObject = smartConnect.getMarginDetails(marginParamsList); + System.out.println(jsonObject); + } } diff --git a/src/main/java/com/angelbroking/smartapi/utils/Constants.java b/src/main/java/com/angelbroking/smartapi/utils/Constants.java index 97cdadd..a7b0f9d 100644 --- a/src/main/java/com/angelbroking/smartapi/utils/Constants.java +++ b/src/main/java/com/angelbroking/smartapi/utils/Constants.java @@ -101,4 +101,10 @@ public class Constants { public static final String TOKEN_EXCEPTION_MESSAGE = "Unauthorized access. Please provide a valid or non-expired jwtToken."; public static final String APIKEY_EXCEPTION_MESSAGE = "Invalid or missing api key. Please provide a valid api key."; + /** Margin data */ + + public static final String TRADETYPE_BUY = "BUY"; + + public static final String TRADETYPE_SELL = "SELL"; + } diff --git a/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java b/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java index 14c4b9e..ce3a621 100644 --- a/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java +++ b/src/test/java/com/angelbroking/smartapi/SmartConnectTest.java @@ -3,6 +3,8 @@ import com.angelbroking.smartapi.http.SmartAPIRequestHandler; import com.angelbroking.smartapi.http.exceptions.DataException; import com.angelbroking.smartapi.http.exceptions.SmartAPIException; +import com.angelbroking.smartapi.models.MarginParams; +import com.angelbroking.smartapi.utils.Constants; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONException; @@ -15,9 +17,12 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -319,5 +324,122 @@ private JSONObject getMarketDataRequest(String mode) { return payload; } + public static JSONObject createMarginDataResponse() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("status", true); + jsonObject.put("message", ""); + jsonObject.put("errorcode", ""); + + JSONObject dataObject = new JSONObject(); + dataObject.put("totalMarginRequired", 218663); + + JSONObject marginComponentsObject = new JSONObject(); + marginComponentsObject.put("netPremium", 15150); + marginComponentsObject.put("spanMargin", 0); + marginComponentsObject.put("marginBenefit", 750505); + marginComponentsObject.put("deliveryMargin", 0); + marginComponentsObject.put("nonNFOMargin", 0); + marginComponentsObject.put("totOptionsPremium", 21850); + + dataObject.put("marginComponents", marginComponentsObject); + + JSONArray marginBreakupArray = new JSONArray(); + + JSONObject marginBreakupObject = new JSONObject(); + marginBreakupObject.put("exchange", "NFO"); + marginBreakupObject.put("productType", "CARRYFORWARD"); + marginBreakupObject.put("totalMarginRequired", 196813); + + marginBreakupArray.put(marginBreakupObject); + + dataObject.put("marginBreakup", marginBreakupArray); + + JSONObject optionsBuyObject = new JSONObject(); + optionsBuyObject.put("totOptionsPremium", 21850); + + JSONArray optionDetailsArray = new JSONArray(); + + JSONObject optionDetailsObject = new JSONObject(); + optionDetailsObject.put("exchange", "NFO"); + optionDetailsObject.put("productType", "CARRYFORWARD"); + optionDetailsObject.put("token", "53669"); + optionDetailsObject.put("lotMultiplier", 500); + optionDetailsObject.put("optionPremium", 21850); + + optionDetailsArray.put(optionDetailsObject); + + optionsBuyObject.put("optionDetails", optionDetailsArray); + + dataObject.put("optionsBuy", optionsBuyObject); + + jsonObject.put("data", dataObject); + + return jsonObject; + } + + public static JSONObject getMarginDataRequestBody() { + JSONObject jsonObject = new JSONObject(); + + JSONArray positionsArray = new JSONArray(); + + JSONObject positionObject = new JSONObject(); + positionObject.put("exchange", "NFO"); + positionObject.put("qty", 20); + positionObject.put("price", 0); + positionObject.put("productType", "INTRADAY"); + positionObject.put("token", "42885"); + positionObject.put("tradeType", "BUY"); + + positionsArray.put(positionObject); + + jsonObject.put("positions", positionsArray); + return jsonObject; + } + + @Test + public void testMarginData_Success() throws SmartAPIException, IOException { + String url = routes.get("api.margin.batch"); + JSONObject params = getMarginDataRequestBody(); + log.info("params {} ",params.toString()); + when(smartAPIRequestHandler.postRequest(eq(this.apiKey), eq(url), eq(params), eq(this.accessToken))).thenReturn(createMarginDataResponse()); + try { + JSONObject response = smartAPIRequestHandler.postRequest(this.apiKey, url, params, this.accessToken); + log.info("response {} ",response.toString()); + JSONObject data = response.getJSONObject("data"); + assertNotNull(data); + } catch (SmartAPIException ex) { + log.error("{} while fetching margin data {}", SMART_API_EXCEPTION_OCCURRED, ex.toString()); + throw new SmartAPIException(String.format("%s in fetching margin data %s", SMART_API_EXCEPTION_ERROR_MSG, ex)); + } catch (IOException ex) { + log.error("{} while fetching margin data {}", IO_EXCEPTION_OCCURRED, ex.getMessage()); + throw new IOException(String.format("%s fetching margin data %s", IO_EXCEPTION_ERROR_MSG, ex.getMessage())); + } catch (JSONException ex) { + log.error("{} while fetching margin data {}", JSON_EXCEPTION_OCCURRED, ex.getMessage()); + throw new JSONException(String.format("%s in fetching margin data %s", JSON_EXCEPTION_ERROR_MSG, ex.getMessage())); + } + } + + // Testing market data failure for OHLC payload + @Test(expected = SmartAPIException.class) + public void testMarginData_Failure() throws SmartAPIException, IOException { + // Stub the postRequest method + String url = routes.get("api.margin.batch"); + JSONObject params = getMarginDataRequestBody(); + when(smartAPIRequestHandler.postRequest(eq(this.apiKey), eq(url), eq(params), eq(this.accessToken))) + .thenThrow(new SmartAPIException("API request failed")); + try { + JSONObject response = smartAPIRequestHandler.postRequest(apiKey, url, params, accessToken); + response.getJSONObject("data"); + } catch (SmartAPIException ex) { + log.error("{} while fetching margin data {}", SMART_API_EXCEPTION_OCCURRED, ex.toString()); + throw new SmartAPIException(String.format("%s in fetching margin data %s", SMART_API_EXCEPTION_ERROR_MSG, ex)); + } catch (IOException ex) { + log.error("{} while fetching margin data {}", IO_EXCEPTION_OCCURRED, ex.getMessage()); + throw new IOException(String.format("%s in fetching margin data %s", IO_EXCEPTION_ERROR_MSG, ex.getMessage())); + } catch (JSONException ex) { + log.error("{} while fetching margin data {}", JSON_EXCEPTION_OCCURRED, ex.getMessage()); + throw new JSONException(String.format("%s in fetching margin data %s", JSON_EXCEPTION_ERROR_MSG, ex.getMessage())); + } + } }