import streamlit as st import yfinance as yf import pandas as pd import numpy as np import ta from datetime import datetime # Streamlit Title st.title("NIFTY 500 Turtle Strategy Scanner with Support, Resistance, RSI, and Volume Filters") # Load the NIFTY 500 stock list stock_list = pd.read_csv('ind_nifty500list.csv') stock_list['Symbol'] = stock_list['Symbol'] + ".NS" nifty_500_stocks = stock_list['Symbol'].tolist() # Sidebar for Parameters st.sidebar.header("Turtle Strategy, RSI, and Support/Resistance Parameters") entry_days = st.sidebar.slider("Entry Lookback Period (days)", min_value=10, max_value=60, value=20, step=1) exit_days = st.sidebar.slider("Exit Lookback Period (days)", min_value=5, max_value=30, value=10, step=1) # RSI Thresholds lower_rsi_threshold = st.sidebar.slider("Lower RSI Threshold (Oversold)", min_value=10, max_value=50, value=30, step=5) upper_rsi_threshold = st.sidebar.slider("Upper RSI Threshold (Overbought)", min_value=50, max_value=90, value=70, step=5) # Volume Threshold volume_threshold = st.sidebar.number_input("Volume Threshold", min_value=100000, value=500000) # Moving Average Parameters short_term_ma = st.sidebar.slider("Short-Term Moving Average (days)", min_value=5, max_value=50, value=20, step=1) long_term_ma = st.sidebar.slider("Long-Term Moving Average (days)", min_value=20, max_value=200, value=50, step=1) # Support and Resistance Lookback Periods support_period = st.sidebar.slider("Support Lookback Period (days)", min_value=5, max_value=50, value=20, step=1) resistance_period = st.sidebar.slider("Resistance Lookback Period (days)", min_value=5, max_value=50, value=20, step=1) # Option to limit the number of stocks to scan limit_stocks = st.sidebar.slider("Number of Stocks to Scan", min_value=5, max_value=len(nifty_500_stocks), value=502, step=5) # Initialize an empty DataFrame to store the filtered stocks filtered_data = pd.DataFrame(columns=["Stock", "Latest Price", "RSI", "Volume", "Short MA", "Long MA", "Support", "Resistance", "Entry Signal", "Exit Signal"]) # Get today's date for the end date end_date = datetime.today().strftime('%Y-%m-%d') # Loop through the selected stocks to scan st.write(f"Scanning the top {limit_stocks} stocks in NIFTY 500 based on Turtle Strategy, Support/Resistance, RSI, and Volume...") for symbol in nifty_500_stocks[:limit_stocks]: try: # Fetch historical data for the stock up to today's date data = yf.download(symbol, start='2022-01-01', end=end_date, progress=False) # Check if the data is sufficient for analysis if len(data) < long_term_ma: st.write(f"Skipping {symbol}: Not enough data available.") continue # Calculate Turtle Strategy parameters data['20D_High'] = data['High'].rolling(window=entry_days).max() data['10D_Low'] = data['Low'].rolling(window=exit_days).min() # Entry and Exit Signals data['Long'] = np.where(data['Close'] > data['20D_High'].shift(1), 1, 0) data['Exit'] = np.where(data['Close'] < data['10D_Low'].shift(1), 1, 0) # Calculate RSI using 'ta' library data['RSI'] = ta.momentum.RSIIndicator(data['Close'], window=14).rsi() # Calculate Moving Averages for confirmation data['Short_MA'] = ta.trend.SMAIndicator(data['Close'], window=short_term_ma).sma_indicator() data['Long_MA'] = ta.trend.SMAIndicator(data['Close'], window=long_term_ma).sma_indicator() # Calculate Support and Resistance Levels data['Support'] = data['Low'].rolling(window=support_period).min() data['Resistance'] = data['High'].rolling(window=resistance_period).max() # Position Management data['Position'] = 0 data.loc[data['Long'] == 1, 'Position'] = 1 data.loc[data['Exit'] == 1, 'Position'] = 0 data['Position'] = data['Position'].ffill().shift(1).fillna(0) # Check for the latest entry or exit signal, RSI, Volume, and Support/Resistance latest_entry = data['Long'].iloc[-1] # Last Long signal (Entry) latest_exit = data['Exit'].iloc[-1] # Last Exit signal latest_rsi = data['RSI'].iloc[-1] # Last RSI value latest_volume = data['Volume'].iloc[-1] # Last Volume latest_short_ma = data['Short_MA'].iloc[-1] # Latest Short-Term MA latest_long_ma = data['Long_MA'].iloc[-1] # Latest Long-Term MA latest_support = data['Support'].iloc[-1] # Latest Support Level latest_resistance = data['Resistance'].iloc[-1] # Latest Resistance Level # Filter based on Support/Resistance, RSI, Volume, and Moving Averages if (latest_entry == 1 or latest_exit == 1) and ((latest_rsi <= lower_rsi_threshold or latest_rsi >= upper_rsi_threshold)) and latest_volume > volume_threshold and latest_short_ma > latest_long_ma: latest_price = data['Close'].iloc[-1] filtered_data = pd.concat([filtered_data, pd.DataFrame([[symbol, latest_price, latest_rsi, latest_volume, latest_short_ma, latest_long_ma, latest_support, latest_resistance, latest_entry, latest_exit]], columns=filtered_data.columns)], ignore_index=True) except Exception as e: st.write(f"Error processing {symbol}: {e}") # Display the filtered stocks that meet the criteria if not filtered_data.empty: st.subheader(f"Filtered Stocks with Support/Resistance, Moving Average, Custom RSI, and Volume Thresholds:") st.dataframe(filtered_data) else: st.write("No stocks meeting the criteria for entry/exit signals, Support/Resistance, RSI, MA, or volume thresholds.")