import yfinance as yf import pandas as pd import numpy as np import plotly.graph_objects as go import streamlit as st import altair as alt from bs4 import BeautifulSoup import requests from datetime import datetime from rich import print # Step 1: Define a function to fetch real-time market data for the selected timeframe def fetch_data(ticker_symbol, selected_timeframe): try: ticker = yf.Ticker(ticker_symbol) data = ticker.history(period=selected_timeframe) # Fetches data based on selected timeframe if data.empty: raise ValueError("No data found for the given ticker. Please check the ticker symbol.") return data except Exception as e: st.error(f"An error occurred while fetching data: {str(e)}") return pd.DataFrame() # Step 2: Define a function to calculate indicators def calculate_indicators(df, lengthEMA=3, lengthRSI=14, momentumLength=3, trendLength=50): if df.empty: return df # Calculate Moving Averages df['MA20'] = df['Close'].rolling(window=20).mean() df['MA50'] = df['Close'].rolling(window=50).mean() # Calculate EMA for Buy Signal df['SignalEMA'] = df['Close'].ewm(span=lengthEMA, adjust=False).mean() # Calculate RSI delta = df['Close'].diff(1) gain = (delta.where(delta > 0, 0)).rolling(window=lengthRSI).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=lengthRSI).mean() rs = gain / loss df['RSI'] = 100 - (100 / (1 + rs)) # Calculate Momentum df['Momentum'] = df['Close'].diff(momentumLength) # Composite SIGNAL Calculation with Dynamic Adjustments df['SignalComposite'] = (0.5 * df['SignalEMA']) + (0.3 * (df['RSI'] - 50) / 100) + (0.2 * (df['Momentum'] / df['Close'].rolling(window=lengthRSI).mean())) # Smooth the Composite SIGNAL with EMA df['SmoothedSignal'] = df['SignalComposite'].ewm(span=lengthEMA, adjust=False).mean() # Trend Filter (SMA) df['TrendSMA'] = df['Close'].rolling(window=trendLength).mean() # Adjusted Buy and Sell Thresholds buyThreshold = 1.5 # Increased threshold for stronger signals sellThreshold = -1.5 # Buy and Sell Signals with Momentum Condition df['BuySignal'] = (df['SmoothedSignal'] > buyThreshold) & (df['Close'] > df['TrendSMA']) & (df['Momentum'] > 0) df['SellSignal'] = (df['SmoothedSignal'] < sellThreshold) & (df['Close'] < df['TrendSMA']) & (df['Momentum'] < 0) # Add Cooldown Logic to Reduce Repeated Signals df['BuySignal'] = df['BuySignal'] & ~df['BuySignal'].shift(1).fillna(False) df['SellSignal'] = df['SellSignal'] & ~df['SellSignal'].shift(1).fillna(False) return df # Step 3: Streamlit UI Setup for Stock Selection st.title("Advanced Indian Share Market Analysis") st.sidebar.header("Select Stock Ticker and Timeframe") # Add a stock selector input box ticker_symbol = st.sidebar.text_input("Enter Stock Ticker (e.g., RELIANCE.NS for NSE or TCS.BO for BSE)", "^NSEI") # Step 7: Interactive Timeframe Selection and Alerts st.sidebar.subheader("Select Timeframe:") timeframes = ['1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max'] selected_timeframe = st.sidebar.selectbox('Timeframe', timeframes) # Step 4: Fetch Data and Calculate Indicators try: nifty_data = fetch_data(ticker_symbol, selected_timeframe) nifty_data = calculate_indicators(nifty_data) # Step 5: Display Stock Data if available if not nifty_data.empty: st.subheader(f"Data Overview for {ticker_symbol}") st.write(nifty_data.tail()) # Step 6: Interactive Visualization Using Plotly st.subheader(f"Interactive Buy and Sell Signals for {ticker_symbol}") fig = go.Figure() # Add Close Price line fig.add_trace(go.Scatter( x=nifty_data.index, y=nifty_data['Close'], mode='lines', name='Close Price', line=dict(color='blue') )) # Add Trend SMA line fig.add_trace(go.Scatter( x=nifty_data.index, y=nifty_data['TrendSMA'], mode='lines', name='Trend SMA', line=dict(color='gray') )) # Plot Buy Signals buy_signals = nifty_data[nifty_data['BuySignal']] fig.add_trace(go.Scatter( x=buy_signals.index, y=buy_signals['Close'], mode='markers', name='Buy Signal', marker=dict(symbol='triangle-up', color='green', size=10) )) # Plot Sell Signals sell_signals = nifty_data[nifty_data['SellSignal']] fig.add_trace(go.Scatter( x=sell_signals.index, y=sell_signals['Close'], mode='markers', name='Sell Signal', marker=dict(symbol='triangle-down', color='red', size=10) )) # Update layout for better readability fig.update_layout( title=f"Buy and Sell Signals with Trend Filter for {ticker_symbol}", xaxis_title="Date", yaxis_title="Close Price", legend_title="Legend", template="plotly_dark" ) st.plotly_chart(fig) # Step 8: Altair Chart for Moving Averages st.subheader(f"Moving Averages for {ticker_symbol}") alt_chart = alt.Chart(nifty_data.reset_index()).mark_line().encode( x='Date:T', y=alt.Y('MA20:Q', title='Moving Average (20-day)'), color=alt.value('orange') ).properties(title="20-Day Moving Average") st.altair_chart(alt_chart, use_container_width=True) # Step 9: Market News Integration Using BeautifulSoup st.sidebar.header("Latest Market News") news_url = 'https://www.moneycontrol.com/news/' response = requests.get(news_url) soup = BeautifulSoup(response.content, 'html.parser') headlines = [headline.text for headline in soup.find_all('h2')[:5]] st.sidebar.subheader("Top 5 News Headlines") for idx, headline in enumerate(headlines, 1): st.sidebar.write(f"{idx}. {headline}") # Step 10: Alerts Using Rich Library st.sidebar.subheader("Set Alerts:") alert_type = st.sidebar.selectbox('Alert Type', ['Price', 'RSI']) alert_value = st.sidebar.number_input('Enter Alert Value') if alert_value: print(f"[bold cyan]Alert Set for {alert_type} at Value:[/bold cyan] {alert_value}") except Exception as e: st.error(f"An error occurred: {str(e)}")