National Stock Exchange provides free "End Of Day" and "Intraday" data dumps via downloadable reports and rest APIs that can be called from your applications using suitable clients. Some of the important APIs provided by NSE that can be used for our data analysis are :
This blog documents the approach I have used in Memunic Insights for consuming these APIs for my education and analysis using Java 11 and Spring Boot 2.5.x.
Step 1: WebClient Bean Definition
We create a WebClient Configuration Bean for consuming NSE Provided APIs. This will be used in the API call method of our NSEClient Service.
@Configuration
public class WebClientConfig {
@Bean("nseWebClient")
public WebClient getNseWebClient() {
final int size = 16 * 1024 * 1024;
final ExchangeStrategies strategies = ExchangeStrategies.builder()
.codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(size))
.build();
return WebClient.builder()
.defaultHeader(HttpHeaders.ACCEPT, "*/*")
.defaultHeader(HttpHeaders.USER_AGENT, "PostmanRuntime/7.28.4")
.exchangeStrategies(strategies)
.build();
}
}
Step 2: NSEClient Service
Create a @Service Bean called NSEClient.java.
This class has three instance variables as below:
private final RestTemplate restTemplate;
@Autowired
@Qualifier("nseWebClient")
private WebClient nseWebClient;
private String cookieValue;
As seen the WebClient Bean which we had defined in step 1 is autowired here.
The method which will be called by various processes in your application to consume any of the NSE provided rest APIs is as mentioned below:
@Retryable(value = { Exception.class },
maxAttempts = 3,
backoff = @Backoff(delay = 2000, multiplier = 2))
public <T> T getWebClientResponseBody(String urlString, Class<T> tClass) {
log.info("Getting Api Response Object For [{}]", urlString);
try {
return nseWebClient.get()
.uri(urlString)
.header(HttpHeaders.COOKIE, this.cookieValue)
.retrieve()
.onStatus(HttpStatus::is5xxServerError, errorResponse ->
errorResponse.bodyToMono(String.class).map(NseClientException::new))
.bodyToMono(tClass)
.block();
} catch (NseClientException e) {
log.error("Client Error [{}]. Retrying Again", e.getMessage());
cookieValue = updateNseCookie();
return getWebClientResponseBody(urlString, tClass);
}
}
As you see above, the NSE apis need the NSE cookie to be set in the header before you make a successful call. This need to be initialized and also refreshed as and when it expires. We call the updateNseCookie method when we get a rest call exception due to the cookie not being set or upon expiry of the cookie. Below is the method that we have for updating the cookie.
@Retryable(value = { Exception.class },
maxAttempts = 3,
backoff = @Backoff(delay = 2000, multiplier = 2))
public String updateNseCookie() {
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "*/*");
headers.set("User-Agent", "PostmanRuntime/7.28.4");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange("https://www.nseindia.com", HttpMethod.GET, entity, String.class);
StringBuilder sb = new StringBuilder();
Optional<Map.Entry<String, List<String>>> cookie = response.getHeaders().entrySet().stream().filter(es-> es.getKey().equalsIgnoreCase("Set-Cookie")).findFirst();
if(cookie.isPresent()) {
Map.Entry<String, List<String>> entry = cookie.get();
for(String s : entry.getValue()) {
if(s.contains("nsit")) {
if(sb.toString().length() > 0)
sb.append(" ");
sb.append(s, s.indexOf("nsit"), s.indexOf(";")+1);
}
if(s.contains("nseappid")) {
if(sb.toString().length() > 0)
sb.append(" ");
sb.append(s, s.indexOf("nseappid"), s.indexOf(";")+1);
}
}
}
log.info("Getting updated Cookie from NSE");
return sb.toString();
}
Finally the Constructor of this class should initialize the RestTemplate and the cookie.
public NseClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
try {
this.cookieValue = updateNseCookie();
} catch (ResourceAccessException rex) {
log.error("Unable to Update NSE Cookie !! Reason [{}]", rex.getMessage(), rex);
}
}
Step 3: Using the NSEClient in your application to make rest calls to NSE APIs in your Java Spring Application.
@Autowired
NseClient nseClient;
// Call the market status API
String responseString = nseClient.getWebClientResponseBody("https://www.nseindia.com/api/marketStatus", String.class);
// Call the Earnings Results API for the quarter
ArrayList<LinkedHashMap<String, String>> earningListResponseMaps = nseClient.getWebClientResponseBody("https://www.nseindia.com/api/corporates-financial-results?index=equities&period=Quarterly", ArrayList.class)
The mostly used NSE provided APIs that you can consume from your applications are listed below.
public static final String nseMarketStatusUrl = "https://www.nseindia.com/api/marketStatus";
public static final String nseEventCalendarUrl = "https://www.nseindia.com/api/event-calendar";
public static final String nseResultsUrl = "https://www.nseindia.com/api/corporates-financial-results?index=equities&period=Quarterly";
public static final Function<String, String> nseResultsForSymbolURLSupplier =
symbol -> "https://www.nseindia.com/api/results-comparision?symbol="+symbol;
public static final Function<String, String> nseStockQuoteURLSupplier =
symbol -> "https://www.nseindia.com/api/quote-equity?symbol="+symbol;
public static final BiFunction<LocalDate, LocalDate, String> bulkDealsURLSupplier =
(sDate, eDate) -> {
DateValidator dateValidator = new DateValidator(AppConstants.DATEFORMAT_DD_MM_YYYY);
String sDateString = dateValidator.getDateString(sDate);
String eDateString = dateValidator.getDateString(eDate);
return "https://www.nseindia.com/api/historical/bulk-deals?from="+ sDateString + "&to=" + eDateString;
};
public static final BiFunction<LocalDate, LocalDate, String> blockDealsURLSupplier =
(sDate, eDate) -> {
DateValidator dateValidator = new DateValidator(AppConstants.DATEFORMAT_DD_MM_YYYY);
String sDateString = dateValidator.getDateString(sDate);
String eDateString = dateValidator.getDateString(eDate);
return "https://www.nseindia.com/api/historical/block-deals?from="+ sDateString + "&to=" + eDateString;
};