ratulsur commited on
Commit
47551b9
·
verified ·
1 Parent(s): 59e86d2

Upload 4 files

Browse files
Files changed (4) hide show
  1. predictions.py +145 -0
  2. quantum_patterns.py +155 -0
  3. sentiment_heatmap.py +214 -0
  4. technical_analysis.py +171 -0
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.")
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.")
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.")
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.")