Spaces:
Runtime error
Runtime error
| 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.") |