Update app.py
Browse files
app.py
CHANGED
@@ -75,13 +75,13 @@ def plot_charts(data, symbol, interval):
|
|
75 |
|
76 |
# Determine the number of subplots based on the interval
|
77 |
if interval in minute_intervals:
|
78 |
-
rows =
|
79 |
-
subplot_titles = ('Price & Volume', 'RSI', 'MACD')
|
80 |
-
row_heights = [0.
|
81 |
else:
|
82 |
-
rows =
|
83 |
-
subplot_titles = ('Price & Volume', 'RSI', 'MACD', '
|
84 |
-
row_heights = [0.
|
85 |
|
86 |
fig = make_subplots(rows=rows, cols=1,
|
87 |
shared_xaxes=True,
|
@@ -111,6 +111,16 @@ def plot_charts(data, symbol, interval):
|
|
111 |
colors = ['red' if row['Open'] - row['Close'] >= 0 else 'green' for index, row in data.iterrows()]
|
112 |
fig.add_trace(go.Bar(x=data.index, y=data['Volume'], name='Volume', marker_color=colors), row=1, col=1)
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
# RSI
|
115 |
if 'RSI' in data.columns:
|
116 |
fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], name='RSI', line=dict(color='purple')), row=2, col=1)
|
@@ -121,21 +131,15 @@ def plot_charts(data, symbol, interval):
|
|
121 |
if 'MACD' in data.columns:
|
122 |
fig.add_trace(go.Scatter(x=data.index, y=data['MACD'], name='MACD', line=dict(color='blue')), row=3, col=1)
|
123 |
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
fig.add_trace(go.Scatter(x=data.index, y=data['BB_upper'], name='BB Upper',
|
128 |
-
line=dict(color='gray', dash='dash')), row=4, col=1)
|
129 |
-
fig.add_trace(go.Scatter(x=data.index, y=data['BB_middle'], name='BB Middle',
|
130 |
-
line=dict(color='gray')), row=4, col=1)
|
131 |
-
fig.add_trace(go.Scatter(x=data.index, y=data['BB_lower'], name='BB Lower',
|
132 |
-
line=dict(color='gray', dash='dash')), row=4, col=1)
|
133 |
|
134 |
# Update layout
|
135 |
fig.update_layout(
|
136 |
title=f'{symbol} Technical Analysis Dashboard',
|
137 |
yaxis_title='Price',
|
138 |
-
height=
|
139 |
showlegend=True,
|
140 |
xaxis_rangeslider_visible=False
|
141 |
)
|
@@ -200,7 +204,7 @@ def main():
|
|
200 |
else:
|
201 |
daily_change = 0.0 # Not enough data to calculate change
|
202 |
|
203 |
-
col1, col2, col3, col4 = st.columns(
|
204 |
col1.metric("Current Price", f"₹{current_price:.2f}", f"{daily_change:.2f}%")
|
205 |
|
206 |
if '52W_High' in data.columns and '52W_Low' in data.columns:
|
@@ -210,6 +214,9 @@ def main():
|
|
210 |
if 'RSI' in data.columns:
|
211 |
col4.metric("RSI", f"{data['RSI'][-1]:.2f}")
|
212 |
|
|
|
|
|
|
|
213 |
# Plot interactive charts
|
214 |
fig = plot_charts(data, symbol, interval)
|
215 |
st.plotly_chart(fig, use_container_width=True)
|
@@ -219,6 +226,8 @@ def main():
|
|
219 |
|
220 |
# Simple trading signals
|
221 |
signals = []
|
|
|
|
|
222 |
if 'RSI' in data.columns:
|
223 |
rsi = data['RSI'][-1]
|
224 |
if rsi < 30:
|
@@ -226,6 +235,7 @@ def main():
|
|
226 |
elif rsi > 70:
|
227 |
signals.append("RSI indicates overbought conditions")
|
228 |
|
|
|
229 |
if 'MACD' in data.columns:
|
230 |
macd = data['MACD'][-1]
|
231 |
if macd > 0:
|
@@ -233,6 +243,7 @@ def main():
|
|
233 |
else:
|
234 |
signals.append("MACD is negative - Bearish momentum")
|
235 |
|
|
|
236 |
if 'SMA_20' in data.columns and 'SMA_50' in data.columns:
|
237 |
current_price = data['Close'][-1]
|
238 |
sma_20 = data['SMA_20'][-1]
|
@@ -243,6 +254,25 @@ def main():
|
|
243 |
elif current_price < sma_20 and current_price < sma_50:
|
244 |
signals.append("Price is below major moving averages - Bearish")
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
for signal in signals:
|
247 |
st.write(f"• {signal}")
|
248 |
|
|
|
75 |
|
76 |
# Determine the number of subplots based on the interval
|
77 |
if interval in minute_intervals:
|
78 |
+
rows = 4 # Added an extra row for OBV
|
79 |
+
subplot_titles = ('Price & Volume', 'RSI', 'MACD', 'On-Balance Volume (OBV)')
|
80 |
+
row_heights = [0.35, 0.15, 0.15, 0.35]
|
81 |
else:
|
82 |
+
rows = 5 # Added two extra rows for OBV and Bollinger Bands
|
83 |
+
subplot_titles = ('Price & Volume', 'RSI', 'MACD', 'Bollinger Bands', 'On-Balance Volume (OBV)')
|
84 |
+
row_heights = [0.3, 0.15, 0.15, 0.2, 0.2]
|
85 |
|
86 |
fig = make_subplots(rows=rows, cols=1,
|
87 |
shared_xaxes=True,
|
|
|
111 |
colors = ['red' if row['Open'] - row['Close'] >= 0 else 'green' for index, row in data.iterrows()]
|
112 |
fig.add_trace(go.Bar(x=data.index, y=data['Volume'], name='Volume', marker_color=colors), row=1, col=1)
|
113 |
|
114 |
+
# Bollinger Bands
|
115 |
+
if rows == 5:
|
116 |
+
if 'BB_upper' in data.columns and 'BB_middle' in data.columns and 'BB_lower' in data.columns:
|
117 |
+
fig.add_trace(go.Scatter(x=data.index, y=data['BB_upper'], name='BB Upper',
|
118 |
+
line=dict(color='gray', dash='dash')), row=4, col=1)
|
119 |
+
fig.add_trace(go.Scatter(x=data.index, y=data['BB_middle'], name='BB Middle',
|
120 |
+
line=dict(color='gray')), row=4, col=1)
|
121 |
+
fig.add_trace(go.Scatter(x=data.index, y=data['BB_lower'], name='BB Lower',
|
122 |
+
line=dict(color='gray', dash='dash')), row=4, col=1)
|
123 |
+
|
124 |
# RSI
|
125 |
if 'RSI' in data.columns:
|
126 |
fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], name='RSI', line=dict(color='purple')), row=2, col=1)
|
|
|
131 |
if 'MACD' in data.columns:
|
132 |
fig.add_trace(go.Scatter(x=data.index, y=data['MACD'], name='MACD', line=dict(color='blue')), row=3, col=1)
|
133 |
|
134 |
+
# On-Balance Volume (OBV)
|
135 |
+
if 'OBV' in data.columns:
|
136 |
+
fig.add_trace(go.Scatter(x=data.index, y=data['OBV'], name='OBV', line=dict(color='brown')), row=rows, col=1)
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
|
138 |
# Update layout
|
139 |
fig.update_layout(
|
140 |
title=f'{symbol} Technical Analysis Dashboard',
|
141 |
yaxis_title='Price',
|
142 |
+
height=1000 if rows == 5 else 800,
|
143 |
showlegend=True,
|
144 |
xaxis_rangeslider_visible=False
|
145 |
)
|
|
|
204 |
else:
|
205 |
daily_change = 0.0 # Not enough data to calculate change
|
206 |
|
207 |
+
col1, col2, col3, col4, col5 = st.columns(5)
|
208 |
col1.metric("Current Price", f"₹{current_price:.2f}", f"{daily_change:.2f}%")
|
209 |
|
210 |
if '52W_High' in data.columns and '52W_Low' in data.columns:
|
|
|
214 |
if 'RSI' in data.columns:
|
215 |
col4.metric("RSI", f"{data['RSI'][-1]:.2f}")
|
216 |
|
217 |
+
if 'OBV' in data.columns:
|
218 |
+
col5.metric("OBV", f"{data['OBV'][-1]:.2f}")
|
219 |
+
|
220 |
# Plot interactive charts
|
221 |
fig = plot_charts(data, symbol, interval)
|
222 |
st.plotly_chart(fig, use_container_width=True)
|
|
|
226 |
|
227 |
# Simple trading signals
|
228 |
signals = []
|
229 |
+
|
230 |
+
# RSI Signals
|
231 |
if 'RSI' in data.columns:
|
232 |
rsi = data['RSI'][-1]
|
233 |
if rsi < 30:
|
|
|
235 |
elif rsi > 70:
|
236 |
signals.append("RSI indicates overbought conditions")
|
237 |
|
238 |
+
# MACD Signals
|
239 |
if 'MACD' in data.columns:
|
240 |
macd = data['MACD'][-1]
|
241 |
if macd > 0:
|
|
|
243 |
else:
|
244 |
signals.append("MACD is negative - Bearish momentum")
|
245 |
|
246 |
+
# SMA Signals
|
247 |
if 'SMA_20' in data.columns and 'SMA_50' in data.columns:
|
248 |
current_price = data['Close'][-1]
|
249 |
sma_20 = data['SMA_20'][-1]
|
|
|
254 |
elif current_price < sma_20 and current_price < sma_50:
|
255 |
signals.append("Price is below major moving averages - Bearish")
|
256 |
|
257 |
+
# OBV Signals
|
258 |
+
if 'OBV' in data.columns:
|
259 |
+
obv = data['OBV'][-1]
|
260 |
+
obv_prev = data['OBV'][-2] if len(data) >= 2 else obv
|
261 |
+
if obv > obv_prev:
|
262 |
+
signals.append("OBV is increasing - Positive volume trend")
|
263 |
+
elif obv < obv_prev:
|
264 |
+
signals.append("OBV is decreasing - Negative volume trend")
|
265 |
+
|
266 |
+
# Bollinger Bands Signals
|
267 |
+
if rows == 5:
|
268 |
+
price = data['Close'][-1]
|
269 |
+
bb_upper = data['BB_upper'][-1]
|
270 |
+
bb_lower = data['BB_lower'][-1]
|
271 |
+
if price > bb_upper:
|
272 |
+
signals.append("Price has breached the upper Bollinger Band - Potential overbought condition")
|
273 |
+
elif price < bb_lower:
|
274 |
+
signals.append("Price has breached the lower Bollinger Band - Potential oversold condition")
|
275 |
+
|
276 |
for signal in signals:
|
277 |
st.write(f"• {signal}")
|
278 |
|