File size: 6,548 Bytes
540c62b 1229b10 540c62b 1229b10 540c62b a74dbcb 7ece375 a74dbcb 7ece375 540c62b 7ece375 540c62b 97600c5 1229b10 540c62b 97600c5 540c62b 1229b10 a74dbcb 540c62b 7ece375 540c62b f353842 a74dbcb 8581a28 540c62b a74dbcb 540c62b 7ece375 a74dbcb 7ece375 a74dbcb 7ece375 a74dbcb 7ece375 1229b10 540c62b |
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
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)}")
|