eshan6704 commited on
Commit
3a83327
·
verified ·
1 Parent(s): 5ec78f4

Create nse.py

Browse files
Files changed (1) hide show
  1. nse.py +220 -0
nse.py ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ================================
2
+ # NSE Fetch Module (DF Only)
3
+ # ================================
4
+
5
+ import datetime
6
+ import pandas as pd
7
+ import time
8
+ import requests
9
+ import nsepython # Moved import here
10
+
11
+ HEADERS = {
12
+ "User-Agent": "Mozilla/5.0",
13
+ "Accept-Language": "en-US,en;q=0.9",
14
+ }
15
+
16
+ session = requests.Session()
17
+ session.get("https://www.nseindia.com", headers=HEADERS, timeout=5)
18
+
19
+ # ---------------------------------------------------
20
+ # Helper: JSON Fetch
21
+ # ---------------------------------------------------
22
+ def fetch_data(url):
23
+ try:
24
+ response = session.get(url, headers=HEADERS, timeout=5)
25
+ response.raise_for_status()
26
+ return response.json()
27
+ except:
28
+ return None
29
+
30
+ # ---------------------------------------------------
31
+ # Clean DF
32
+ # ---------------------------------------------------
33
+ def clean_dataframe(df):
34
+ df.columns = df.columns.str.strip()
35
+ str_cols = df.select_dtypes(include=["object"]).columns
36
+ df[str_cols] = df[str_cols].apply(lambda x: x.str.strip())
37
+ df.fillna(0.01, inplace=True)
38
+ return df
39
+
40
+ # ---------------------------------------------------
41
+ # Bhavcopy Fetch → DataFrame
42
+ # ---------------------------------------------------
43
+ def fetch_bhavcopy_df(date):
44
+ """Returns Cleaned Bhavcopy DF for EQ / BE / SM"""
45
+ date_str = date.strftime("%d-%m-%Y")
46
+ print(f"Attempting to fetch bhavcopy for date: {date_str}")
47
+
48
+ try:
49
+ df = nsepython.get_bhavcopy(date_str) # Direct call
50
+ if df is None or df.empty:
51
+ print(f"No bhavcopy data or empty DataFrame returned for {date_str}")
52
+ return None, None
53
+
54
+ actual_bhavcopy_date = datetime.datetime.strptime(
55
+ df.iloc[2, 2].strip(), "%d-%b-%Y"
56
+ ).date()
57
+
58
+ df = clean_dataframe(df)
59
+ df_filtered = df[df.iloc[:, 1].isin(["EQ", "BE", "SM"])]
60
+
61
+ return df_filtered, actual_bhavcopy_date
62
+
63
+ except Exception as e:
64
+ print(f"An error occurred while fetching bhavcopy for {date_str}: {e}")
65
+ return None, None
66
+
67
+ # ---------------------------------------------------
68
+ # Stock Deliverable DF (security-wise archive)
69
+ # ---------------------------------------------------
70
+ def fetch_stock_df(nse_module, stock, start, end, series="ALL"):
71
+ """Return DF for security-wise archive (deliverable + all columns)"""
72
+
73
+ df = nse_module.security_wise_archive(start, end, stock, series)
74
+ if df is not None and not df.empty:
75
+ return df
76
+ return None
77
+
78
+ # ---------------------------------------------------
79
+ # All NSE Indices → DataFrames
80
+ # ---------------------------------------------------
81
+ def nse_indices_df():
82
+ url = "https://www.nseindia.com/api/allIndices"
83
+ data = fetch_data(url)
84
+ if data is None:
85
+ return None, None, None
86
+
87
+ df_dates = pd.DataFrame([data["dates"]])
88
+ df_meta = pd.DataFrame([{k: v for k, v in data.items() if k not in ["data", "dates"]}])
89
+ df_data = pd.DataFrame(data["data"])
90
+
91
+ return df_dates, df_meta, df_data
92
+
93
+ # ---------------------------------------------------
94
+ # Specific Index → DataFrames
95
+ # ---------------------------------------------------
96
+ def nse_index_df(index_name="NIFTY 50"):
97
+ url = f"https://www.nseindia.com/api/equity-stockIndices?index={index_name.replace(' ', '%20')}"
98
+ data = fetch_data(url)
99
+ if data is None:
100
+ return None, None, None, None
101
+
102
+ df_market = pd.DataFrame([data["marketStatus"]])
103
+ df_adv = pd.DataFrame([data["advance"]])
104
+ df_meta = pd.DataFrame([data["metadata"]])
105
+ df_data = pd.DataFrame(data["data"])
106
+
107
+ return df_market, df_adv, df_meta, df_data
108
+
109
+ # ---------------------------------------------------
110
+ # Option Chain DF (Raw CE/PE)
111
+ # ---------------------------------------------------
112
+ def fetch_option_chain_df(symbol="NIFTY"):
113
+ url = f"https://www.nseindia.com/api/option-chain-indices?symbol={symbol}"
114
+ data = fetch_data(url)
115
+
116
+ if data and "filtered" in data:
117
+ ce_df = pd.DataFrame([r["CE"] for r in data["filtered"]["data"] if "CE" in r])
118
+ pe_df = pd.DataFrame([r["PE"] for r in data["filtered"]["data"] if "PE" in r])
119
+ return ce_df, pe_df
120
+
121
+ return None, None
122
+
123
+ # ---------------------------------------------------
124
+ # Pre-open market → DataFrame
125
+ # ---------------------------------------------------
126
+ def nse_preopen_df(key="NIFTY"):
127
+ url = f"https://www.nseindia.com/api/market-data-pre-open?key={key}"
128
+ data = fetch_data(url)
129
+ if data:
130
+ return pd.DataFrame(data.get("data", []))
131
+ return None
132
+
133
+ # ---------------------------------------------------
134
+ # FNO Quote → DataFrames
135
+ # ---------------------------------------------------
136
+ def nse_fno_df(symbol):
137
+ payload = nsepython.nse_quote(symbol) # Direct call
138
+ if not payload:
139
+ return None
140
+
141
+ # info + timestamps + volatility info
142
+ info_keys = list(payload["info"].keys()) + [
143
+ "fut_timestamp",
144
+ "opt_timestamp",
145
+ "maxVolatility",
146
+ "minVolatility",
147
+ "avgVolatility",
148
+ ]
149
+
150
+ info_values = list(payload["info"].values()) + [
151
+ payload["fut_timestamp"],
152
+ payload["opt_timestamp"],
153
+ payload["underlyingInfo"]["volatility"][0]['maxVolatility'],
154
+ payload["underlyingInfo"]["volatility"][0]['minVolatility'],
155
+ payload["underlyingInfo"]["volatility"][0]['avgVolatility'],
156
+ ]
157
+
158
+ df_info = pd.DataFrame([info_values], columns=info_keys)
159
+
160
+ df_mcap = pd.DataFrame(payload["underlyingInfo"].get("marketCap", {}))
161
+ df_fno_list = pd.DataFrame(payload.get("allSymbol", []), columns=["FNO_Symbol"])
162
+
163
+ # Core stock depth
164
+ df_stock = process_stocks_df(payload["stocks"])
165
+
166
+ return {
167
+ "info": df_info,
168
+ "mcap": df_mcap,
169
+ "fno": df_fno_list,
170
+ "stock": df_stock
171
+ }
172
+
173
+ # ---------------------------------------------------
174
+ # Handle nested stock → DF
175
+ # ---------------------------------------------------
176
+ def process_stocks_df(data):
177
+ """Return final merged stock DF only"""
178
+ trade_info_list, other_info_list = [], []
179
+ bid_ask_list = []
180
+ stock_values = []
181
+ trade_keys = other_keys = bidask_keys = stock_keys = None
182
+
183
+ for i, stock in enumerate(data):
184
+ meta = stock.pop("metadata")
185
+ depth = stock.pop("marketDeptOrderBook")
186
+ parent = stock
187
+
188
+ trade_info = depth.pop("tradeInfo", {})
189
+ other_info = depth.pop("otherInfo", {})
190
+
191
+ trade_info_list.append(trade_info)
192
+ other_info_list.append(other_info)
193
+
194
+ # bid / ask
195
+ bid_ask_row = {}
196
+ for side in ["bid", "ask"]:
197
+ for j, entry in enumerate(depth.get(side, []), start=1):
198
+ bid_ask_row[f"{side}_price_{j}"] = entry.get("price")
199
+ bid_ask_row[f"{side}_qty_{j}"] = entry.get("quantity")
200
+
201
+ bid_ask_list.append(bid_ask_row)
202
+
203
+ if i == 0:
204
+ trade_keys = list(trade_info.keys())
205
+ other_keys = list(other_info.keys())
206
+ bidask_keys = list(bid_ask_row.keys())
207
+ stock_keys = list(meta.keys()) + list(depth.keys()) + list(parent.keys())
208
+
209
+ stock_values.append(
210
+ list(meta.values()) + list(depth.values()) + list(parent.values())
211
+ )
212
+
213
+ df_trade = pd.DataFrame(trade_info_list, columns=trade_keys)
214
+ df_other = pd.DataFrame(other_info_list, columns=other_keys)
215
+ df_bidask = pd.DataFrame(bid_ask_list, columns=bidask_keys)
216
+ df_stock = pd.DataFrame(stock_values, columns=stock_keys)
217
+
218
+ df_stock = df_stock.drop(columns=['bid', 'ask', 'carryOfCost'], errors="ignore")
219
+
220
+ return pd.concat([df_stock, df_trade, df_other, df_bidask], axis=1)