eshan6704 commited on
Commit
3bc7074
·
verified ·
1 Parent(s): 84a8842

Create nsepython.py

Browse files
Files changed (1) hide show
  1. app/nsepython.py +292 -0
app/nsepython.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================
2
+ # nsepython.py
3
+ # Fully working NSE fetch library
4
+ # Uses session + curl fallback for reliability
5
+ # ==============================
6
+
7
+ import os, sys, json, random, datetime, time, logging, re, urllib.parse, zipfile
8
+ from collections import Counter
9
+ from io import BytesIO, StringIO
10
+ import pandas as pd
11
+ import requests
12
+
13
+ # ------------------------- HEADERS -------------------------
14
+ headers = {
15
+ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
16
+ "accept-language": "en-US,en;q=0.9,en-IN;q=0.8,en-GB;q=0.7",
17
+ "cache-control": "max-age=0",
18
+ "sec-ch-ua": '"Microsoft Edge";v="129","Not=A?Brand";v="8","Chromium";v="129"',
19
+ "sec-ch-ua-mobile": "?0",
20
+ "sec-ch-ua-platform": '"Windows"',
21
+ "sec-fetch-dest": "document",
22
+ "sec-fetch-mode": "navigate",
23
+ "sec-fetch-site": "none",
24
+ "sec-fetch-user": "?1",
25
+ "upgrade-insecure-requests": "1",
26
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
27
+ }
28
+
29
+ niftyindices_headers = {
30
+ 'Connection': 'keep-alive',
31
+ 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
32
+ 'Accept': 'application/json, text/javascript, */*; q=0.01',
33
+ 'DNT': '1',
34
+ 'X-Requested-With': 'XMLHttpRequest',
35
+ 'sec-ch-ua-mobile': '?0',
36
+ 'User-Agent': 'Mozilla/5.0',
37
+ 'Content-Type': 'application/json; charset=UTF-8',
38
+ 'Origin': 'https://niftyindices.com',
39
+ 'Sec-Fetch-Site': 'same-origin',
40
+ 'Sec-Fetch-Mode': 'cors',
41
+ 'Sec-Fetch-Dest': 'empty',
42
+ 'Referer': 'https://niftyindices.com/reports/historical-data',
43
+ 'Accept-Language': 'en-US,en;q=0.9,hi;q=0.8',
44
+ }
45
+
46
+ curl_headers = ''' -H "authority: beta.nseindia.com" -H "cache-control: max-age=0" -H "dnt: 1" -H "upgrade-insecure-requests: 1" -H "user-agent: Mozilla/5.0" -H "sec-fetch-user: ?1" -H "accept: */*" -H "sec-fetch-site: none" -H "accept-language: en-US,en;q=0.9" --compressed'''
47
+
48
+ # ------------------------- NSE SESSION -------------------------
49
+ class NSESession:
50
+ def __init__(self):
51
+ self.s = requests.Session()
52
+ self.base_urls = ["https://www.nseindia.com", "https://www.nseindia.com/option-chain"]
53
+ self.cookies_file = "nse_cookies.txt"
54
+ self.init_session()
55
+
56
+ def init_session(self):
57
+ for url in self.base_urls:
58
+ try:
59
+ self.s.get(url, headers=headers, timeout=10)
60
+ except:
61
+ pass
62
+
63
+ def get_json(self, url):
64
+ try:
65
+ r = self.s.get(url, headers=headers, timeout=10)
66
+ r.raise_for_status()
67
+ return r.json()
68
+ except:
69
+ # fallback: curl
70
+ return self.curl_json(url)
71
+
72
+ def get_text(self, url):
73
+ try:
74
+ r = self.s.get(url, headers=headers, timeout=10)
75
+ r.raise_for_status()
76
+ return r.text
77
+ except:
78
+ # fallback: curl
79
+ return self.curl_text(url)
80
+
81
+ def download_file(self, url, local_path):
82
+ try:
83
+ r = self.s.get(url, headers=headers, timeout=10)
84
+ r.raise_for_status()
85
+ with open(local_path, "wb") as f:
86
+ f.write(r.content)
87
+ return local_path
88
+ except:
89
+ # fallback: curl
90
+ cmd = f'curl -s -L -o {local_path} "{url}"'
91
+ os.system(cmd)
92
+ if os.path.exists(local_path):
93
+ return local_path
94
+ return None
95
+
96
+ def curl_json(self, url):
97
+ try:
98
+ cmd = f'curl -s -H "User-Agent: Mozilla/5.0" "{url}"'
99
+ raw = os.popen(cmd).read()
100
+ return json.loads(raw)
101
+ except:
102
+ return {}
103
+
104
+ def curl_text(self, url):
105
+ cmd = f'curl -s -L "{url}"'
106
+ return os.popen(cmd).read()
107
+
108
+ # Create global session
109
+ nse_session = NSESession()
110
+
111
+ # ------------------------- HELPERS -------------------------
112
+ def nsesymbolpurify(s): return s.replace('&','%26')
113
+
114
+ def flatten_dict(d, parent="", sep="."):
115
+ items={}
116
+ for k,v in d.items():
117
+ nk = f"{parent}{sep}{k}" if parent else k
118
+ if isinstance(v, dict): items.update(flatten_dict(v, nk, sep))
119
+ else: items[nk] = v
120
+ return items
121
+
122
+ def flatten_nested(d, prefix=""):
123
+ flat={}
124
+ for k,v in d.items():
125
+ nk = f"{prefix}{k}" if prefix=="" else f"{prefix}.{k}"
126
+ if isinstance(v, dict):
127
+ flat.update(flatten_nested(v, nk))
128
+ elif isinstance(v, list):
129
+ if v and isinstance(v[0], dict):
130
+ for i,x in enumerate(v): flat.update(flatten_nested(x, f"{nk}.{i}"))
131
+ else: flat[nk]=v
132
+ else: flat[nk]=v
133
+ return flat
134
+
135
+ def rename_col(cols):
136
+ child=[c.split('.')[-1] for c in cols]
137
+ cnt=Counter(child)
138
+ new=[]
139
+ for c,ch in zip(cols,child):
140
+ if cnt[ch]==1: new.append(ch)
141
+ else:
142
+ p=c.split('.')
143
+ new.append(f"{p[-1]}_{p[-2]}" if len(p)>=2 else p[-1])
144
+ return new
145
+
146
+ def df_from_data(data):
147
+ rows=[ flatten_nested(x) if isinstance(x,dict) else {"value":x} for x in data ]
148
+ df=pd.DataFrame(rows)
149
+ df.columns=rename_col(df.columns)
150
+ return df
151
+
152
+ def _fmt_date(d):
153
+ return d.replace("-", "")
154
+
155
+ # ------------------------- NSE APIs -------------------------
156
+ def nsefetch(url):
157
+ return nse_session.get_json(url)
158
+
159
+ def nse_csv_fetch(url):
160
+ return nse_session.get_text(url)
161
+
162
+ def nse_zip_csv_fetch(url):
163
+ try:
164
+ r = nse_session.s.get(url, headers=headers, timeout=10)
165
+ z = zipfile.ZipFile(BytesIO(r.content))
166
+ dfs = []
167
+ for name in z.namelist():
168
+ if name.lower().endswith(".csv"):
169
+ with z.open(name) as f:
170
+ dfs.append(pd.read_csv(f))
171
+ return dfs
172
+ except:
173
+ return []
174
+
175
+ # ------------------------- NSE DATA FUNCTIONS -------------------------
176
+ def indices():
177
+ p = nsefetch("https://www.nseindia.com/api/allIndices")
178
+ return {"data":pd.DataFrame(p.pop("data")), "dates":pd.DataFrame([p.pop("dates")]), "indices":pd.DataFrame([p])}
179
+
180
+ def eq(symbol):
181
+ symbol=nsesymbolpurify(symbol)
182
+ df=nsefetch(f'https://www.nseindia.com/api/quote-equity?symbol={symbol}')
183
+ pre=df.pop('preOpenMarket')
184
+ out={
185
+ "securityInfo": pd.DataFrame([df["securityInfo"]]),
186
+ "priceInfo": pd.DataFrame([flatten_dict(df["priceInfo"])]),
187
+ "industryInfo": pd.DataFrame([df["industryInfo"]]),
188
+ "pdSectorIndAll": pd.DataFrame([df["metadata"].pop("pdSectorIndAll")]),
189
+ "metadata": pd.DataFrame([df["metadata"]]),
190
+ "info": pd.DataFrame([df["info"]]),
191
+ "preOpen": pd.DataFrame(pre.pop('preopen')),
192
+ "preOpenMarket": pd.DataFrame([pre])
193
+ }
194
+ return out
195
+
196
+ def eq_fno(): return nsefetch('https://www.nseindia.com/api/equity-stockIndices?index=SECURITIES%20IN%20F%26O')
197
+ def eq_der(symbol): return nsefetch('https://www.nseindia.com/api/quote-derivative?symbol='+nsesymbolpurify(symbol))
198
+ def index_chain(symbol): return nsefetch('https://www.nseindia.com/api/option-chain-indices?symbol='+nsesymbolpurify(symbol))
199
+ def eq_chain(symbol): return nsefetch('https://www.nseindia.com/api/option-chain-equities?symbol='+nsesymbolpurify(symbol))
200
+ def nse_holidays(t="trading"): return nsefetch('https://www.nseindia.com/api/holiday-master?type='+t)
201
+
202
+ def nse_results(index="equities",period="Quarterly"):
203
+ if index in ["equities","debt","sme"] and period in ["Quarterly","Annual","Half-Yearly","Others"]:
204
+ return pd.json_normalize(nsefetch(f'https://www.nseindia.com/api/corporates-financial-results?index={index}&period={period}'))
205
+ print("Invalid Input")
206
+
207
+ def nse_events(): return pd.json_normalize(nsefetch('https://www.nseindia.com/api/event-calendar'))
208
+ def nse_past_results(symbol): return nsefetch('https://www.nseindia.com/api/results-comparision?symbol='+nsesymbolpurify(symbol))
209
+ def nse_blockdeal(): return nsefetch('https://nseindia.com/api/block-deal')
210
+ def nse_marketStatus(): return nsefetch('https://nseindia.com/api/marketStatus')
211
+ def nse_circular(mode="latest"): return nsefetch('https://www.nseindia.com/api/latest-circular' if mode=="latest" else 'https://www.nseindia.com/api/circulars')
212
+ def nse_fiidii(mode="pandas"): return pd.DataFrame(nsefetch('https://www.nseindia.com/api/fiidiiTradeReact'))
213
+
214
+ def nsetools_get_quote(symbol):
215
+ p=nsefetch('https://www.nseindia.com/api/equity-stockIndices?index=SECURITIES%20IN%20F%26O')
216
+ for x in p['data']:
217
+ if x['symbol']==symbol.upper(): return x
218
+
219
+ def nse_index(): return pd.DataFrame(nsefetch('https://iislliveblob.niftyindices.com/jsonfiles/LiveIndicesWatch.json')['data'])
220
+
221
+ # ------------------------- INDEX FUNCTIONS -------------------------
222
+ def index_history(symbol, start_date, end_date):
223
+ start_date = _fmt_date(start_date)
224
+ end_date = _fmt_date(end_date)
225
+ data = {'cinfo': f"{{'name':'{symbol}','startDate':'{start_date}','endDate':'{end_date}','indexName':'{symbol}'}}"}
226
+ payload = nse_session.s.post('https://niftyindices.com/Backpage.aspx/getHistoricaldatatabletoString', headers=niftyindices_headers, json=data).json()
227
+ payload = json.loads(payload["d"])
228
+ return pd.DataFrame.from_records(payload)
229
+
230
+ def index_pe_pb_div(symbol, start_date, end_date):
231
+ start_date = _fmt_date(start_date)
232
+ end_date = _fmt_date(end_date)
233
+ data = {'cinfo': f"{{'name':'{symbol}','startDate':'{start_date}','endDate':'{end_date}','indexName':'{symbol}'}}"}
234
+ payload = nse_session.s.post('https://niftyindices.com/Backpage.aspx/getpepbHistoricaldataDBtoString', headers=niftyindices_headers, json=data).json()
235
+ payload = json.loads(payload["d"])
236
+ return pd.DataFrame.from_records(payload)
237
+
238
+ def index_total_returns(symbol, start_date, end_date):
239
+ start_date = _fmt_date(start_date)
240
+ end_date = _fmt_date(end_date)
241
+ data = {'cinfo': f"{{'name':'{symbol}','startDate':'{start_date}','endDate':'{end_date}','indexName':'{symbol}'}}"}
242
+ payload = nse_session.s.post('https://niftyindices.com/Backpage.aspx/getTotalReturnIndexString', headers=niftyindices_headers, json=data).json()
243
+ payload = json.loads(payload["d"])
244
+ return pd.DataFrame.from_records(payload)
245
+
246
+ # ------------------------- CSV / BHAV -------------------------
247
+ def nse_bhavcopy(d): return pd.read_csv("https://archives.nseindia.com/products/content/sec_bhavdata_full_"+d.replace("-","")+".csv")
248
+ def nse_bulkdeals(): return pd.read_csv("https://archives.nseindia.com/content/equities/bulk.csv")
249
+ def nse_blockdeals(): return pd.read_csv("https://archives.nseindia.com/content/equities/block.csv")
250
+
251
+ def nse_preopen(key="NIFTY"):
252
+ p=nsefetch("https://www.nseindia.com/api/market-data-pre-open?key="+key)
253
+ return {"data":df_from_data(p.pop("data")), "rem":df_from_data([p])}
254
+
255
+ def nse_most_active(t="securities",s="value"):
256
+ return pd.DataFrame(nsefetch(f"https://www.nseindia.com/api/live-analysis-most-active-{t}?index={s}")["data"])
257
+
258
+ def nse_eq_symbols():
259
+ return pd.read_csv('https://archives.nseindia.com/content/equities/EQUITY_L.csv')['SYMBOL'].tolist()
260
+
261
+ def nse_price_band_hitters(b="both",v="AllSec"):
262
+ p=nsefetch("https://www.nseindia.com/api/live-analysis-price-band-hitter")
263
+ return {"data":pd.DataFrame(p[b][v]["data"]), "count":pd.DataFrame([p['count']])}
264
+
265
+ def nse_largedeals(mode="bulk_deals"):
266
+ p=nsefetch('https://www.nseindia.com/api/snapshot-capital-market-largedeal')
267
+ return pd.DataFrame(p["BULK_DEALS_DATA" if mode=="bulk_deals" else "SHORT_DEALS_DATA" if mode=="short_deals" else "BLOCK_DEALS_DATA"])
268
+
269
+ def nse_largedeals_historical(f,t,mode="bulk_deals"):
270
+ m = "bulk-deals" if mode=="bulk_deals" else "short-selling" if mode=="short_deals" else "block-deals"
271
+ p=nsefetch(f'https://www.nseindia.com/api/historical/{m}?from={f}&to={t}')
272
+ return pd.DataFrame(p["data"])
273
+
274
+ def nse_stock_hist(f,t,symbol,series="ALL"):
275
+ url=f"https://www.nseindia.com/api/historical/securityArchives?from={f}&to={t}&symbol={symbol.upper()}&dataType=priceVolumeDeliverable&series={series}"
276
+ return pd.DataFrame(nsefetch(url)['data'])
277
+
278
+ def nse_index_live(name="NIFTY 50"):
279
+ p=nsefetch(f"https://www.nseindia.com/api/equity-stockIndices?index={name.replace(' ','%20')}")
280
+ return {"data":df_from_data(p.pop("data")) if "data" in p else pd.DataFrame(), "rem":df_from_data([p])}
281
+
282
+ def nse_highlow(date_str):
283
+ date_str = date_str.replace("-", "")
284
+ url="https://archives.nseindia.com/content/indices/ind_close_all_"+date_str+".csv"
285
+ return pd.read_csv(url, header=0)
286
+
287
+ def stock_highlow(date_str):
288
+ date_str = date_str.replace("-", "")
289
+ url="https://archives.nseindia.com/content/CM_52_wk_High_low_"+date_str+".csv"
290
+ return pd.read_csv(url, header=2)
291
+
292
+ # ------------------------- END OF FILE -------------------------