UNPKG

stock-nse-india

Version:

This package will help us to get equity/index details and historical data from National Stock Exchange of India.

1,478 lines 79.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mainRouter = void 0; const express_1 = require("express"); const swaggerDocOptions_1 = require("./swaggerDocOptions"); const index_1 = require("./index"); const helpers_1 = require("./helpers"); const mcp_client_js_1 = require("./mcp/client/mcp-client.js"); const route_errors_1 = require("./route-errors"); const mainRouter = (0, express_1.Router)(); exports.mainRouter = mainRouter; const nseIndia = new index_1.NseIndia(); /** * @openapi * /: * get: * description: To get market status * tags: * - Base * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE market status * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/', async (_req, res) => { try { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MARKET_STATUS)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/v1/swagger.json: * get: * description: To get open api specification for swagger documentation * tags: * - Base * produces: * - application/json * responses: * 200: * description: Returns a JSON object of open api specification */ mainRouter.get('/api/v1/swagger.json', (_req, res) => { res.json(swaggerDocOptions_1.openapiSpecification); }); /** * @openapi * /api/glossary: * get: * description: To get glossary of NSE India * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of glossary for NSE India * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/glossary', async (_req, res) => { try { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.GLOSSARY)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/marketStatus: * get: * description: To get market status * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE market status * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/marketStatus', async (_req, res) => { try { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MARKET_STATUS)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/marketTurnover: * get: * description: To get market turn over * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE market turn over * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/marketTurnover', async (_req, res) => { try { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MARKET_TURNOVER)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equityMaster: * get: * description: To get equity master * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE equity master * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equityMaster', async (_req, res) => { try { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.EQUITY_MASTER)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/holidays: * get: * description: To get holidays of NSE India * tags: * - Common * parameters: * - name: type * in: query * description: Holiday list for * required: true * schema: * type: string * enum: [trading,clearing] * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE India's holidays * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/holidays', async (req, res) => { try { const { type } = req.query; if (type === 'clearing') { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.HOLIDAY_CLEARING)); } else { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.HOLIDAY_TRADING)); } } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/circulars: * get: * description: To get NSE India's circulars * tags: * - Common * parameters: * - name: isLatest * in: query * description: Boolean value get latest circulars * required: false * schema: * type: boolean * default: false * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE India's circulars * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/circulars', async (req, res) => { try { const { isLatest } = req.query; if (isLatest === 'true') { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.LATEST_CIRCULARS)); } else { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.CIRCULARS)); } } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/mergedDailyReports: * get: * description: To get merged daily reports * tags: * - Common * parameters: * - name: key * in: query * description: Key for merged daily reports * required: true * schema: * type: string * enum: [capital,derivatives,debt] * produces: * - application/json * responses: * 200: * description: Returns a JSON object of NSE India's merged daily reports * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/mergedDailyReports', async (req, res) => { try { const { key } = req.query; if (key === 'debt') { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MERGED_DAILY_REPORTS_DEBT)); } else if (key === 'derivatives') { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MERGED_DAILY_REPORTS_DERIVATIVES)); } else { res.json(await nseIndia.getDataByEndpoint(index_1.ApiList.MERGED_DAILY_REPORTS_CAPITAL)); } } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/allIndices: * get: * description: To get all NSE indices * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of all NSE indices * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/allIndices', async (_req, res) => { try { const allIndices = await nseIndia.getDataByEndpoint(index_1.ApiList.ALL_INDICES); res.json(allIndices); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/indexNames: * get: * description: To get all NSE index names * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns a JSON object of all NSE index names * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/indexNames', async (_req, res) => { try { const indexNames = await nseIndia.getDataByEndpoint(index_1.ApiList.INDEX_NAMES); res.json(indexNames); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/allSymbols: * get: * description: To get all NSE equity symbols * tags: * - Common * produces: * - application/json * responses: * 200: * description: Returns an array of NSE equity symbols * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/allSymbols', async (_req, res) => { try { const symbols = await nseIndia.getAllStockSymbols(); res.json(symbols); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/{symbol}: * get: * description: To get details of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a details of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/:symbol', async (req, res) => { try { const { symbol } = req.params; const data = await nseIndia.getEquityDetails(symbol); res.json(data); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/series/{symbol}: * get: * description: To get equity series of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a equity series of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/series/:symbol', async (req, res) => { try { res.json(await nseIndia.getEquitySeries(req.params.symbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/tradeInfo/{symbol}: * get: * description: To get trade info of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a trade info of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/tradeInfo/:symbol', async (req, res) => { try { res.json(await nseIndia.getEquityTradeInfo(req.params.symbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/corporateInfo/{symbol}: * get: * description: To get corporate info of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a corporate info of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/corporateInfo/:symbol', async (req, res) => { try { res.json(await nseIndia.getEquityCorporateInfo(req.params.symbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/options/{symbol}: * get: * description: To get options chain of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a options chain of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/options/:symbol', async (req, res) => { try { res.json(await nseIndia.getEquityOptionChain(req.params.symbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/intraday/{symbol}: * get: * description: To get intraday trade info of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a intraday trade info of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/intraday/:symbol', async (req, res) => { try { const { symbol } = req.params; const data = await nseIndia.getEquityIntradayData(symbol); res.json(data); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/historical/{symbol}: * get: * description: To get details of the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * - name: dateStart * in: query * description: "Start date to pull historical data (format: YYYY-MM-DD)" * required: false * schema: * type: string * format: date * - name: dateEnd * in: query * description: "End date to pull historical data (format: YYYY-MM-DD)" * required: false * schema: * type: string * format: date * responses: * 200: * description: Returns a historical data of the NSE symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/historical/:symbol', async (req, res) => { try { const dateStart = req.query.dateStart; const dateEnd = req.query.dateEnd; if (dateStart) { const start = new Date(dateStart); const end = dateEnd ? new Date(dateEnd) : new Date(); if (start.getTime() > 0 && end.getTime() > 0) { const range = { start, end }; res.json(await nseIndia.getEquityHistoricalData(req.params.symbol, range)); } else { res.status(400).json({ error: 'Invalid date format. Please use the format (YYYY-MM-DD)' }); } } else { res.json(await nseIndia.getEquityHistoricalData(req.params.symbol)); } } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/equity/technicalIndicators/{symbol}: * get: * description: To get technical indicators for the NSE symbol * tags: * - Equity * produces: * - application/json * parameters: * - name: symbol * in: path * description: NSE Symbol of the Equity * required: true * schema: * type: string * format: any * - name: period * in: query * description: "Number of days for historical data (default: 200)" * required: false * schema: * type: integer * default: 200 * - name: smaPeriods * in: query * description: "Comma-separated SMA periods (e.g., 5,10,20,50)" * required: false * schema: * type: string * default: "5,10,20,50,100,200" * - name: emaPeriods * in: query * description: "Comma-separated EMA periods (e.g., 5,10,20,50)" * required: false * schema: * type: string * default: "5,10,20,50,100,200" * - name: rsiPeriod * in: query * description: "RSI period (default: 14)" * required: false * schema: * type: integer * default: 14 * - name: bbPeriod * in: query * description: "Bollinger Bands period (default: 20)" * required: false * schema: * type: integer * default: 20 * - name: bbStdDev * in: query * description: "Bollinger Bands standard deviation (default: 2)" * required: false * schema: * type: number * default: 2 * - name: showOnlyLatest * in: query * description: "Show only latest values (true) or all values (false) - useful for charts (default: true)" * required: false * schema: * type: boolean * default: true * responses: * 200: * description: Returns technical indicators for the NSE symbol * content: * application/json: * schema: * type: object * properties: * sma: * type: object * description: "Simple Moving Averages with dynamic keys (sma5, sma10, etc.)" * additionalProperties: * type: array * items: * type: number * ema: * type: object * description: "Exponential Moving Averages with dynamic keys (ema5, ema10, etc.)" * additionalProperties: * type: array * items: * type: number * rsi: * type: array * items: * type: number * description: "Relative Strength Index" * macd: * type: object * properties: * macd: * type: array * items: * type: number * signal: * type: array * items: * type: number * histogram: * type: array * items: * type: number * bollingerBands: * type: object * properties: * upper: * type: array * items: * type: number * middle: * type: array * items: * type: number * lower: * type: array * items: * type: number * stochastic: * type: object * properties: * k: * type: array * items: * type: number * d: * type: array * items: * type: number * williamsR: * type: array * items: * type: number * description: "Williams %R" * atr: * type: array * items: * type: number * description: "Average True Range" * adx: * type: array * items: * type: number * description: "Average Directional Index" * obv: * type: array * items: * type: number * description: "On-Balance Volume" * cci: * type: array * items: * type: number * description: "Commodity Channel Index" * mfi: * type: array * items: * type: number * description: "Money Flow Index" * roc: * type: array * items: * type: number * description: "Rate of Change" * momentum: * type: array * items: * type: number * description: "Momentum" * ad: * type: array * items: * type: number * description: "Accumulation/Distribution" * vwap: * type: array * items: * type: number * description: "Volume Weighted Average Price" * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/equity/technicalIndicators/:symbol', async (req, res) => { try { const { symbol } = req.params; const { period, smaPeriods, emaPeriods, rsiPeriod, bbPeriod, bbStdDev, showOnlyLatest } = req.query; // Parse query parameters const options = {}; if (period) { options.period = parseInt(period); } if (smaPeriods) { options.smaPeriods = smaPeriods.split(',').map(p => parseInt(p.trim())); } if (emaPeriods) { options.emaPeriods = emaPeriods.split(',').map(p => parseInt(p.trim())); } if (rsiPeriod) { options.rsiPeriod = parseInt(rsiPeriod); } if (bbPeriod) { options.bbPeriod = parseInt(bbPeriod); } if (bbStdDev) { options.bbStdDev = parseFloat(bbStdDev); } const indicators = await nseIndia.getTechnicalIndicators(symbol, options.period || 200, options); // Parse showOnlyLatest flag (default: true) const showLatest = showOnlyLatest === undefined || showOnlyLatest === 'true'; // Helper function to round numbers to 2 decimal places const roundTo2Decimals = (value) => { return value !== null ? Math.round(value * 100) / 100 : null; }; // Helper function to round array of numbers to 2 decimal places const roundArrayTo2Decimals = (arr) => { return arr.map(value => roundTo2Decimals(value)); }; if (showLatest) { // Return only the latest values const latestIndicators = {}; // Process SMA indicators latestIndicators.sma = {}; Object.keys(indicators.sma).forEach(key => { const values = indicators.sma[key]; latestIndicators.sma[key] = values.length > 0 ? roundTo2Decimals(values[values.length - 1]) : null; }); // Process EMA indicators latestIndicators.ema = {}; Object.keys(indicators.ema).forEach(key => { const values = indicators.ema[key]; latestIndicators.ema[key] = values.length > 0 ? roundTo2Decimals(values[values.length - 1]) : null; }); // Process other indicators latestIndicators.rsi = roundTo2Decimals(indicators.rsi.length > 0 ? indicators.rsi[indicators.rsi.length - 1] : null); latestIndicators.macd = { macd: roundTo2Decimals(indicators.macd.macd.length > 0 ? indicators.macd.macd[indicators.macd.macd.length - 1] : null), signal: roundTo2Decimals(indicators.macd.signal.length > 0 ? indicators.macd.signal[indicators.macd.signal.length - 1] : null), histogram: roundTo2Decimals(indicators.macd.histogram.length > 0 ? indicators.macd.histogram[indicators.macd.histogram.length - 1] : null) }; latestIndicators.bollingerBands = { upper: roundTo2Decimals(indicators.bollingerBands.upper.length > 0 ? indicators.bollingerBands.upper[indicators.bollingerBands.upper.length - 1] : null), middle: roundTo2Decimals(indicators.bollingerBands.middle.length > 0 ? indicators.bollingerBands.middle[indicators.bollingerBands.middle.length - 1] : null), lower: roundTo2Decimals(indicators.bollingerBands.lower.length > 0 ? indicators.bollingerBands.lower[indicators.bollingerBands.lower.length - 1] : null) }; latestIndicators.stochastic = { k: roundTo2Decimals(indicators.stochastic.k.length > 0 ? indicators.stochastic.k[indicators.stochastic.k.length - 1] : null), d: roundTo2Decimals(indicators.stochastic.d.length > 0 ? indicators.stochastic.d[indicators.stochastic.d.length - 1] : null) }; latestIndicators.williamsR = roundTo2Decimals(indicators.williamsR.length > 0 ? indicators.williamsR[indicators.williamsR.length - 1] : null); latestIndicators.atr = roundTo2Decimals(indicators.atr.length > 0 ? indicators.atr[indicators.atr.length - 1] : null); latestIndicators.adx = roundTo2Decimals(indicators.adx.length > 0 ? indicators.adx[indicators.adx.length - 1] : null); latestIndicators.obv = roundTo2Decimals(indicators.obv.length > 0 ? indicators.obv[indicators.obv.length - 1] : null); latestIndicators.cci = roundTo2Decimals(indicators.cci.length > 0 ? indicators.cci[indicators.cci.length - 1] : null); latestIndicators.mfi = roundTo2Decimals(indicators.mfi.length > 0 ? indicators.mfi[indicators.mfi.length - 1] : null); latestIndicators.roc = roundTo2Decimals(indicators.roc.length > 0 ? indicators.roc[indicators.roc.length - 1] : null); latestIndicators.momentum = roundTo2Decimals(indicators.momentum.length > 0 ? indicators.momentum[indicators.momentum.length - 1] : null); latestIndicators.ad = roundTo2Decimals(indicators.ad.length > 0 ? indicators.ad[indicators.ad.length - 1] : null); latestIndicators.vwap = roundTo2Decimals(indicators.vwap.length > 0 ? indicators.vwap[indicators.vwap.length - 1] : null); res.json(latestIndicators); } else { // Return all values with 2 decimal precision const roundedIndicators = {}; // Process SMA indicators roundedIndicators.sma = {}; Object.keys(indicators.sma).forEach(key => { roundedIndicators.sma[key] = roundArrayTo2Decimals(indicators.sma[key]); }); // Process EMA indicators roundedIndicators.ema = {}; Object.keys(indicators.ema).forEach(key => { roundedIndicators.ema[key] = roundArrayTo2Decimals(indicators.ema[key]); }); // Process other indicators roundedIndicators.rsi = roundArrayTo2Decimals(indicators.rsi); roundedIndicators.macd = { macd: roundArrayTo2Decimals(indicators.macd.macd), signal: roundArrayTo2Decimals(indicators.macd.signal), histogram: roundArrayTo2Decimals(indicators.macd.histogram) }; roundedIndicators.bollingerBands = { upper: roundArrayTo2Decimals(indicators.bollingerBands.upper), middle: roundArrayTo2Decimals(indicators.bollingerBands.middle), lower: roundArrayTo2Decimals(indicators.bollingerBands.lower) }; roundedIndicators.stochastic = { k: roundArrayTo2Decimals(indicators.stochastic.k), d: roundArrayTo2Decimals(indicators.stochastic.d) }; roundedIndicators.williamsR = roundArrayTo2Decimals(indicators.williamsR); roundedIndicators.atr = roundArrayTo2Decimals(indicators.atr); roundedIndicators.adx = roundArrayTo2Decimals(indicators.adx); roundedIndicators.obv = roundArrayTo2Decimals(indicators.obv); roundedIndicators.cci = roundArrayTo2Decimals(indicators.cci); roundedIndicators.mfi = roundArrayTo2Decimals(indicators.mfi); roundedIndicators.roc = roundArrayTo2Decimals(indicators.roc); roundedIndicators.momentum = roundArrayTo2Decimals(indicators.momentum); roundedIndicators.ad = roundArrayTo2Decimals(indicators.ad); roundedIndicators.vwap = roundArrayTo2Decimals(indicators.vwap); res.json(roundedIndicators); } } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/index/{indexSymbol}: * get: * description: To get detailsof the NSE index * tags: * - Index * produces: * - application/json * parameters: * - name: indexSymbol * in: path * description: NSE index symbol * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a details of the NSE index symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/index/:indexSymbol', async (req, res) => { try { res.json(await nseIndia.getEquityStockIndices(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/index/options/{indexSymbol}: * get: * description: To get index Option chain data * tags: * - Index * produces: * - application/json * parameters: * - name: indexSymbol * in: path * description: NSE index symbol * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns Data for Index OPTION CHAIN * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/index/options/:indexSymbol', async (req, res) => { try { res.json(await nseIndia.getIndexOptionChain(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @swagger * /api/index/options/contract-info/{indexSymbol}: * get: * summary: Get option chain contract information for an index * tags: [Index] * parameters: * - in: path * name: indexSymbol * required: true * schema: * type: string * description: Index symbol (e.g., NIFTY, BANKNIFTY) * responses: * 200: * description: Returns option chain contract information (expiry dates and strike prices) * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/index/options/contract-info/:indexSymbol', async (req, res) => { try { res.json(await nseIndia.getIndexOptionChainContractInfo(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/commodity/options/{commoditySymbol}: * get: * description: To get commodity Option chain data * tags: * - Commodity * produces: * - application/json * parameters: * - name: commoditySymbol * in: path * description: NSE commodity symbol * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a option chain data of the NSE commodity symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/commodity/options/:commoditySymbol', async (req, res) => { try { res.json(await nseIndia.getCommodityOptionChain(req.params.commoditySymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/index/intraday/{indexSymbol}: * get: * description: To get intraday trade info of the NSE index symbol * tags: * - Index * produces: * - application/json * parameters: * - name: indexSymbol * in: path * description: NSE index symbol * required: true * schema: * type: string * format: any * responses: * 200: * description: Returns a intraday trade info of the NSE index symbol * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/index/intraday/:indexSymbol', async (req, res) => { try { res.json(await nseIndia.getIndexIntradayData(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/gainersAndLosers/{indexSymbol}: * get: * description: To get gainers and losers of the specific index * tags: * - Helpers * parameters: * - name: indexSymbol * in: path * description: NSE index symbol * required: true * schema: * type: string * format: any * produces: * - application/json * responses: * 200: * description: Returns a JSON object of the specified index's gainers and losers * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/gainersAndLosers/:indexSymbol', async (req, res) => { try { res.json(await (0, helpers_1.getGainersAndLosersByIndex)(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/mostActive/{indexSymbol}: * get: * description: To get most active equities of the specific index * tags: * - Helpers * parameters: * - name: indexSymbol * in: path * description: NSE index symbol * required: true * schema: * type: string * format: any * produces: * - application/json * responses: * 200: * description: Returns a JSON object of most active equities of the specified index * 400: * description: Returns a JSON error object of API call */ mainRouter.get('/api/mostActive/:indexSymbol', async (req, res) => { try { res.json(await (0, helpers_1.getMostActiveEquities)(req.params.indexSymbol)); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/charts/equity-historical-data: * get: * description: Get historical chart data from charting.nseindia.com for equity symbols * tags: * - Charting * produces: * - application/json * parameters: * - name: symbol * in: query * description: Equity symbol with series code (e.g., 'ONGC') * required: true * schema: * type: string * example: ONGC * - name: start * in: query * description: > * Start date/time. Supports YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, unix timestamp * (seconds or milliseconds) * required: false * schema: * type: string * example: "2026-04-10 09:15:00" * - name: end * in: query * description: > * End date/time. Supports YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, unix timestamp * (seconds or milliseconds) * required: false * schema: * type: string * example: "2026-04-12 15:30:00" * - name: token * in: query * description: Optional token value for charting API (auto-fetched when omitted) * required: false * schema: * type: string * example: "2475" * - name: symbolType * in: query * description: Type of symbol (e.g., 'Equity', 'Index') * required: false * schema: * type: string * default: Equity * example: Equity * - name: chartType * in: query * description: Chart type ('I' for intraday, 'D' for daily pattern, etc.) * required: false * schema: * type: string * default: I * example: I * - name: timeInterval * in: query * description: Time interval in minutes (e.g., '5', '15', '60') * required: false * schema: * type: string * default: "5" * example: "5" * responses: * 200: * description: Returns historical chart data with OHLC values and timestamps * content: * application/json: * schema: * type: object * properties: * status: * type: boolean * description: true if request was successful * example: true * data: * type: array * description: Array of candle data points * items: * type: object * properties: * volume: * type: number * example: 46151 * high: * type: number * example: 286.7 * low: * type: number * example: 286.3 * time: * type: number * description: Unix timestamp in milliseconds * example: 1775834999000 * close: * type: number * example: 286.7 * open: * type: number * example: 286.65 * 400: * description: Returns error object if API call fails or parameters are invalid */ mainRouter.get('/api/charts/equity-historical-data', async (req, res) => { try { const { symbol, start, end, token, symbolType = 'Equity', chartType = 'I', timeInterval = '5' } = req.query; // Validate required parameters if (!symbol) { return res.status(400).json({ error: 'Missing required parameter: symbol' }); } // Call the charting method const parseChartDateParam = (value) => { const input = String(value).trim(); const numeric = Number(input); // Accept unix timestamp in seconds (10 digits) or milliseconds (13 digits). if (!Number.isNaN(numeric) && input !== '') { const unixMs = input.length <= 10 ? numeric * 1000 : numeric; return new Date(unixMs); } return new Date(input); }; let range; if (start || end) { const endDate = end ? parseChartDateParam(end) : new Date(); const startDate = start ? parseChartDateParam(start) : new Date(endDate.getTime() - 24 * 60 * 60 * 1000); if (!(startDate.getTime() > 0 && endDate.getTime() > 0)) { return res.status(400).json({ error: 'Invalid date format. Use YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, or unix timestamp' }); } range = { start: startDate, end: endDate }; } const chartData = await nseIndia.getEquityChartHistoricalData(String(symbol), range, token ? String(token) : undefined, String(symbolType), String(chartType), String(timeInterval)); res.json(chartData); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); /** * @openapi * /api/charts/symbol-info: * get: * description: > * Look up NSE charting symbol information (including scripCode / token) for a * given equity symbol. The returned `scripCode` is the value that must be passed * as `token` to the `/api/charts/equity-historical-data` endpoint. * tags: * - Charting * produces: * - application/json * parameters: * - name: symbol * in: query * description: Equity symbol with or without series code (e.g., 'ONGC' or 'ONGC') * required: true * schema: * type: string * example: ONGC * - name: segment * in: query * description: Optional market segment filter (leave empty to search all segments) * required: false * schema: * type: string * example: '' * responses: * 200: * description: Returns charting symbol information including scripCode (token) * content: * application/json: * schema: * type: object * properties: * symbol: * type: string * example: ONGC * scripCode: * type: string * description: The token value required by the historical chart API * example: "2475" * companyName: * type: string * isin: * type: string * segment: * type: string * series: * type: string * status: * type: string * 400: * description: Returns error if symbol is missing or lookup fails */ mainRouter.get('/api/charts/symbol-info', async (req, res) => { try { const { symbol, segment = '' } = req.query; if (!symbol) { return res.status(400).json({ error: 'Missing required parameter: symbol' }); } const symbolInfo = await nseIndia.getEquitySymbolInfo(String(symbol), String(segment)); res.json(symbolInfo); } catch (error) { (0, route_errors_1.sendRouteError)(res, error); } }); // ============================================================================ // MCP CLIENT - CORE ENDPOINTS // ============================================================================ /** * @openapi * /api/mcp/query: * post: * description: Query NSE India data using natural language. Supports OpenAI function calling, * memory, context summarization, and session management. * tags: * - MCP Client * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - query * properties: * query: * type: string * description: Natural language query about NSE India stock market data * example: "What is the current price of TCS stock? Also compare it with RELIANCE." * sessionId: * type: string * description: Optional session identifier for memory features * example: "user123_session456" * userId: * type: string * description: Optional user identifier for personalization * example: "user123" * model: * type: string * description: OpenAI model to use * default: gpt-4o-mini * temperature: * type: number * description: Temperature for response generation * default: 0.7 * max_tokens: * type: number * description: Maximum tokens in response * default: 2000 * includeContext: * type: boolean * description: Whether to include conversation context (requires sessionId) * default: true * updatePreferences: * type: boolean * description: Whether to update user preferences based on query (requires sessionId) * default: true * useMemory: * type: boolean * description: Whether to use memory features (requires sessionId) * default: true * maxIterations: * type: number * description: Maximum number of iterations for complex queries * default: 5 * enableDebugLogging: * type: boolean * description: Enable debug logging for AI messages and tool calls * default: false * responses: * 200: * description: Returns AI-generated response with NSE data * content: * application/json: * schema: * type: object * properties: * response: * type: string * description: AI-generated response * tools_used: * type: array * items: * type: string * description: List of unique MCP tools used across all iterations * data_sources: * type: array * items: * type: string * description: Data sources used * timestamp: * type: string * format: date-time * description: Response timestamp * sessionId: * type: string * description: Session identifier (if memory was used) * context_used: * type: boolean * description: Whether context was used * user_preferences_updated: * type: boolean * description: Whether user preferences were updated * conversation_length: * type: number * description: Current conversation length * context_summarized: * type: boolean * description: Whether context was summarized * context_summary: * type: object * description: Context summary (if summarized) * token_count: * type: object * description: Token count information * iterations_used: * type: number * description: Number of iterations used to process the query * iteration_details: * type: array * items: * type: object * properties: * iteration: * type: number * tools_called: * type: array * items: * type: string * purpose: * type: string * tool_parameters: * type: array * items: * type: object * properties: * tool_name: * type: string * parameters: * type: object * description: Detailed breakdown of each iteration including tool parameters * 400: * description: Returns error if query processing fails * 500: * description: Returns error if OpenAI API fails */ mainRouter.post('/api/mcp/query', async (req, res) => { try { const { query, sessionId: providedSessionId, userId, model, temperature, max_tokens, includeContext, updatePreferences, useMemory, maxIterations, enableDebugLogging } = req.body; if (!query || typeof query !== 'string') { return res.status(400).json({ error: 'Query is required and must be a string' }); } // Generate sessionId if not provided to enable memory features const sessionId = pro