Upload 10 files
Browse files- market_overview.py +26 -10
- pages/market_overview.py +139 -0
- pages/predictions.py +145 -0
- pages/quantum_patterns.py +155 -0
- pages/sentiment_heatmap.py +214 -0
- pages/technical_analysis.py +171 -0
- predictions.py +40 -13
- technical_analysis.py +113 -41
market_overview.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
-
import
|
| 3 |
import pandas as pd # Added import statement for pandas
|
| 4 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data, get_stock_info
|
| 5 |
|
|
@@ -82,7 +82,7 @@ with cols[2]:
|
|
| 82 |
st.dataframe(pd.DataFrame(active_data))
|
| 83 |
|
| 84 |
# Sector Performance Heat Map
|
| 85 |
-
st.subheader(f"{selected_sector} Performance
|
| 86 |
heat_map_data = []
|
| 87 |
for symbol in sectors[selected_sector]:
|
| 88 |
data = fetch_stock_data(symbol, period='1d')
|
|
@@ -92,16 +92,32 @@ for symbol in sectors[selected_sector]:
|
|
| 92 |
heat_map_data.append({
|
| 93 |
'Company': info['name'],
|
| 94 |
'Symbol': symbol,
|
| 95 |
-
'Change%': change
|
|
|
|
|
|
|
| 96 |
})
|
| 97 |
|
| 98 |
if heat_map_data:
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
# Detailed Sector Analysis
|
| 107 |
st.subheader(f"{selected_sector} Companies")
|
|
@@ -120,4 +136,4 @@ for symbol in sectors[selected_sector]:
|
|
| 120 |
})
|
| 121 |
|
| 122 |
if detailed_data:
|
| 123 |
-
st.dataframe(pd.DataFrame(detailed_data))
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
import pandas as pd # Added import statement for pandas
|
| 4 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data, get_stock_info
|
| 5 |
|
|
|
|
| 82 |
st.dataframe(pd.DataFrame(active_data))
|
| 83 |
|
| 84 |
# Sector Performance Heat Map
|
| 85 |
+
st.subheader(f"{selected_sector} Performance Heat Map")
|
| 86 |
heat_map_data = []
|
| 87 |
for symbol in sectors[selected_sector]:
|
| 88 |
data = fetch_stock_data(symbol, period='1d')
|
|
|
|
| 92 |
heat_map_data.append({
|
| 93 |
'Company': info['name'],
|
| 94 |
'Symbol': symbol,
|
| 95 |
+
'Change%': change,
|
| 96 |
+
'Market Cap': info['market_cap'],
|
| 97 |
+
'Volume': info['volume']
|
| 98 |
})
|
| 99 |
|
| 100 |
if heat_map_data:
|
| 101 |
+
fig = go.Figure(data=[go.Treemap(
|
| 102 |
+
labels=[f"{d['Company']}<br>{d['Symbol']}" for d in heat_map_data],
|
| 103 |
+
parents=[''] * len(heat_map_data),
|
| 104 |
+
values=[d['Market Cap'] for d in heat_map_data],
|
| 105 |
+
textinfo="label+value+percent",
|
| 106 |
+
marker=dict(
|
| 107 |
+
colors=[d['Change%'] for d in heat_map_data],
|
| 108 |
+
colorscale='RdYlGn',
|
| 109 |
+
showscale=True
|
| 110 |
+
),
|
| 111 |
+
hovertemplate="""
|
| 112 |
+
Company: %{label}<br>
|
| 113 |
+
Change: %{color:.2f}%<br>
|
| 114 |
+
Market Cap: ₹%{value:,.0f}<br>
|
| 115 |
+
<extra></extra>
|
| 116 |
+
"""
|
| 117 |
+
)])
|
| 118 |
+
|
| 119 |
+
fig.update_layout(title=f"{selected_sector} Companies Heat Map")
|
| 120 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 121 |
|
| 122 |
# Detailed Sector Analysis
|
| 123 |
st.subheader(f"{selected_sector} Companies")
|
|
|
|
| 136 |
})
|
| 137 |
|
| 138 |
if detailed_data:
|
| 139 |
+
st.dataframe(pd.DataFrame(detailed_data))
|
pages/market_overview.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
import pandas as pd # Added import statement for pandas
|
| 4 |
+
from utils.data_loader import load_nifty50_symbols, fetch_stock_data, get_stock_info
|
| 5 |
+
|
| 6 |
+
st.title("Market Overview")
|
| 7 |
+
|
| 8 |
+
# Create sector categories
|
| 9 |
+
sectors = {
|
| 10 |
+
"IT": ["TCS.NS", "INFY.NS", "HCLTECH.NS", "TECHM.NS", "WIPRO.NS"],
|
| 11 |
+
"Banking & Finance": ["HDFCBANK.NS", "ICICIBANK.NS", "SBIN.NS", "AXISBANK.NS", "KOTAKBANK.NS",
|
| 12 |
+
"BAJFINANCE.NS", "BAJAJFINSV.NS", "HDFC.NS", "INDUSINDBK.NS"],
|
| 13 |
+
"Energy & Oil": ["RELIANCE.NS", "ONGC.NS", "POWERGRID.NS", "NTPC.NS", "BPCL.NS"],
|
| 14 |
+
"Automobile": ["TATAMOTORS.NS", "M&M.NS", "MARUTI.NS", "HEROMOTOCO.NS", "EICHERMOT.NS"],
|
| 15 |
+
"Consumer Goods": ["HINDUNILVR.NS", "ITC.NS", "NESTLEIND.NS", "BRITANNIA.NS", "TITAN.NS"],
|
| 16 |
+
"Metals & Mining": ["TATASTEEL.NS", "HINDALCO.NS", "JSWSTEEL.NS", "COALINDIA.NS"],
|
| 17 |
+
"Pharmaceuticals": ["SUNPHARMA.NS", "DRREDDY.NS", "CIPLA.NS", "DIVISLAB.NS"],
|
| 18 |
+
"Infrastructure": ["LT.NS", "ADANIPORTS.NS", "ULTRACEMCO.NS", "SHREECEM.NS", "GRASIM.NS"],
|
| 19 |
+
"Others": ["BHARTIARTL.NS", "ASIANPAINT.NS", "HDFCLIFE.NS", "SBILIFE.NS", "UPL.NS",
|
| 20 |
+
"ADANIENT.NS", "BAJAJ-AUTO.NS", "APOLLOHOSP.NS", "DMART.NS", "PIDILITIND.NS"]
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
# Sector selection
|
| 24 |
+
selected_sector = st.selectbox("Select Sector", list(sectors.keys()))
|
| 25 |
+
|
| 26 |
+
# Load data for selected sector
|
| 27 |
+
cols = st.columns(3)
|
| 28 |
+
|
| 29 |
+
# Market Movers for selected sector
|
| 30 |
+
with cols[0]:
|
| 31 |
+
st.subheader("Top Gainers")
|
| 32 |
+
gainers_data = []
|
| 33 |
+
for symbol in sectors[selected_sector]:
|
| 34 |
+
data = fetch_stock_data(symbol, period='1d')
|
| 35 |
+
if data is not None:
|
| 36 |
+
change = ((data['Close'][-1] - data['Open'][0]) / data['Open'][0]) * 100
|
| 37 |
+
info = get_stock_info(symbol)
|
| 38 |
+
company_name = info['name'] if info else symbol
|
| 39 |
+
gainers_data.append({
|
| 40 |
+
'Company': company_name,
|
| 41 |
+
'Symbol': symbol,
|
| 42 |
+
'Change%': change
|
| 43 |
+
})
|
| 44 |
+
|
| 45 |
+
# Sort gainers by change percentage
|
| 46 |
+
gainers_data = sorted(gainers_data, key=lambda x: x['Change%'], reverse=True)[:3]
|
| 47 |
+
st.dataframe(pd.DataFrame(gainers_data))
|
| 48 |
+
|
| 49 |
+
with cols[1]:
|
| 50 |
+
st.subheader("Top Losers")
|
| 51 |
+
losers_data = []
|
| 52 |
+
for symbol in sectors[selected_sector]:
|
| 53 |
+
data = fetch_stock_data(symbol, period='1d')
|
| 54 |
+
if data is not None:
|
| 55 |
+
change = ((data['Close'][-1] - data['Open'][0]) / data['Open'][0]) * 100
|
| 56 |
+
info = get_stock_info(symbol)
|
| 57 |
+
company_name = info['name'] if info else symbol
|
| 58 |
+
losers_data.append({
|
| 59 |
+
'Company': company_name,
|
| 60 |
+
'Symbol': symbol,
|
| 61 |
+
'Change%': change
|
| 62 |
+
})
|
| 63 |
+
|
| 64 |
+
# Sort losers by change percentage
|
| 65 |
+
losers_data = sorted(losers_data, key=lambda x: x['Change%'])[:3]
|
| 66 |
+
st.dataframe(pd.DataFrame(losers_data))
|
| 67 |
+
|
| 68 |
+
with cols[2]:
|
| 69 |
+
st.subheader("Most Active")
|
| 70 |
+
active_data = []
|
| 71 |
+
for symbol in sectors[selected_sector]:
|
| 72 |
+
info = get_stock_info(symbol)
|
| 73 |
+
if info:
|
| 74 |
+
active_data.append({
|
| 75 |
+
'Company': info['name'],
|
| 76 |
+
'Symbol': symbol,
|
| 77 |
+
'Volume': info['volume']
|
| 78 |
+
})
|
| 79 |
+
|
| 80 |
+
# Sort by volume
|
| 81 |
+
active_data = sorted(active_data, key=lambda x: x['Volume'], reverse=True)[:3]
|
| 82 |
+
st.dataframe(pd.DataFrame(active_data))
|
| 83 |
+
|
| 84 |
+
# Sector Performance Heat Map
|
| 85 |
+
st.subheader(f"{selected_sector} Performance Heat Map")
|
| 86 |
+
heat_map_data = []
|
| 87 |
+
for symbol in sectors[selected_sector]:
|
| 88 |
+
data = fetch_stock_data(symbol, period='1d')
|
| 89 |
+
info = get_stock_info(symbol)
|
| 90 |
+
if data is not None and info:
|
| 91 |
+
change = ((data['Close'][-1] - data['Open'][0]) / data['Open'][0]) * 100
|
| 92 |
+
heat_map_data.append({
|
| 93 |
+
'Company': info['name'],
|
| 94 |
+
'Symbol': symbol,
|
| 95 |
+
'Change%': change,
|
| 96 |
+
'Market Cap': info['market_cap'],
|
| 97 |
+
'Volume': info['volume']
|
| 98 |
+
})
|
| 99 |
+
|
| 100 |
+
if heat_map_data:
|
| 101 |
+
fig = go.Figure(data=[go.Treemap(
|
| 102 |
+
labels=[f"{d['Company']}<br>{d['Symbol']}" for d in heat_map_data],
|
| 103 |
+
parents=[''] * len(heat_map_data),
|
| 104 |
+
values=[d['Market Cap'] for d in heat_map_data],
|
| 105 |
+
textinfo="label+value+percent",
|
| 106 |
+
marker=dict(
|
| 107 |
+
colors=[d['Change%'] for d in heat_map_data],
|
| 108 |
+
colorscale='RdYlGn',
|
| 109 |
+
showscale=True
|
| 110 |
+
),
|
| 111 |
+
hovertemplate="""
|
| 112 |
+
Company: %{label}<br>
|
| 113 |
+
Change: %{color:.2f}%<br>
|
| 114 |
+
Market Cap: ₹%{value:,.0f}<br>
|
| 115 |
+
<extra></extra>
|
| 116 |
+
"""
|
| 117 |
+
)])
|
| 118 |
+
|
| 119 |
+
fig.update_layout(title=f"{selected_sector} Companies Heat Map")
|
| 120 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 121 |
+
|
| 122 |
+
# Detailed Sector Analysis
|
| 123 |
+
st.subheader(f"{selected_sector} Companies")
|
| 124 |
+
detailed_data = []
|
| 125 |
+
for symbol in sectors[selected_sector]:
|
| 126 |
+
info = get_stock_info(symbol)
|
| 127 |
+
if info:
|
| 128 |
+
detailed_data.append({
|
| 129 |
+
'Company': info['name'],
|
| 130 |
+
'Symbol': symbol,
|
| 131 |
+
'Market Cap (Cr)': info['market_cap'] / 10000000, # Convert to Crores
|
| 132 |
+
'P/E Ratio': info['pe_ratio'],
|
| 133 |
+
'Volume': info['volume'],
|
| 134 |
+
'Recommendation': info['recommendation'],
|
| 135 |
+
'Target Price': info['target_price']
|
| 136 |
+
})
|
| 137 |
+
|
| 138 |
+
if detailed_data:
|
| 139 |
+
st.dataframe(pd.DataFrame(detailed_data))
|
pages/predictions.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
import numpy as np
|
| 4 |
+
from datetime import datetime, timedelta
|
| 5 |
+
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
| 6 |
+
from utils.quantum_algorithms import QuantumInspiredOptimizer
|
| 7 |
+
|
| 8 |
+
st.title("Market Predictions")
|
| 9 |
+
|
| 10 |
+
# Initialize quantum optimizer
|
| 11 |
+
quantum_optimizer = QuantumInspiredOptimizer()
|
| 12 |
+
|
| 13 |
+
# Stock selection
|
| 14 |
+
symbol = st.selectbox("Select Stock", load_nifty50_symbols())
|
| 15 |
+
prediction_days = st.slider("Prediction Window (days)", 5, 30, 7)
|
| 16 |
+
|
| 17 |
+
# Fetch data
|
| 18 |
+
data = fetch_stock_data(symbol, period='1y')
|
| 19 |
+
|
| 20 |
+
if data is not None:
|
| 21 |
+
prices = data['Close'].values
|
| 22 |
+
|
| 23 |
+
# Calculate predictions
|
| 24 |
+
predictions = quantum_optimizer.quantum_trend_prediction(prices)
|
| 25 |
+
|
| 26 |
+
# Create future dates for predictions
|
| 27 |
+
last_date = data.index[-1]
|
| 28 |
+
future_dates = [last_date + timedelta(days=x) for x in range(1, prediction_days + 1)]
|
| 29 |
+
|
| 30 |
+
# Calculate confidence intervals (simple example)
|
| 31 |
+
confidence_high = predictions * 1.02
|
| 32 |
+
confidence_low = predictions * 0.98
|
| 33 |
+
|
| 34 |
+
# Plotting
|
| 35 |
+
fig = go.Figure()
|
| 36 |
+
|
| 37 |
+
# Historical prices
|
| 38 |
+
fig.add_trace(go.Scatter(
|
| 39 |
+
x=data.index,
|
| 40 |
+
y=data['Close'],
|
| 41 |
+
name='Historical Price',
|
| 42 |
+
line=dict(color='#00B894')
|
| 43 |
+
))
|
| 44 |
+
|
| 45 |
+
# Predictions
|
| 46 |
+
fig.add_trace(go.Scatter(
|
| 47 |
+
x=future_dates,
|
| 48 |
+
y=predictions[-prediction_days:],
|
| 49 |
+
name='Predicted Price',
|
| 50 |
+
line=dict(color='#FFA500', dash='dash')
|
| 51 |
+
))
|
| 52 |
+
|
| 53 |
+
# Confidence interval
|
| 54 |
+
fig.add_trace(go.Scatter(
|
| 55 |
+
x=future_dates,
|
| 56 |
+
y=confidence_high[-prediction_days:],
|
| 57 |
+
fill=None,
|
| 58 |
+
mode='lines',
|
| 59 |
+
line_color='rgba(255, 165, 0, 0)',
|
| 60 |
+
showlegend=False
|
| 61 |
+
))
|
| 62 |
+
|
| 63 |
+
fig.add_trace(go.Scatter(
|
| 64 |
+
x=future_dates,
|
| 65 |
+
y=confidence_low[-prediction_days:],
|
| 66 |
+
fill='tonexty',
|
| 67 |
+
mode='lines',
|
| 68 |
+
line_color='rgba(255, 165, 0, 0)',
|
| 69 |
+
name='Confidence Interval'
|
| 70 |
+
))
|
| 71 |
+
|
| 72 |
+
fig.update_layout(
|
| 73 |
+
title=f"Price Prediction for {symbol}",
|
| 74 |
+
xaxis_title="Date",
|
| 75 |
+
yaxis_title="Price",
|
| 76 |
+
height=600
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 80 |
+
|
| 81 |
+
# Prediction metrics
|
| 82 |
+
col1, col2, col3 = st.columns(3)
|
| 83 |
+
|
| 84 |
+
with col1:
|
| 85 |
+
predicted_change = (predictions[-1] - prices[-1]) / prices[-1] * 100
|
| 86 |
+
st.metric(
|
| 87 |
+
"Predicted Change",
|
| 88 |
+
f"{predicted_change:.2f}%",
|
| 89 |
+
delta=f"{predicted_change:.2f}%"
|
| 90 |
+
)
|
| 91 |
+
|
| 92 |
+
with col2:
|
| 93 |
+
confidence_range = (confidence_high[-1] - confidence_low[-1]) / predictions[-1] * 100
|
| 94 |
+
st.metric(
|
| 95 |
+
"Confidence Range",
|
| 96 |
+
f"±{confidence_range:.2f}%"
|
| 97 |
+
)
|
| 98 |
+
|
| 99 |
+
with col3:
|
| 100 |
+
trend = "Bullish" if predicted_change > 0 else "Bearish"
|
| 101 |
+
st.metric(
|
| 102 |
+
"Predicted Trend",
|
| 103 |
+
trend,
|
| 104 |
+
delta="↑" if predicted_change > 0 else "↓"
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
# Additional analysis
|
| 108 |
+
st.subheader("Technical Factors")
|
| 109 |
+
|
| 110 |
+
# Calculate some basic technical indicators for the prediction
|
| 111 |
+
momentum = np.gradient(predictions[-30:])
|
| 112 |
+
volatility = np.std(prices[-30:]) / np.mean(prices[-30:]) * 100
|
| 113 |
+
|
| 114 |
+
factors_col1, factors_col2 = st.columns(2)
|
| 115 |
+
|
| 116 |
+
with factors_col1:
|
| 117 |
+
st.markdown("""
|
| 118 |
+
### Momentum Analysis
|
| 119 |
+
- Short-term trend: **{}**
|
| 120 |
+
- Momentum strength: **{:.2f}**
|
| 121 |
+
""".format(
|
| 122 |
+
"Positive" if momentum[-1] > 0 else "Negative",
|
| 123 |
+
abs(momentum[-1])
|
| 124 |
+
))
|
| 125 |
+
|
| 126 |
+
with factors_col2:
|
| 127 |
+
st.markdown("""
|
| 128 |
+
### Risk Metrics
|
| 129 |
+
- Historical volatility: **{:.2f}%**
|
| 130 |
+
- Prediction confidence: **{:.2f}%**
|
| 131 |
+
""".format(
|
| 132 |
+
volatility,
|
| 133 |
+
100 - confidence_range
|
| 134 |
+
))
|
| 135 |
+
|
| 136 |
+
# Warning/Disclaimer
|
| 137 |
+
st.warning("""
|
| 138 |
+
**Disclaimer**: These predictions are based on quantum-inspired algorithms and historical data analysis.
|
| 139 |
+
Market behavior is inherently unpredictable and these projections should not be used as the sole basis
|
| 140 |
+
for investment decisions. Always conduct thorough research and consider multiple factors before making
|
| 141 |
+
investment choices.
|
| 142 |
+
""")
|
| 143 |
+
|
| 144 |
+
else:
|
| 145 |
+
st.error("Unable to fetch data. Please try again later.")
|
pages/quantum_patterns.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
import numpy as np
|
| 4 |
+
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
| 5 |
+
from utils.quantum_algorithms import QuantumInspiredOptimizer
|
| 6 |
+
|
| 7 |
+
st.title("Quantum Pattern Analysis")
|
| 8 |
+
|
| 9 |
+
# Initialize quantum optimizer
|
| 10 |
+
quantum_optimizer = QuantumInspiredOptimizer()
|
| 11 |
+
|
| 12 |
+
# Stock selection
|
| 13 |
+
symbol = st.selectbox("Select Stock", load_nifty50_symbols())
|
| 14 |
+
timeframe = st.selectbox("Select Timeframe", ["1mo", "3mo", "6mo", "1y"])
|
| 15 |
+
|
| 16 |
+
# Fetch data
|
| 17 |
+
data = fetch_stock_data(symbol, period=timeframe)
|
| 18 |
+
|
| 19 |
+
if data is not None:
|
| 20 |
+
# Create tabs for different quantum analyses
|
| 21 |
+
tab1, tab2, tab3 = st.tabs([
|
| 22 |
+
"Quantum Pattern Detection",
|
| 23 |
+
"Quantum Momentum",
|
| 24 |
+
"Quantum State Analysis"
|
| 25 |
+
])
|
| 26 |
+
|
| 27 |
+
with tab1:
|
| 28 |
+
st.subheader("Quantum-Inspired Pattern Detection")
|
| 29 |
+
|
| 30 |
+
# Calculate quantum patterns
|
| 31 |
+
prices = data['Close'].values
|
| 32 |
+
pattern_strength = quantum_optimizer.quantum_pattern_detection(prices)
|
| 33 |
+
|
| 34 |
+
fig = go.Figure()
|
| 35 |
+
|
| 36 |
+
# Price plot
|
| 37 |
+
fig.add_trace(go.Scatter(
|
| 38 |
+
x=data.index,
|
| 39 |
+
y=data['Close'],
|
| 40 |
+
name='Price',
|
| 41 |
+
line=dict(color='#00B894')
|
| 42 |
+
))
|
| 43 |
+
|
| 44 |
+
# Pattern strength
|
| 45 |
+
fig.add_trace(go.Scatter(
|
| 46 |
+
x=data.index,
|
| 47 |
+
y=pattern_strength[:len(data)],
|
| 48 |
+
name='Pattern Strength',
|
| 49 |
+
line=dict(color='#FFA500'),
|
| 50 |
+
yaxis='y2'
|
| 51 |
+
))
|
| 52 |
+
|
| 53 |
+
fig.update_layout(
|
| 54 |
+
title="Quantum Pattern Detection",
|
| 55 |
+
yaxis=dict(title="Price"),
|
| 56 |
+
yaxis2=dict(title="Pattern Strength", overlaying='y', side='right'),
|
| 57 |
+
height=600
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 61 |
+
|
| 62 |
+
with tab2:
|
| 63 |
+
st.subheader("Quantum Momentum Indicator")
|
| 64 |
+
|
| 65 |
+
# Calculate quantum momentum
|
| 66 |
+
momentum = quantum_optimizer.quantum_momentum_indicator(prices)
|
| 67 |
+
|
| 68 |
+
fig = go.Figure()
|
| 69 |
+
|
| 70 |
+
# Price plot
|
| 71 |
+
fig.add_trace(go.Scatter(
|
| 72 |
+
x=data.index,
|
| 73 |
+
y=data['Close'],
|
| 74 |
+
name='Price',
|
| 75 |
+
line=dict(color='#00B894')
|
| 76 |
+
))
|
| 77 |
+
|
| 78 |
+
# Momentum indicator
|
| 79 |
+
fig.add_trace(go.Scatter(
|
| 80 |
+
x=data.index,
|
| 81 |
+
y=momentum,
|
| 82 |
+
name='Quantum Momentum',
|
| 83 |
+
line=dict(color='#FF4757'),
|
| 84 |
+
yaxis='y2'
|
| 85 |
+
))
|
| 86 |
+
|
| 87 |
+
fig.update_layout(
|
| 88 |
+
title="Quantum Momentum Analysis",
|
| 89 |
+
yaxis=dict(title="Price"),
|
| 90 |
+
yaxis2=dict(title="Momentum", overlaying='y', side='right'),
|
| 91 |
+
height=600
|
| 92 |
+
)
|
| 93 |
+
|
| 94 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 95 |
+
|
| 96 |
+
with tab3:
|
| 97 |
+
st.subheader("Quantum State Analysis")
|
| 98 |
+
|
| 99 |
+
# Calculate quantum states
|
| 100 |
+
encoded_data = quantum_optimizer.quantum_inspired_encoding(prices)
|
| 101 |
+
amplitudes = np.abs(encoded_data)
|
| 102 |
+
phases = np.angle(encoded_data)
|
| 103 |
+
|
| 104 |
+
# Create subplots
|
| 105 |
+
fig = go.Figure()
|
| 106 |
+
|
| 107 |
+
# Amplitude plot
|
| 108 |
+
fig.add_trace(go.Scatter(
|
| 109 |
+
x=data.index,
|
| 110 |
+
y=amplitudes.flatten(),
|
| 111 |
+
name='Amplitude',
|
| 112 |
+
line=dict(color='#00B894')
|
| 113 |
+
))
|
| 114 |
+
|
| 115 |
+
# Phase plot
|
| 116 |
+
fig.add_trace(go.Scatter(
|
| 117 |
+
x=data.index,
|
| 118 |
+
y=phases.flatten(),
|
| 119 |
+
name='Phase',
|
| 120 |
+
line=dict(color='#FFA500'),
|
| 121 |
+
yaxis='y2'
|
| 122 |
+
))
|
| 123 |
+
|
| 124 |
+
fig.update_layout(
|
| 125 |
+
title="Quantum State Representation",
|
| 126 |
+
yaxis=dict(title="Amplitude"),
|
| 127 |
+
yaxis2=dict(title="Phase", overlaying='y', side='right'),
|
| 128 |
+
height=600
|
| 129 |
+
)
|
| 130 |
+
|
| 131 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 132 |
+
|
| 133 |
+
# Display quantum state statistics
|
| 134 |
+
col1, col2, col3 = st.columns(3)
|
| 135 |
+
|
| 136 |
+
with col1:
|
| 137 |
+
st.metric(
|
| 138 |
+
"Average Amplitude",
|
| 139 |
+
f"{np.mean(amplitudes):.4f}"
|
| 140 |
+
)
|
| 141 |
+
|
| 142 |
+
with col2:
|
| 143 |
+
st.metric(
|
| 144 |
+
"Phase Coherence",
|
| 145 |
+
f"{np.std(phases):.4f}"
|
| 146 |
+
)
|
| 147 |
+
|
| 148 |
+
with col3:
|
| 149 |
+
st.metric(
|
| 150 |
+
"Quantum Entropy",
|
| 151 |
+
f"{-np.sum(amplitudes**2 * np.log(amplitudes**2 + 1e-10)):.4f}"
|
| 152 |
+
)
|
| 153 |
+
|
| 154 |
+
else:
|
| 155 |
+
st.error("Unable to fetch data. Please try again later.")
|
pages/sentiment_heatmap.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
from utils.data_loader import load_nifty50_symbols, fetch_stock_data, get_stock_info
|
| 6 |
+
from utils.market_analysis import MarketAnalyzer
|
| 7 |
+
import asyncio
|
| 8 |
+
import json
|
| 9 |
+
|
| 10 |
+
st.title("Market Sentiment Heatmap")
|
| 11 |
+
|
| 12 |
+
# Initialize market analyzer
|
| 13 |
+
market_analyzer = MarketAnalyzer()
|
| 14 |
+
|
| 15 |
+
# Create tabs for different views
|
| 16 |
+
tab1, tab2 = st.tabs(["Sector-wise Sentiment", "Stock-wise Sentiment"])
|
| 17 |
+
|
| 18 |
+
with tab1:
|
| 19 |
+
st.subheader("Sector Sentiment Analysis")
|
| 20 |
+
|
| 21 |
+
# Define sectors and their stocks
|
| 22 |
+
sectors = {
|
| 23 |
+
"IT": ["TCS.NS", "INFY.NS", "HCLTECH.NS", "TECHM.NS", "WIPRO.NS"],
|
| 24 |
+
"Banking & Finance": ["HDFCBANK.NS", "ICICIBANK.NS", "SBIN.NS", "AXISBANK.NS", "KOTAKBANK.NS"],
|
| 25 |
+
"Energy & Oil": ["RELIANCE.NS", "ONGC.NS", "POWERGRID.NS", "NTPC.NS", "BPCL.NS"],
|
| 26 |
+
"Automobile": ["TATAMOTORS.NS", "M&M.NS", "MARUTI.NS", "HEROMOTOCO.NS"],
|
| 27 |
+
"Consumer Goods": ["HINDUNILVR.NS", "ITC.NS", "NESTLEIND.NS", "BRITANNIA.NS"],
|
| 28 |
+
"Metals & Mining": ["TATASTEEL.NS", "HINDALCO.NS", "JSWSTEEL.NS", "COALINDIA.NS"],
|
| 29 |
+
"Pharmaceuticals": ["SUNPHARMA.NS", "DRREDDY.NS", "CIPLA.NS", "DIVISLAB.NS"]
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
# Calculate sector sentiment
|
| 33 |
+
sector_data = {}
|
| 34 |
+
|
| 35 |
+
with st.spinner("Analyzing sector sentiment..."):
|
| 36 |
+
for sector, symbols in sectors.items():
|
| 37 |
+
valid_changes = []
|
| 38 |
+
for symbol in symbols:
|
| 39 |
+
try:
|
| 40 |
+
data = fetch_stock_data(symbol, period='1d')
|
| 41 |
+
if data is not None and not data.empty:
|
| 42 |
+
change = ((data['Close'].iloc[-1] - data['Open'].iloc[0]) / data['Open'].iloc[0]) * 100
|
| 43 |
+
valid_changes.append(change)
|
| 44 |
+
except Exception as e:
|
| 45 |
+
continue
|
| 46 |
+
|
| 47 |
+
if valid_changes:
|
| 48 |
+
sector_data[sector] = np.mean(valid_changes)
|
| 49 |
+
|
| 50 |
+
if sector_data:
|
| 51 |
+
sectors = list(sector_data.keys())
|
| 52 |
+
values = list(sector_data.values())
|
| 53 |
+
|
| 54 |
+
fig = go.Figure(data=[go.Treemap(
|
| 55 |
+
labels=sectors,
|
| 56 |
+
parents=[''] * len(sectors),
|
| 57 |
+
values=[abs(v) for v in values],
|
| 58 |
+
textinfo="label+value+percent",
|
| 59 |
+
marker=dict(
|
| 60 |
+
colors=values,
|
| 61 |
+
colorscale='RdYlGn',
|
| 62 |
+
showscale=True,
|
| 63 |
+
colorbar=dict(title="Change %")
|
| 64 |
+
),
|
| 65 |
+
hovertemplate="""
|
| 66 |
+
Sector: %{label}<br>
|
| 67 |
+
Average Change: %{color:.2f}%<br>
|
| 68 |
+
<extra></extra>
|
| 69 |
+
"""
|
| 70 |
+
)])
|
| 71 |
+
|
| 72 |
+
fig.update_layout(
|
| 73 |
+
title="Sector-wise Market Sentiment",
|
| 74 |
+
width=800,
|
| 75 |
+
height=600
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 79 |
+
|
| 80 |
+
# Display sector statistics
|
| 81 |
+
st.subheader("Sector Performance")
|
| 82 |
+
sector_stats = pd.DataFrame({
|
| 83 |
+
'Sector': sectors,
|
| 84 |
+
'Average Change %': values
|
| 85 |
+
}).sort_values('Average Change %', ascending=False)
|
| 86 |
+
|
| 87 |
+
st.dataframe(sector_stats)
|
| 88 |
+
else:
|
| 89 |
+
st.warning("No sector data available. Please try again later.")
|
| 90 |
+
|
| 91 |
+
with tab2:
|
| 92 |
+
st.subheader("Stock-wise Sentiment")
|
| 93 |
+
|
| 94 |
+
# Select sector for stock analysis
|
| 95 |
+
selected_sector = st.selectbox("Select Sector", list(sectors.keys()))
|
| 96 |
+
|
| 97 |
+
if selected_sector:
|
| 98 |
+
symbols = sectors[selected_sector]
|
| 99 |
+
stock_data = []
|
| 100 |
+
|
| 101 |
+
with st.spinner(f"Analyzing sentiment for {selected_sector} sector stocks..."):
|
| 102 |
+
for symbol in symbols:
|
| 103 |
+
try:
|
| 104 |
+
# Get basic stock info
|
| 105 |
+
info = get_stock_info(symbol)
|
| 106 |
+
if info is None:
|
| 107 |
+
st.warning(f"Could not fetch info for {symbol}")
|
| 108 |
+
continue
|
| 109 |
+
|
| 110 |
+
# Fetch stock data
|
| 111 |
+
data = fetch_stock_data(symbol, period='5d')
|
| 112 |
+
if data is None or data.empty:
|
| 113 |
+
st.warning(f"Could not fetch data for {symbol}")
|
| 114 |
+
continue
|
| 115 |
+
|
| 116 |
+
# Get AI sentiment
|
| 117 |
+
sentiment_response = await market_analyzer.get_ai_sentiment(symbol, data)
|
| 118 |
+
|
| 119 |
+
if sentiment_response.startswith("Error"):
|
| 120 |
+
st.error(f"Sentiment analysis error for {symbol}: {sentiment_response}")
|
| 121 |
+
continue
|
| 122 |
+
|
| 123 |
+
try:
|
| 124 |
+
# Parse sentiment response
|
| 125 |
+
sentiment_dict = json.loads(sentiment_response.replace("'", '"'))
|
| 126 |
+
|
| 127 |
+
sentiment_score = {
|
| 128 |
+
'bullish': 1,
|
| 129 |
+
'neutral': 0,
|
| 130 |
+
'bearish': -1
|
| 131 |
+
}.get(str(sentiment_dict.get('sentiment', '')).lower(), 0)
|
| 132 |
+
|
| 133 |
+
confidence = float(sentiment_dict.get('confidence', 0.5))
|
| 134 |
+
final_score = sentiment_score * confidence
|
| 135 |
+
|
| 136 |
+
stock_data.append({
|
| 137 |
+
'name': info['name'],
|
| 138 |
+
'symbol': symbol,
|
| 139 |
+
'sentiment_score': final_score,
|
| 140 |
+
'market_cap': info['market_cap'],
|
| 141 |
+
'sentiment': sentiment_dict.get('sentiment', 'N/A'),
|
| 142 |
+
'confidence': confidence,
|
| 143 |
+
'recommendation': sentiment_dict.get('recommendation', 'N/A'),
|
| 144 |
+
'risk_level': sentiment_dict.get('risk_level', 'N/A'),
|
| 145 |
+
'key_factors': sentiment_dict.get('key_factors', [])
|
| 146 |
+
})
|
| 147 |
+
|
| 148 |
+
except json.JSONDecodeError as e:
|
| 149 |
+
st.error(f"Error parsing sentiment data for {symbol}: {str(e)}")
|
| 150 |
+
continue
|
| 151 |
+
except Exception as e:
|
| 152 |
+
st.error(f"Unexpected error processing {symbol}: {str(e)}")
|
| 153 |
+
continue
|
| 154 |
+
|
| 155 |
+
if stock_data:
|
| 156 |
+
# Create heatmap
|
| 157 |
+
fig = go.Figure(data=[go.Treemap(
|
| 158 |
+
labels=[f"{d['name']}<br>({d['symbol']})" for d in stock_data],
|
| 159 |
+
parents=[''] * len(stock_data),
|
| 160 |
+
values=[abs(d['market_cap']) for d in stock_data],
|
| 161 |
+
textinfo="label",
|
| 162 |
+
marker=dict(
|
| 163 |
+
colors=[d['sentiment_score'] for d in stock_data],
|
| 164 |
+
colorscale='RdYlGn',
|
| 165 |
+
showscale=True,
|
| 166 |
+
colorbar=dict(title="Sentiment Score")
|
| 167 |
+
),
|
| 168 |
+
hovertemplate="""
|
| 169 |
+
Company: %{label}<br>
|
| 170 |
+
Sentiment Score: %{color:.2f}<br>
|
| 171 |
+
Market Cap: ₹%{value:,.0f}<br>
|
| 172 |
+
<extra></extra>
|
| 173 |
+
"""
|
| 174 |
+
)])
|
| 175 |
+
|
| 176 |
+
fig.update_layout(
|
| 177 |
+
title=f"{selected_sector} Sector Sentiment Heatmap",
|
| 178 |
+
width=800,
|
| 179 |
+
height=600
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 183 |
+
|
| 184 |
+
# Create summary table
|
| 185 |
+
st.subheader("Sentiment Summary")
|
| 186 |
+
summary_df = pd.DataFrame([{
|
| 187 |
+
'Company': d['name'],
|
| 188 |
+
'Symbol': d['symbol'],
|
| 189 |
+
'Sentiment': d['sentiment'],
|
| 190 |
+
'Confidence': f"{d['confidence']:.2f}",
|
| 191 |
+
'Recommendation': d['recommendation'],
|
| 192 |
+
'Risk Level': d['risk_level']
|
| 193 |
+
} for d in stock_data])
|
| 194 |
+
|
| 195 |
+
st.dataframe(summary_df)
|
| 196 |
+
|
| 197 |
+
# Show detailed insights
|
| 198 |
+
st.subheader("Detailed Analysis")
|
| 199 |
+
for stock in stock_data:
|
| 200 |
+
with st.expander(f"{stock['name']} ({stock['symbol']})"):
|
| 201 |
+
st.markdown(f"""
|
| 202 |
+
**Sentiment:** {stock['sentiment']}
|
| 203 |
+
**Confidence:** {stock['confidence']:.2f}
|
| 204 |
+
**Recommendation:** {stock['recommendation']}
|
| 205 |
+
**Risk Level:** {stock['risk_level']}
|
| 206 |
+
|
| 207 |
+
**Key Factors:**
|
| 208 |
+
""")
|
| 209 |
+
for factor in stock['key_factors']:
|
| 210 |
+
st.markdown(f"- {factor}")
|
| 211 |
+
else:
|
| 212 |
+
st.warning("No sentiment data available. Please try again later.")
|
| 213 |
+
else:
|
| 214 |
+
st.info("Please select a sector to view stock-wise sentiment analysis.")
|
pages/technical_analysis.py
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
from plotly.subplots import make_subplots
|
| 4 |
+
import pandas as pd
|
| 5 |
+
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
| 6 |
+
from utils.technical_indicators import (
|
| 7 |
+
calculate_rsi,
|
| 8 |
+
calculate_macd,
|
| 9 |
+
calculate_bollinger_bands,
|
| 10 |
+
calculate_support_resistance
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
st.title("Technical Analysis")
|
| 14 |
+
|
| 15 |
+
# Stock selection
|
| 16 |
+
symbol = st.selectbox("Select Stock", load_nifty50_symbols())
|
| 17 |
+
timeframe = st.selectbox(
|
| 18 |
+
"Select Timeframe",
|
| 19 |
+
options=["1w", "1mo", "3mo", "6mo", "1y", "3y", "5y"],
|
| 20 |
+
format_func=lambda x: {
|
| 21 |
+
"1w": "1 Week",
|
| 22 |
+
"1mo": "1 Month",
|
| 23 |
+
"3mo": "1 Quarter",
|
| 24 |
+
"6mo": "6 Months",
|
| 25 |
+
"1y": "1 Year",
|
| 26 |
+
"3y": "3 Years",
|
| 27 |
+
"5y": "5 Years"
|
| 28 |
+
}[x]
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
# Fetch data
|
| 32 |
+
data = fetch_stock_data(symbol, period=timeframe)
|
| 33 |
+
|
| 34 |
+
if data is not None:
|
| 35 |
+
# Create tabs for different analysis
|
| 36 |
+
tab1, tab2, tab3 = st.tabs(["Price & Volume", "Technical Indicators", "Support & Resistance"])
|
| 37 |
+
|
| 38 |
+
with tab1:
|
| 39 |
+
# Candlestick chart with volume
|
| 40 |
+
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
|
| 41 |
+
vertical_spacing=0.03,
|
| 42 |
+
row_heights=[0.7, 0.3])
|
| 43 |
+
|
| 44 |
+
# Candlestick
|
| 45 |
+
fig.add_trace(go.Candlestick(
|
| 46 |
+
x=data.index,
|
| 47 |
+
open=data['Open'],
|
| 48 |
+
high=data['High'],
|
| 49 |
+
low=data['Low'],
|
| 50 |
+
close=data['Close'],
|
| 51 |
+
name='OHLC'
|
| 52 |
+
), row=1, col=1)
|
| 53 |
+
|
| 54 |
+
# Volume
|
| 55 |
+
fig.add_trace(go.Bar(
|
| 56 |
+
x=data.index,
|
| 57 |
+
y=data['Volume'],
|
| 58 |
+
name='Volume',
|
| 59 |
+
marker_color='rgba(0,184,148,0.3)'
|
| 60 |
+
), row=2, col=1)
|
| 61 |
+
|
| 62 |
+
fig.update_layout(
|
| 63 |
+
title=f"{symbol} Price and Volume",
|
| 64 |
+
yaxis_title="Price",
|
| 65 |
+
yaxis2_title="Volume",
|
| 66 |
+
xaxis_rangeslider_visible=False,
|
| 67 |
+
height=800
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 71 |
+
|
| 72 |
+
with tab2:
|
| 73 |
+
# Technical indicators
|
| 74 |
+
col1, col2 = st.columns(2)
|
| 75 |
+
|
| 76 |
+
with col1:
|
| 77 |
+
# RSI
|
| 78 |
+
rsi = calculate_rsi(data)
|
| 79 |
+
fig_rsi = go.Figure()
|
| 80 |
+
fig_rsi.add_trace(go.Scatter(
|
| 81 |
+
x=data.index,
|
| 82 |
+
y=rsi,
|
| 83 |
+
name='RSI',
|
| 84 |
+
line=dict(color='#00B894')
|
| 85 |
+
))
|
| 86 |
+
fig_rsi.add_hline(y=70, line_dash="dash", line_color="red")
|
| 87 |
+
fig_rsi.add_hline(y=30, line_dash="dash", line_color="green")
|
| 88 |
+
fig_rsi.update_layout(title="RSI (14)", height=400)
|
| 89 |
+
st.plotly_chart(fig_rsi, use_container_width=True)
|
| 90 |
+
|
| 91 |
+
with col2:
|
| 92 |
+
# MACD
|
| 93 |
+
macd, signal = calculate_macd(data)
|
| 94 |
+
fig_macd = go.Figure()
|
| 95 |
+
fig_macd.add_trace(go.Scatter(
|
| 96 |
+
x=data.index,
|
| 97 |
+
y=macd,
|
| 98 |
+
name='MACD',
|
| 99 |
+
line=dict(color='#00B894')
|
| 100 |
+
))
|
| 101 |
+
fig_macd.add_trace(go.Scatter(
|
| 102 |
+
x=data.index,
|
| 103 |
+
y=signal,
|
| 104 |
+
name='Signal',
|
| 105 |
+
line=dict(color='#FFA500')
|
| 106 |
+
))
|
| 107 |
+
fig_macd.update_layout(title="MACD", height=400)
|
| 108 |
+
st.plotly_chart(fig_macd, use_container_width=True)
|
| 109 |
+
|
| 110 |
+
# Bollinger Bands
|
| 111 |
+
upper_band, middle_band, lower_band = calculate_bollinger_bands(data)
|
| 112 |
+
fig_bb = go.Figure()
|
| 113 |
+
fig_bb.add_trace(go.Scatter(
|
| 114 |
+
x=data.index,
|
| 115 |
+
y=upper_band,
|
| 116 |
+
name='Upper Band',
|
| 117 |
+
line=dict(color='gray', dash='dash')
|
| 118 |
+
))
|
| 119 |
+
fig_bb.add_trace(go.Scatter(
|
| 120 |
+
x=data.index,
|
| 121 |
+
y=middle_band,
|
| 122 |
+
name='Middle Band',
|
| 123 |
+
line=dict(color='blue')
|
| 124 |
+
))
|
| 125 |
+
fig_bb.add_trace(go.Scatter(
|
| 126 |
+
x=data.index,
|
| 127 |
+
y=lower_band,
|
| 128 |
+
name='Lower Band',
|
| 129 |
+
line=dict(color='gray', dash='dash')
|
| 130 |
+
))
|
| 131 |
+
fig_bb.add_trace(go.Scatter(
|
| 132 |
+
x=data.index,
|
| 133 |
+
y=data['Close'],
|
| 134 |
+
name='Close Price',
|
| 135 |
+
line=dict(color='#00B894')
|
| 136 |
+
))
|
| 137 |
+
fig_bb.update_layout(title="Bollinger Bands", height=500)
|
| 138 |
+
st.plotly_chart(fig_bb, use_container_width=True)
|
| 139 |
+
|
| 140 |
+
with tab3:
|
| 141 |
+
# Support and Resistance
|
| 142 |
+
support, resistance = calculate_support_resistance(data)
|
| 143 |
+
fig_sr = go.Figure()
|
| 144 |
+
|
| 145 |
+
fig_sr.add_trace(go.Scatter(
|
| 146 |
+
x=data.index,
|
| 147 |
+
y=data['Close'],
|
| 148 |
+
name='Price',
|
| 149 |
+
line=dict(color='#00B894')
|
| 150 |
+
))
|
| 151 |
+
fig_sr.add_trace(go.Scatter(
|
| 152 |
+
x=data.index,
|
| 153 |
+
y=support,
|
| 154 |
+
name='Support',
|
| 155 |
+
line=dict(color='green', dash='dash')
|
| 156 |
+
))
|
| 157 |
+
fig_sr.add_trace(go.Scatter(
|
| 158 |
+
x=data.index,
|
| 159 |
+
y=resistance,
|
| 160 |
+
name='Resistance',
|
| 161 |
+
line=dict(color='red', dash='dash')
|
| 162 |
+
))
|
| 163 |
+
|
| 164 |
+
fig_sr.update_layout(
|
| 165 |
+
title="Support and Resistance Levels",
|
| 166 |
+
height=600
|
| 167 |
+
)
|
| 168 |
+
st.plotly_chart(fig_sr, use_container_width=True)
|
| 169 |
+
|
| 170 |
+
else:
|
| 171 |
+
st.error("Unable to fetch data. Please try again later.")
|
predictions.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
-
import
|
| 3 |
import numpy as np
|
| 4 |
from datetime import datetime, timedelta
|
| 5 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
|
@@ -32,23 +32,51 @@ if data is not None:
|
|
| 32 |
confidence_low = predictions * 0.98
|
| 33 |
|
| 34 |
# Plotting
|
| 35 |
-
fig
|
| 36 |
|
| 37 |
# Historical prices
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
|
| 40 |
# Predictions
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
# Confidence interval
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
-
st.
|
| 52 |
|
| 53 |
# Prediction metrics
|
| 54 |
col1, col2, col3 = st.columns(3)
|
|
@@ -111,8 +139,7 @@ if data is not None:
|
|
| 111 |
Market behavior is inherently unpredictable and these projections should not be used as the sole basis
|
| 112 |
for investment decisions. Always conduct thorough research and consider multiple factors before making
|
| 113 |
investment choices.
|
| 114 |
-
""
|
| 115 |
-
)
|
| 116 |
|
| 117 |
else:
|
| 118 |
st.error("Unable to fetch data. Please try again later.")
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
import numpy as np
|
| 4 |
from datetime import datetime, timedelta
|
| 5 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
|
|
|
| 32 |
confidence_low = predictions * 0.98
|
| 33 |
|
| 34 |
# Plotting
|
| 35 |
+
fig = go.Figure()
|
| 36 |
|
| 37 |
# Historical prices
|
| 38 |
+
fig.add_trace(go.Scatter(
|
| 39 |
+
x=data.index,
|
| 40 |
+
y=data['Close'],
|
| 41 |
+
name='Historical Price',
|
| 42 |
+
line=dict(color='#00B894')
|
| 43 |
+
))
|
| 44 |
|
| 45 |
# Predictions
|
| 46 |
+
fig.add_trace(go.Scatter(
|
| 47 |
+
x=future_dates,
|
| 48 |
+
y=predictions[-prediction_days:],
|
| 49 |
+
name='Predicted Price',
|
| 50 |
+
line=dict(color='#FFA500', dash='dash')
|
| 51 |
+
))
|
| 52 |
|
| 53 |
# Confidence interval
|
| 54 |
+
fig.add_trace(go.Scatter(
|
| 55 |
+
x=future_dates,
|
| 56 |
+
y=confidence_high[-prediction_days:],
|
| 57 |
+
fill=None,
|
| 58 |
+
mode='lines',
|
| 59 |
+
line_color='rgba(255, 165, 0, 0)',
|
| 60 |
+
showlegend=False
|
| 61 |
+
))
|
| 62 |
+
|
| 63 |
+
fig.add_trace(go.Scatter(
|
| 64 |
+
x=future_dates,
|
| 65 |
+
y=confidence_low[-prediction_days:],
|
| 66 |
+
fill='tonexty',
|
| 67 |
+
mode='lines',
|
| 68 |
+
line_color='rgba(255, 165, 0, 0)',
|
| 69 |
+
name='Confidence Interval'
|
| 70 |
+
))
|
| 71 |
+
|
| 72 |
+
fig.update_layout(
|
| 73 |
+
title=f"Price Prediction for {symbol}",
|
| 74 |
+
xaxis_title="Date",
|
| 75 |
+
yaxis_title="Price",
|
| 76 |
+
height=600
|
| 77 |
+
)
|
| 78 |
|
| 79 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 80 |
|
| 81 |
# Prediction metrics
|
| 82 |
col1, col2, col3 = st.columns(3)
|
|
|
|
| 139 |
Market behavior is inherently unpredictable and these projections should not be used as the sole basis
|
| 140 |
for investment decisions. Always conduct thorough research and consider multiple factors before making
|
| 141 |
investment choices.
|
| 142 |
+
""")
|
|
|
|
| 143 |
|
| 144 |
else:
|
| 145 |
st.error("Unable to fetch data. Please try again later.")
|
technical_analysis.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
-
import
|
|
|
|
| 3 |
import pandas as pd
|
| 4 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
| 5 |
from utils.technical_indicators import (
|
|
@@ -35,14 +36,38 @@ if data is not None:
|
|
| 35 |
tab1, tab2, tab3 = st.tabs(["Price & Volume", "Technical Indicators", "Support & Resistance"])
|
| 36 |
|
| 37 |
with tab1:
|
| 38 |
-
#
|
| 39 |
-
fig
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
with tab2:
|
| 48 |
# Technical indicators
|
|
@@ -51,49 +76,96 @@ if data is not None:
|
|
| 51 |
with col1:
|
| 52 |
# RSI
|
| 53 |
rsi = calculate_rsi(data)
|
| 54 |
-
fig_rsi
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
with col2:
|
| 64 |
# MACD
|
| 65 |
macd, signal = calculate_macd(data)
|
| 66 |
-
fig_macd
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
# Bollinger Bands
|
| 75 |
upper_band, middle_band, lower_band = calculate_bollinger_bands(data)
|
| 76 |
-
fig_bb
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
with tab3:
|
| 87 |
# Support and Resistance
|
| 88 |
support, resistance = calculate_support_resistance(data)
|
| 89 |
-
fig_sr
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
else:
|
| 99 |
st.error("Unable to fetch data. Please try again later.")
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
from plotly.subplots import make_subplots
|
| 4 |
import pandas as pd
|
| 5 |
from utils.data_loader import load_nifty50_symbols, fetch_stock_data
|
| 6 |
from utils.technical_indicators import (
|
|
|
|
| 36 |
tab1, tab2, tab3 = st.tabs(["Price & Volume", "Technical Indicators", "Support & Resistance"])
|
| 37 |
|
| 38 |
with tab1:
|
| 39 |
+
# Candlestick chart with volume
|
| 40 |
+
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
|
| 41 |
+
vertical_spacing=0.03,
|
| 42 |
+
row_heights=[0.7, 0.3])
|
| 43 |
+
|
| 44 |
+
# Candlestick
|
| 45 |
+
fig.add_trace(go.Candlestick(
|
| 46 |
+
x=data.index,
|
| 47 |
+
open=data['Open'],
|
| 48 |
+
high=data['High'],
|
| 49 |
+
low=data['Low'],
|
| 50 |
+
close=data['Close'],
|
| 51 |
+
name='OHLC'
|
| 52 |
+
), row=1, col=1)
|
| 53 |
+
|
| 54 |
+
# Volume
|
| 55 |
+
fig.add_trace(go.Bar(
|
| 56 |
+
x=data.index,
|
| 57 |
+
y=data['Volume'],
|
| 58 |
+
name='Volume',
|
| 59 |
+
marker_color='rgba(0,184,148,0.3)'
|
| 60 |
+
), row=2, col=1)
|
| 61 |
+
|
| 62 |
+
fig.update_layout(
|
| 63 |
+
title=f"{symbol} Price and Volume",
|
| 64 |
+
yaxis_title="Price",
|
| 65 |
+
yaxis2_title="Volume",
|
| 66 |
+
xaxis_rangeslider_visible=False,
|
| 67 |
+
height=800
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 71 |
|
| 72 |
with tab2:
|
| 73 |
# Technical indicators
|
|
|
|
| 76 |
with col1:
|
| 77 |
# RSI
|
| 78 |
rsi = calculate_rsi(data)
|
| 79 |
+
fig_rsi = go.Figure()
|
| 80 |
+
fig_rsi.add_trace(go.Scatter(
|
| 81 |
+
x=data.index,
|
| 82 |
+
y=rsi,
|
| 83 |
+
name='RSI',
|
| 84 |
+
line=dict(color='#00B894')
|
| 85 |
+
))
|
| 86 |
+
fig_rsi.add_hline(y=70, line_dash="dash", line_color="red")
|
| 87 |
+
fig_rsi.add_hline(y=30, line_dash="dash", line_color="green")
|
| 88 |
+
fig_rsi.update_layout(title="RSI (14)", height=400)
|
| 89 |
+
st.plotly_chart(fig_rsi, use_container_width=True)
|
| 90 |
|
| 91 |
with col2:
|
| 92 |
# MACD
|
| 93 |
macd, signal = calculate_macd(data)
|
| 94 |
+
fig_macd = go.Figure()
|
| 95 |
+
fig_macd.add_trace(go.Scatter(
|
| 96 |
+
x=data.index,
|
| 97 |
+
y=macd,
|
| 98 |
+
name='MACD',
|
| 99 |
+
line=dict(color='#00B894')
|
| 100 |
+
))
|
| 101 |
+
fig_macd.add_trace(go.Scatter(
|
| 102 |
+
x=data.index,
|
| 103 |
+
y=signal,
|
| 104 |
+
name='Signal',
|
| 105 |
+
line=dict(color='#FFA500')
|
| 106 |
+
))
|
| 107 |
+
fig_macd.update_layout(title="MACD", height=400)
|
| 108 |
+
st.plotly_chart(fig_macd, use_container_width=True)
|
| 109 |
|
| 110 |
# Bollinger Bands
|
| 111 |
upper_band, middle_band, lower_band = calculate_bollinger_bands(data)
|
| 112 |
+
fig_bb = go.Figure()
|
| 113 |
+
fig_bb.add_trace(go.Scatter(
|
| 114 |
+
x=data.index,
|
| 115 |
+
y=upper_band,
|
| 116 |
+
name='Upper Band',
|
| 117 |
+
line=dict(color='gray', dash='dash')
|
| 118 |
+
))
|
| 119 |
+
fig_bb.add_trace(go.Scatter(
|
| 120 |
+
x=data.index,
|
| 121 |
+
y=middle_band,
|
| 122 |
+
name='Middle Band',
|
| 123 |
+
line=dict(color='blue')
|
| 124 |
+
))
|
| 125 |
+
fig_bb.add_trace(go.Scatter(
|
| 126 |
+
x=data.index,
|
| 127 |
+
y=lower_band,
|
| 128 |
+
name='Lower Band',
|
| 129 |
+
line=dict(color='gray', dash='dash')
|
| 130 |
+
))
|
| 131 |
+
fig_bb.add_trace(go.Scatter(
|
| 132 |
+
x=data.index,
|
| 133 |
+
y=data['Close'],
|
| 134 |
+
name='Close Price',
|
| 135 |
+
line=dict(color='#00B894')
|
| 136 |
+
))
|
| 137 |
+
fig_bb.update_layout(title="Bollinger Bands", height=500)
|
| 138 |
+
st.plotly_chart(fig_bb, use_container_width=True)
|
| 139 |
|
| 140 |
with tab3:
|
| 141 |
# Support and Resistance
|
| 142 |
support, resistance = calculate_support_resistance(data)
|
| 143 |
+
fig_sr = go.Figure()
|
| 144 |
+
|
| 145 |
+
fig_sr.add_trace(go.Scatter(
|
| 146 |
+
x=data.index,
|
| 147 |
+
y=data['Close'],
|
| 148 |
+
name='Price',
|
| 149 |
+
line=dict(color='#00B894')
|
| 150 |
+
))
|
| 151 |
+
fig_sr.add_trace(go.Scatter(
|
| 152 |
+
x=data.index,
|
| 153 |
+
y=support,
|
| 154 |
+
name='Support',
|
| 155 |
+
line=dict(color='green', dash='dash')
|
| 156 |
+
))
|
| 157 |
+
fig_sr.add_trace(go.Scatter(
|
| 158 |
+
x=data.index,
|
| 159 |
+
y=resistance,
|
| 160 |
+
name='Resistance',
|
| 161 |
+
line=dict(color='red', dash='dash')
|
| 162 |
+
))
|
| 163 |
+
|
| 164 |
+
fig_sr.update_layout(
|
| 165 |
+
title="Support and Resistance Levels",
|
| 166 |
+
height=600
|
| 167 |
+
)
|
| 168 |
+
st.plotly_chart(fig_sr, use_container_width=True)
|
| 169 |
|
| 170 |
else:
|
| 171 |
st.error("Unable to fetch data. Please try again later.")
|