riteshcp's picture
Update app.py
8581a28 verified
raw
history blame
6.55 kB
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)}")