File size: 5,604 Bytes
df9795e
 
 
 
0bf4744
6970bbb
df9795e
 
ad3da81
df9795e
 
 
 
 
 
 
a9a420d
df9795e
 
9723d9d
 
 
 
 
 
6970bbb
df9795e
9723d9d
 
 
 
a9a420d
 
 
 
df9795e
687c3b1
df9795e
 
a9a420d
6970bbb
 
 
df9795e
 
a9a420d
df9795e
 
6970bbb
 
 
 
9723d9d
6970bbb
 
df9795e
 
 
 
 
 
 
0bf4744
df9795e
28e094d
 
6970bbb
9723d9d
 
 
 
a9a420d
 
 
 
ad3da81
 
 
 
 
df9795e
a9a420d
df9795e
6970bbb
 
 
9723d9d
 
a9a420d
 
df9795e
ad3da81
 
 
 
 
df9795e
 
ad3da81
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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.")