Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import yfinance as yf
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
import plotly.graph_objects as go
|
5 |
+
import streamlit as st
|
6 |
+
import altair as alt
|
7 |
+
import matplotlib.pyplot as plt
|
8 |
+
import seaborn as sns
|
9 |
+
from bs4 import BeautifulSoup
|
10 |
+
import requests
|
11 |
+
from datetime import datetime
|
12 |
+
from rich import print
|
13 |
+
import jsonschema
|
14 |
+
|
15 |
+
# Step 1: Define a function to fetch real-time market data up to the current date
|
16 |
+
def fetch_data(ticker_symbol):
|
17 |
+
ticker = yf.Ticker(ticker_symbol)
|
18 |
+
end_date = datetime.now().strftime('%Y-%m-%d') # Get the current date
|
19 |
+
data = ticker.history(start="2023-01-01", end=end_date) # Fetches data from the start of this year to the current date
|
20 |
+
return data
|
21 |
+
|
22 |
+
# Step 2: Define a function to calculate indicators
|
23 |
+
def calculate_indicators(df, lengthEMA=3, lengthRSI=14, momentumLength=3, trendLength=50):
|
24 |
+
# Calculate Moving Averages
|
25 |
+
df['MA20'] = df['Close'].rolling(window=20).mean()
|
26 |
+
df['MA50'] = df['Close'].rolling(window=50).mean()
|
27 |
+
|
28 |
+
# Calculate EMA for Buy Signal
|
29 |
+
df['SignalEMA'] = df['Close'].ewm(span=lengthEMA, adjust=False).mean()
|
30 |
+
|
31 |
+
# Calculate RSI
|
32 |
+
delta = df['Close'].diff(1)
|
33 |
+
gain = (delta.where(delta > 0, 0)).rolling(window=lengthRSI).mean()
|
34 |
+
loss = (-delta.where(delta < 0, 0)).rolling(window=lengthRSI).mean()
|
35 |
+
rs = gain / loss
|
36 |
+
df['RSI'] = 100 - (100 / (1 + rs))
|
37 |
+
|
38 |
+
# Calculate Momentum
|
39 |
+
df['Momentum'] = df['Close'].diff(momentumLength)
|
40 |
+
|
41 |
+
# Composite SIGNAL Calculation
|
42 |
+
df['SignalComposite'] = (0.5 * df['SignalEMA']) + (0.3 * (df['RSI'] - 50) / 100) + (0.2 * (df['Momentum'] / df['Close'].rolling(window=lengthRSI).mean()))
|
43 |
+
|
44 |
+
# Smooth the Composite SIGNAL with EMA
|
45 |
+
df['SmoothedSignal'] = df['SignalComposite'].ewm(span=lengthEMA, adjust=False).mean()
|
46 |
+
|
47 |
+
# Trend Filter (SMA)
|
48 |
+
df['TrendSMA'] = df['Close'].rolling(window=trendLength).mean()
|
49 |
+
|
50 |
+
# Buy and Sell Signals
|
51 |
+
buyThreshold = 0.75
|
52 |
+
sellThreshold = -0.75
|
53 |
+
df['BuySignal'] = (df['SmoothedSignal'] > buyThreshold) & (df['Close'] > df['TrendSMA'])
|
54 |
+
df['SellSignal'] = (df['SmoothedSignal'] < sellThreshold) & (df['Close'] < df['TrendSMA'])
|
55 |
+
|
56 |
+
return df
|
57 |
+
|
58 |
+
# Step 3: Streamlit UI Setup for Stock Selection
|
59 |
+
st.title("Advanced Indian Share Market Analysis")
|
60 |
+
st.sidebar.header("Select Stock Ticker")
|
61 |
+
|
62 |
+
# Add a stock selector input box
|
63 |
+
ticker_symbol = st.sidebar.text_input("Enter Stock Ticker (e.g., RELIANCE.NS, ^NSEI)", "^NSEI")
|
64 |
+
|
65 |
+
# Step 4: Fetch Data and Calculate Indicators
|
66 |
+
try:
|
67 |
+
nifty_data = fetch_data(ticker_symbol)
|
68 |
+
nifty_data = calculate_indicators(nifty_data)
|
69 |
+
|
70 |
+
# Step 5: Display Stock Data
|
71 |
+
st.subheader(f"Data Overview for {ticker_symbol}")
|
72 |
+
st.write(nifty_data.head())
|
73 |
+
|
74 |
+
# Step 6: Interactive Visualization Using Plotly
|
75 |
+
st.subheader(f"Interactive Buy and Sell Signals for {ticker_symbol}")
|
76 |
+
fig = go.Figure()
|
77 |
+
|
78 |
+
# Add Close Price line
|
79 |
+
fig.add_trace(go.Scatter(
|
80 |
+
x=nifty_data.index,
|
81 |
+
y=nifty_data['Close'],
|
82 |
+
mode='lines',
|
83 |
+
name='Close Price',
|
84 |
+
line=dict(color='blue')
|
85 |
+
))
|
86 |
+
|
87 |
+
# Add Trend SMA line
|
88 |
+
fig.add_trace(go.Scatter(
|
89 |
+
x=nifty_data.index,
|
90 |
+
y=nifty_data['TrendSMA'],
|
91 |
+
mode='lines',
|
92 |
+
name='Trend SMA',
|
93 |
+
line=dict(color='gray')
|
94 |
+
))
|
95 |
+
|
96 |
+
# Plot Buy Signals
|
97 |
+
buy_signals = nifty_data[nifty_data['BuySignal']]
|
98 |
+
fig.add_trace(go.Scatter(
|
99 |
+
x=buy_signals.index,
|
100 |
+
y=buy_signals['Close'],
|
101 |
+
mode='markers',
|
102 |
+
name='Buy Signal',
|
103 |
+
marker=dict(symbol='triangle-up', color='green', size=10)
|
104 |
+
))
|
105 |
+
|
106 |
+
# Plot Sell Signals
|
107 |
+
sell_signals = nifty_data[nifty_data['SellSignal']]
|
108 |
+
fig.add_trace(go.Scatter(
|
109 |
+
x=sell_signals.index,
|
110 |
+
y=sell_signals['Close'],
|
111 |
+
mode='markers',
|
112 |
+
name='Sell Signal',
|
113 |
+
marker=dict(symbol='triangle-down', color='red', size=10)
|
114 |
+
))
|
115 |
+
|
116 |
+
# Update layout for better readability
|
117 |
+
fig.update_layout(
|
118 |
+
title=f"Buy and Sell Signals with Trend Filter for {ticker_symbol}",
|
119 |
+
xaxis_title="Date",
|
120 |
+
yaxis_title="Close Price",
|
121 |
+
legend_title="Legend",
|
122 |
+
template="plotly_dark"
|
123 |
+
)
|
124 |
+
|
125 |
+
st.plotly_chart(fig)
|
126 |
+
|
127 |
+
# Step 7: Altair Chart for Moving Averages
|
128 |
+
st.subheader(f"Moving Averages for {ticker_symbol}")
|
129 |
+
alt_chart = alt.Chart(nifty_data.reset_index()).mark_line().encode(
|
130 |
+
x='Date:T',
|
131 |
+
y=alt.Y('MA20:Q', title='Moving Average (20-day)'),
|
132 |
+
color=alt.value('orange')
|
133 |
+
).properties(title="20-Day Moving Average")
|
134 |
+
st.altair_chart(alt_chart, use_container_width=True)
|
135 |
+
|
136 |
+
# Step 8: Market News Integration Using BeautifulSoup
|
137 |
+
st.sidebar.header("Latest Market News")
|
138 |
+
news_url = 'https://www.moneycontrol.com/news/'
|
139 |
+
response = requests.get(news_url)
|
140 |
+
soup = BeautifulSoup(response.content, 'html.parser')
|
141 |
+
|
142 |
+
headlines = [headline.text for headline in soup.find_all('h2')[:5]]
|
143 |
+
st.sidebar.subheader("Top 5 News Headlines")
|
144 |
+
for idx, headline in enumerate(headlines, 1):
|
145 |
+
st.sidebar.write(f"{idx}. {headline}")
|
146 |
+
|
147 |
+
# Step 9: Alerts Using Rich Library
|
148 |
+
st.sidebar.subheader("Set Alerts:")
|
149 |
+
alert_type = st.sidebar.selectbox('Alert Type', ['Price', 'RSI'])
|
150 |
+
alert_value = st.sidebar.number_input('Enter Alert Value')
|
151 |
+
|
152 |
+
if alert_value:
|
153 |
+
print(f"[bold cyan]Alert Set for {alert_type} at Value:[/bold cyan] {alert_value}")
|
154 |
+
|
155 |
+
except Exception as e:
|
156 |
+
st.error(f"An error occurred: {str(e)}")
|