Update app.py
Browse files
app.py
CHANGED
@@ -15,28 +15,25 @@ futures_stocks = [
|
|
15 |
"COALINDIA.NS", "CONCOR.NS", "CUMMINSIND.NS", "DABUR.NS", "DELTACORP.NS",
|
16 |
"DIVISLAB.NS", "DLF.NS", "DRREDDY.NS", "EICHERMOT.NS", "FEDERALBNK.NS",
|
17 |
"GAIL.NS", "GLENMARK.NS", "GMRINFRA.NS", "GODREJCP.NS", "GODREJPROP.NS",
|
18 |
-
"GRANULES.NS", "GRASIM.NS", "HAVELLS.NS", "HCLTECH.NS",
|
19 |
-
"
|
20 |
-
"
|
21 |
-
"
|
22 |
-
"
|
23 |
-
"
|
24 |
-
"
|
25 |
-
"
|
26 |
-
"
|
27 |
-
"MFSL.NS", "MGL.NS", "MINDTREE.NS", "MOTHERSUMI.NS", "MPHASIS.NS",
|
28 |
"MRF.NS", "MUTHOOTFIN.NS", "NAM-INDIA.NS", "NATIONALUM.NS", "NAUKRI.NS",
|
29 |
-
"NAVINFLUOR.NS", "NBCC.NS", "NESTLEIND.NS", "NMDC.NS", "NTPC.NS",
|
30 |
-
"
|
31 |
-
"
|
32 |
-
"
|
33 |
-
"
|
34 |
-
"SHREECEM.NS", "SIEMENS.NS", "SRF.NS", "SRTRANSFIN.NS", "SUNPHARMA.NS",
|
35 |
"SUNTV.NS", "TATACHEM.NS", "TATACOMM.NS", "TATACONSUM.NS", "TATAMOTORS.NS",
|
36 |
-
"TATAPOWER.NS", "TATASTEEL.NS", "TCS.NS", "TECHM.NS", "TITAN.NS",
|
37 |
-
"
|
38 |
-
"
|
39 |
-
"WHIRLPOOL.NS", "WIPRO.NS", "ZEEL.NS"
|
40 |
]
|
41 |
|
42 |
# Predefined setups
|
@@ -84,7 +81,69 @@ predefined_setups = {
|
|
84 |
}
|
85 |
}
|
86 |
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
def main():
|
90 |
st.title("Indian Stock Market Scanner: RSI, Stochastic RSI, and OBV")
|
|
|
15 |
"COALINDIA.NS", "CONCOR.NS", "CUMMINSIND.NS", "DABUR.NS", "DELTACORP.NS",
|
16 |
"DIVISLAB.NS", "DLF.NS", "DRREDDY.NS", "EICHERMOT.NS", "FEDERALBNK.NS",
|
17 |
"GAIL.NS", "GLENMARK.NS", "GMRINFRA.NS", "GODREJCP.NS", "GODREJPROP.NS",
|
18 |
+
"GRANULES.NS", "GRASIM.NS", "HAVELLS.NS", "HCLTECH.NS", "HDFCAMC.NS",
|
19 |
+
"HDFCBANK.NS", "HDFCLIFE.NS", "HEROMOTOCO.NS", "HINDALCO.NS", "HINDCOPPER.NS",
|
20 |
+
"HINDPETRO.NS", "HINDUNILVR.NS", "IBULHSGFIN.NS", "ICICIBANK.NS", "ICICIGI.NS",
|
21 |
+
"ICICIPRULI.NS", "IDEA.NS", "IDFCFIRSTB.NS", "INDHOTEL.NS", "INDIACEM.NS",
|
22 |
+
"INDIAMART.NS", "INDIGO.NS", "INDUSINDBK.NS", "INFY.NS", "IRCTC.NS", "ITC.NS",
|
23 |
+
"JINDALSTEL.NS", "JSWSTEEL.NS", "JUBLFOOD.NS", "KOTAKBANK.NS", "L&TFH.NS",
|
24 |
+
"LALPATHLAB.NS", "LAURUSLABS.NS", "LICHSGFIN.NS", "LT.NS", "LUPIN.NS", "M&M.NS",
|
25 |
+
"M&MFIN.NS", "MANAPPURAM.NS", "MARICO.NS", "MARUTI.NS", "MCDOWELL-N.NS", "MCX.NS",
|
26 |
+
"METROPOLIS.NS", "MFSL.NS", "MGL.NS", "MINDTREE.NS", "MOTHERSUMI.NS", "MPHASIS.NS",
|
|
|
27 |
"MRF.NS", "MUTHOOTFIN.NS", "NAM-INDIA.NS", "NATIONALUM.NS", "NAUKRI.NS",
|
28 |
+
"NAVINFLUOR.NS", "NBCC.NS", "NESTLEIND.NS", "NMDC.NS", "NTPC.NS", "ONGC.NS",
|
29 |
+
"PAGEIND.NS", "PEL.NS", "PETRONET.NS", "PFC.NS", "PFIZER.NS", "PIDILITIND.NS",
|
30 |
+
"PIIND.NS", "PNB.NS", "POLYCAB.NS", "POWERGRID.NS", "PVR.NS", "RAMCOCEM.NS",
|
31 |
+
"RBLBANK.NS", "RECLTD.NS", "RELIANCE.NS", "SAIL.NS", "SBICARD.NS", "SBILIFE.NS",
|
32 |
+
"SBIN.NS", "SHREECEM.NS", "SIEMENS.NS", "SRF.NS", "SRTRANSFIN.NS", "SUNPHARMA.NS",
|
|
|
33 |
"SUNTV.NS", "TATACHEM.NS", "TATACOMM.NS", "TATACONSUM.NS", "TATAMOTORS.NS",
|
34 |
+
"TATAPOWER.NS", "TATASTEEL.NS", "TCS.NS", "TECHM.NS", "TITAN.NS", "TORNTPHARM.NS",
|
35 |
+
"TORNTPOWER.NS", "TRENT.NS", "TVSMOTOR.NS", "UBL.NS", "ULTRACEMCO.NS", "UPL.NS",
|
36 |
+
"VBL.NS", "VEDL.NS", "VOLTAS.NS", "WHIRLPOOL.NS", "WIPRO.NS", "ZEEL.NS"
|
|
|
37 |
]
|
38 |
|
39 |
# Predefined setups
|
|
|
81 |
}
|
82 |
}
|
83 |
|
84 |
+
@st.cache_data
|
85 |
+
def fetch_and_calculate_indicators(ticker, start_date, end_date, rsi_length, stoch_length, k_period, d_period):
|
86 |
+
try:
|
87 |
+
df = yf.download(ticker, start=start_date, end=end_date)
|
88 |
+
|
89 |
+
if df.empty:
|
90 |
+
return None
|
91 |
+
|
92 |
+
# Calculate RSI
|
93 |
+
df['RSI'] = ta.momentum.RSIIndicator(df['Close'], window=rsi_length).rsi()
|
94 |
+
|
95 |
+
# Calculate Stochastic RSI
|
96 |
+
stoch_rsi = ta.momentum.StochRSIIndicator(
|
97 |
+
df['Close'],
|
98 |
+
window=stoch_length,
|
99 |
+
smooth1=k_period,
|
100 |
+
smooth2=d_period
|
101 |
+
)
|
102 |
+
df['StochRSI_K'] = stoch_rsi.stochrsi_k()
|
103 |
+
df['StochRSI_D'] = stoch_rsi.stochrsi_d()
|
104 |
+
|
105 |
+
# Calculate OBV
|
106 |
+
df['OBV'] = ta.volume.OnBalanceVolumeIndicator(df['Close'], df['Volume']).on_balance_volume()
|
107 |
+
|
108 |
+
if df['RSI'].isna().all() or df['StochRSI_K'].isna().all() or df['OBV'].isna().all():
|
109 |
+
return None
|
110 |
+
|
111 |
+
return df
|
112 |
+
except Exception as e:
|
113 |
+
st.error(f"Error occurred for {ticker}: {str(e)}")
|
114 |
+
return None
|
115 |
+
|
116 |
+
def filter_stocks_by_indicators(stocks, start_date, end_date, rsi_threshold, stoch_rsi_threshold, obv_threshold, indicator_choice, rsi_length, stoch_length, k_period, d_period):
|
117 |
+
filtered_stocks = []
|
118 |
+
progress_bar = st.progress(0)
|
119 |
+
for i, ticker in enumerate(stocks):
|
120 |
+
df = fetch_and_calculate_indicators(ticker, start_date, end_date, rsi_length, stoch_length, k_period, d_period)
|
121 |
+
if df is not None and not df['RSI'].empty and not df['StochRSI_K'].empty and not df['OBV'].empty:
|
122 |
+
rsi_value = df['RSI'].iloc[-1]
|
123 |
+
stoch_rsi_value = df['StochRSI_K'].iloc[-1]
|
124 |
+
obv_value = df['OBV'].iloc[-1]
|
125 |
+
obv_change = (df['OBV'].iloc[-1] - df['OBV'].iloc[-2]) / df['OBV'].iloc[-2] * 100 # Percentage change
|
126 |
+
|
127 |
+
if not pd.isna(rsi_value) and not pd.isna(stoch_rsi_value) and not pd.isna(obv_value):
|
128 |
+
if (indicator_choice == 'RSI' and rsi_value < rsi_threshold) or \
|
129 |
+
(indicator_choice == 'StochRSI' and stoch_rsi_value < stoch_rsi_threshold) or \
|
130 |
+
(indicator_choice == 'OBV' and obv_change > obv_threshold) or \
|
131 |
+
(indicator_choice == 'All' and rsi_value < rsi_threshold and stoch_rsi_value < stoch_rsi_threshold and obv_change > obv_threshold):
|
132 |
+
filtered_stocks.append({
|
133 |
+
'Ticker': ticker,
|
134 |
+
'RSI': rsi_value,
|
135 |
+
'StochRSI': stoch_rsi_value,
|
136 |
+
'OBV_Change': obv_change
|
137 |
+
})
|
138 |
+
st.info(f"{ticker} - RSI: {rsi_value:.2f}, StochRSI: {stoch_rsi_value:.2f}, OBV Change: {obv_change:.2f}%")
|
139 |
+
else:
|
140 |
+
st.info(f"{ticker} - RSI: {rsi_value:.2f}, StochRSI: {stoch_rsi_value:.2f}, OBV Change: {obv_change:.2f}% (doesn't meet criteria)")
|
141 |
+
else:
|
142 |
+
st.info(f"{ticker} has NaN value for RSI, StochRSI, or OBV.")
|
143 |
+
else:
|
144 |
+
st.info(f"No valid data available for {ticker}.")
|
145 |
+
progress_bar.progress((i + 1) / len(stocks))
|
146 |
+
return filtered_stocks
|
147 |
|
148 |
def main():
|
149 |
st.title("Indian Stock Market Scanner: RSI, Stochastic RSI, and OBV")
|