|
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 |
|
|
|
|
|
def fetch_data(ticker_symbol, selected_timeframe): |
|
try: |
|
ticker = yf.Ticker(ticker_symbol) |
|
data = ticker.history(period=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() |
|
|
|
|
|
def calculate_indicators(df, lengthEMA=3, lengthRSI=14, momentumLength=3, trendLength=50): |
|
if df.empty: |
|
return df |
|
|
|
|
|
df['MA20'] = df['Close'].rolling(window=20).mean() |
|
df['MA50'] = df['Close'].rolling(window=50).mean() |
|
|
|
|
|
df['SignalEMA'] = df['Close'].ewm(span=lengthEMA, adjust=False).mean() |
|
|
|
|
|
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)) |
|
|
|
|
|
df['Momentum'] = df['Close'].diff(momentumLength) |
|
|
|
|
|
df['SignalComposite'] = (0.5 * df['SignalEMA']) + (0.3 * (df['RSI'] - 50) / 100) + (0.2 * (df['Momentum'] / df['Close'].rolling(window=lengthRSI).mean())) |
|
|
|
|
|
df['SmoothedSignal'] = df['SignalComposite'].ewm(span=lengthEMA, adjust=False).mean() |
|
|
|
|
|
df['TrendSMA'] = df['Close'].rolling(window=trendLength).mean() |
|
|
|
|
|
buyThreshold = 1.5 |
|
sellThreshold = -1.5 |
|
|
|
|
|
df['BuySignal'] = (df['SmoothedSignal'] > buyThreshold) & (df['Close'] > df['TrendSMA']) & (df['Momentum'] > 0) |
|
df['SellSignal'] = (df['SmoothedSignal'] < sellThreshold) & (df['Close'] < df['TrendSMA']) & (df['Momentum'] < 0) |
|
|
|
|
|
df['BuySignal'] = df['BuySignal'] & ~df['BuySignal'].shift(1).fillna(False) |
|
df['SellSignal'] = df['SellSignal'] & ~df['SellSignal'].shift(1).fillna(False) |
|
|
|
return df |
|
|
|
|
|
st.title("Advanced Indian Share Market Analysis") |
|
st.sidebar.header("Select Stock Ticker and Timeframe") |
|
|
|
|
|
ticker_symbol = st.sidebar.text_input("Enter Stock Ticker (e.g., RELIANCE.NS for NSE or TCS.BO for BSE)", "^NSEI") |
|
|
|
|
|
st.sidebar.subheader("Select Timeframe:") |
|
timeframes = ['1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max'] |
|
selected_timeframe = st.sidebar.selectbox('Timeframe', timeframes) |
|
|
|
|
|
|
|
try: |
|
nifty_data = fetch_data(ticker_symbol, selected_timeframe) |
|
nifty_data = calculate_indicators(nifty_data) |
|
|
|
|
|
if not nifty_data.empty: |
|
st.subheader(f"Data Overview for {ticker_symbol}") |
|
st.write(nifty_data.tail()) |
|
|
|
|
|
st.subheader(f"Interactive Buy and Sell Signals for {ticker_symbol}") |
|
fig = go.Figure() |
|
|
|
|
|
fig.add_trace(go.Scatter( |
|
x=nifty_data.index, |
|
y=nifty_data['Close'], |
|
mode='lines', |
|
name='Close Price', |
|
line=dict(color='blue') |
|
)) |
|
|
|
|
|
fig.add_trace(go.Scatter( |
|
x=nifty_data.index, |
|
y=nifty_data['TrendSMA'], |
|
mode='lines', |
|
name='Trend SMA', |
|
line=dict(color='gray') |
|
)) |
|
|
|
|
|
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) |
|
)) |
|
|
|
|
|
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) |
|
)) |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
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}") |
|
|
|
|
|
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)}") |
|
|