diff --git a/docs/source/usage.rst b/docs/source/usage.rst index 68a51d3..9307a51 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -420,5 +420,79 @@ can do the following. . } +Getting a Stock Futures Quote +------------------------------ + +You can get the current Futures quote for any stock, given its stock code and expiry date using the command below. Here, we fetch the current futures quote of State Bank of India. The NSE stock code for +State Bank of India is **SBIN**. + +>>> fq = nse.get_futures_quote('sbin',expiry='29OCT2020') +>>> from pprint import pprint +>>> pprint(fq) +{'annualisedVolatility': 54.99, + 'bestBuy': 2.84, + 'bestSell': 3.57, + 'buyPrice1': 197.95, + 'buyPrice2': 197.85, + 'buyPrice3': 197.0, + 'buyPrice4': 196.7, + 'buyPrice5': 196.35, + 'buyQuantity1': 3000.0, + 'buyQuantity2': 3000.0, + 'buyQuantity3': 3000.0, + 'buyQuantity4': 9000.0, + 'buyQuantity5': 3000.0, + 'change': '-5.20', + 'changeinOpenInterest': 87000.0, + 'clientWisePositionLimits': None, + 'closePrice': 198.05, + 'dailyVolatility': 2.88, + 'expiryDate': '29OCT2020', + 'highPrice': 205.2, + 'impliedVolatility': None, + 'instrumentType': 'FUTSTK', + 'lastPrice': 198.1, + 'lowPrice': 196.0, + 'ltp': 3.2, + 'marketLot': 3000.0, + 'marketWidePositionLimits': 746624593.0, + 'numberOfContractsTraded': 134.0, + 'openInterest': 591000.0, + 'openPrice': 205.05, + 'optionType': None, + 'pChange': '-2.56', + 'pchangeinOpenInterest': 17.26, + 'premiumTurnover': None, + 'prevClose': 203.3, + 'sellPrice1': 198.25, + 'sellPrice2': 198.3, + 'sellPrice3': 199.45, + 'sellPrice4': 199.5, + 'sellPrice5': 200.2, + 'sellQuantity1': 3000.0, + 'sellQuantity2': 3000.0, + 'sellQuantity3': 9000.0, + 'sellQuantity4': 45000.0, + 'sellQuantity5': 6000.0, + 'settlementPrice': 198.05, + 'strikePrice': None, + 'totalBuyQuantity': 78000.0, + 'totalSellQuantity': 129000.0, + 'turnoverinRsLakhs': 805.81, + 'underlying': 'SBIN', + 'underlyingValue': 196.8, + 'vwap': 200.45} +>>> + +.. note:: + + The argument expiry is optional. You can also pass only Stock code as an argument. + In that case, it will fetch the result for the next upcoming expiry date. + +.. warning:: + + Always pass a valid expiry date. Otherwise the result will be a blank dict. + Also, take care of the proper format of expiry date. + .. disqus:: diff --git a/nse.py b/nse.py index 84136f0..ac4fcb0 100644 --- a/nse.py +++ b/nse.py @@ -57,6 +57,7 @@ def __init__(self): self.headers = self.nse_headers() # URL list self.get_quote_url = 'https://www1.nseindia.com/live_market/dynaContent/live_watch/get_quote/GetQuote.jsp?' + self.get_derivative_quote_url = 'https://www1.nseindia.com/live_market/dynaContent/live_watch/get_quote/GetQuoteFO.jsp?' self.stocks_csv_url = 'http://www1.nseindia.com/content/equities/EQUITY_L.csv' self.top_gainer_url = 'http://www1.nseindia.com/live_market/dynaContent/live_analysis/gainers/niftyGainers1.json' self.top_loser_url = 'http://www1.nseindia.com/live_market/dynaContent/live_analysis/losers/niftyLosers1.json' @@ -143,6 +144,19 @@ def is_valid_code(self, code): else: return False + def is_valid_fno_code(self, code): + """ + Returns true if a stock has Futures and Options derivative + :param code: a string stock code + :return: Boolean + """ + if code: + stock_codes = self.get_fno_lot_sizes() + if code.upper() in stock_codes.keys(): + return True + else: + return False + def get_quote(self, code, as_json=False): """ gets the quote for a given stock code @@ -182,6 +196,46 @@ def get_quote(self, code, as_json=False): else: return None + def get_futures_quote(self, code, expiry='NODATEGIVEN', as_json=False): + """ + gets the quote of futures derivative for a given stock code + :param code: + :return: dict or None + :raises: HTTPError, URLError + """ + code = code.upper() + expiry = expiry.upper() + if self.is_valid_fno_code(code): + url = self.build_url_for_futures_quote(code, expiry) + req = Request(url, None, self.headers) + # this can raise HTTPError and URLError, but we are not handling it + # north bound APIs should use it for exception handling + res = self.opener.open(req) + + # for py3 compat covert byte file like object to + # string file like object + res = byte_adaptor(res) + res = res.read() + # Now parse the response to get the relevant data + match = re.search(\ + r'