QuantumLearner commited on
Commit
5d24c08
·
verified ·
1 Parent(s): 999cbda

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -8
app.py CHANGED
@@ -13,7 +13,14 @@ st.set_page_config(page_title="Identifying Key Support and Resistance In Price L
13
  st.title('Key Support and Resistance In Price Levels')
14
 
15
  st.markdown("""
16
- This tool aims to identify key support and resistance price levels in stocks using various algorithmic methods. Select the method from the dropdown menu to view the corresponding analysis.
 
 
 
 
 
 
 
17
  """)
18
 
19
  # Sidebar for input parameters
@@ -45,8 +52,8 @@ with st.sidebar:
45
  n_days = st.slider('Lookback Period for Volume Profile and KMeans (Days)', min_value=30, max_value=365, value=60, help="Set the number of days for calculating volume profile and KMeans clustering.")
46
  num_clusters = st.slider('Number of Clusters for KMeans', min_value=2, max_value=10, value=3, help="Set the number of clusters for KMeans analysis.")
47
 
48
- # Select analysis type
49
- analysis_type = st.selectbox("Select Analysis", ["Pivot Points", "Support and Resistance", "Swing Highs and Lows", "Fibonacci Retracement Levels", "Trendlines", "Volume Profile", "KMeans Clustering"])
50
 
51
  # Function to fetch and cache data
52
  @st.cache_data
@@ -56,6 +63,54 @@ def get_data(ticker, start_date, end_date):
56
  st.error("No data found for the given ticker and date range.")
57
  return data
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  # Run analysis only if the user clicks the "Run Analysis" button
60
  if st.sidebar.button('Run Analysis'):
61
  data = get_data(ticker, start_date, end_date)
@@ -133,7 +188,7 @@ if st.sidebar.button('Run Analysis'):
133
  fig3 = go.Figure()
134
  fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Close'], mode='lines', name='Close Price'))
135
  fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Swing_High'], mode='markers', name='Swing Highs', marker=dict(color='red')))
136
- fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Swing_Low'], mode='markers', name='Swing Lows', marker=dict(color='green')))
137
  fig3.update_layout(
138
  title=f'{ticker} with Swing Highs & Lows',
139
  xaxis_title='Date',
@@ -157,7 +212,7 @@ if st.sidebar.button('Run Analysis'):
157
  fig4.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Stock Price'))
158
  color_list = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
159
  for i, (level, color) in enumerate(zip(levels, color_list)):
160
- fig4.add_trace(go.Scatter(x=data.index, y=fib_levels[:, i], mode='lines', name=f'Fib {level:.3f}', line=dict(color=color)))
161
  fig4.update_layout(
162
  title=f'{ticker} with Fibonacci Retracement Levels',
163
  xaxis_title='Date',
@@ -192,8 +247,8 @@ if st.sidebar.button('Run Analysis'):
192
  lower_m, lower_b = np.polyfit(swing_lows.index.map(pd.Timestamp.toordinal), swing_lows.values, 1)
193
  data_with_trendlines['Upper_Trendline'] = upper_m * data_with_trendlines.index.map(pd.Timestamp.toordinal) + upper_b
194
  data_with_trendlines['Lower_Trendline'] = lower_m * data_with_trendlines.index.map(pd.Timestamp.toordinal) + lower_b
195
- fig5.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Upper_Trendline'], mode='lines', name='Upper Trendline', line=dict(color='orange')))
196
- fig5.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Lower_Trendline'], mode='lines', name='Lower Trendline', line=dict(color='blue')))
197
 
198
  fig5.update_layout(
199
  title=f'{ticker} with Trendlines',
@@ -254,7 +309,7 @@ if st.sidebar.button('Run Analysis'):
254
  fig7.add_trace(go.Scatter(x=[data.index[-1]], y=[center], mode='markers+text', name=f'Cluster Center: {center:.2f}', text=[f'{center:.2f}'], textposition='top center'))
255
  fig7.add_shape(type="line",
256
  x0=data.index[0], x1=data.index[-1], y0=center, y1=center,
257
- line=dict(color='Red', dash="dash"))
258
  fig7.update_layout(
259
  title=f'{ticker} with KMeans Clustering (Last {n_days} Days)',
260
  xaxis_title='Date',
@@ -264,6 +319,7 @@ if st.sidebar.button('Run Analysis'):
264
  height=600
265
  )
266
  st.plotly_chart(fig7, use_container_width=True)
 
267
  else:
268
  st.write("No data found for the given ticker and date range.")
269
 
 
13
  st.title('Key Support and Resistance In Price Levels')
14
 
15
  st.markdown("""
16
+ This tool aims to identify key support and resistance price levels in stocks using various algorithmic methods. Each method is detailed below:
17
+ 1. **Pivot Points**: Short-term trend indicators used to determine potential support and resistance levels based on the high, low, and close prices of previous trading sessions.
18
+ 2. **Support and Resistance Levels using Rolling Midpoint Range**: Key price points where the stock's price tends to halt its upward or downward trajectory, identified using a rolling window to calculate dynamic support and resistance levels.
19
+ 3. **Swing Highs and Lows**: Local maxima and minima used to identify trends and potential reversal points by pinpointing key inflection points on a stock's chart.
20
+ 4. **Fibonacci Retracement Levels**: Horizontal lines indicating potential support and resistance levels based on Fibonacci numbers, helping to identify prospective market reversal points.
21
+ 5. **Trendlines**: Straight lines drawn to connect two or more price points, helping identify the market trend direction and potential areas of support and resistance.
22
+ 6. **Volume Profile**: A charting tool that shows the amount of volume traded at different price levels over a specified period, helping identify areas of high trading activity which can act as support or resistance.
23
+ 7. **KMeans Clustering**: A machine learning algorithm used to partition the dataset into clusters, identifying patterns and grouping similar price movements together to highlight significant price levels.
24
  """)
25
 
26
  # Sidebar for input parameters
 
52
  n_days = st.slider('Lookback Period for Volume Profile and KMeans (Days)', min_value=30, max_value=365, value=60, help="Set the number of days for calculating volume profile and KMeans clustering.")
53
  num_clusters = st.slider('Number of Clusters for KMeans', min_value=2, max_value=10, value=3, help="Set the number of clusters for KMeans analysis.")
54
 
55
+ # Select the page (analysis type)
56
+ analysis_type = st.radio("Select Analysis", ["Pivot Points", "Support and Resistance", "Swing Highs and Lows", "Fibonacci Retracement Levels", "Trendlines", "Volume Profile", "KMeans Clustering"])
57
 
58
  # Function to fetch and cache data
59
  @st.cache_data
 
63
  st.error("No data found for the given ticker and date range.")
64
  return data
65
 
66
+ # Functions for different analyses
67
+ def calculate_pivot_points(df, window):
68
+ df['Pivot'] = df['Close'].rolling(window=window).mean()
69
+ df['R1'] = 2 * df['Pivot'] - df['Low'].rolling(window=window).min()
70
+ df['S1'] = 2 * df['Pivot'] - df['High'].rolling(window=window).max()
71
+ df['R2'] = df['Pivot'] + (df['High'].rolling(window=window).max() - df['Low'].rolling(window=window).min())
72
+ df['S2'] = df['Pivot'] - (df['High'].rolling(window=window).max() - df['Low'].rolling(window=window).min())
73
+ return df
74
+
75
+ def find_levels(data, window):
76
+ resistance = data['High'].rolling(window=window).max()
77
+ support = data['Low'].rolling(window=window).min()
78
+ return support, resistance
79
+
80
+ def check_significant_break(data, support, resistance):
81
+ breaks_above_resistance = (data['Close'] > resistance.shift(1)) & (data['Volume'] > data['Volume'].rolling(window=30).mean())
82
+ breaks_below_support = (data['Close'] < support.shift(1)) & (data['Volume'] > data['Volume'].rolling(window=30).mean())
83
+ return breaks_above_resistance, breaks_below_support
84
+
85
+ def prepare_data_for_trendlines(data, lookback_period):
86
+ data['Swing_High'] = data['High'][argrelextrema(data['High'].values, np.greater_equal, order=lookback_period)[0]]
87
+ data['Swing_Low'] = data['Low'][argrelextrema(data['Low'].values, np.less_equal, order=lookback_period)[0]]
88
+ return data
89
+
90
+ def calculate_fibonacci_levels(data, lookback_period):
91
+ high_prices = data["High"].rolling(window=lookback_period).max()
92
+ low_prices = data["Low"].rolling(window=lookback_period).min()
93
+ price_diff = high_prices - low_prices
94
+ levels = np.array([0, 0.236, 0.382, 0.5, 0.618, 0.786, 1])
95
+ fib_levels = low_prices.values.reshape(-1, 1) + price_diff.values.reshape(-1, 1) * levels
96
+ return fib_levels, levels
97
+
98
+ def calculate_volume_profile(data, n_days):
99
+ filtered_data = data[-n_days:]
100
+ price_bins = np.linspace(filtered_data['Low'].min(), filtered_data['High'].max(), 100)
101
+ volume_profile = [filtered_data['Volume'][(filtered_data['Close'] > price_bins[i]) & (filtered_data['Close'] <= price_bins[i+1])].sum() for i in range(len(price_bins)-1)]
102
+ return price_bins, volume_profile
103
+
104
+ def calculate_kmeans_clusters(data, n_days, num_clusters):
105
+ filtered_data = data[-n_days:]
106
+ X_time = np.linspace(0, 1, len(filtered_data)).reshape(-1, 1)
107
+ X_price = (filtered_data['Close'].values - np.min(filtered_data['Close'])) / (np.max(filtered_data['Close']) - np.min(filtered_data['Close']))
108
+ X_cluster = np.column_stack((X_time, X_price))
109
+ kmeans = KMeans(n_clusters=num_clusters)
110
+ kmeans.fit(X_cluster)
111
+ cluster_centers = kmeans.cluster_centers_[:, 1] * (np.max(filtered_data['Close']) - np.min(filtered_data['Close'])) + np.min(filtered_data['Close'])
112
+ return cluster_centers
113
+
114
  # Run analysis only if the user clicks the "Run Analysis" button
115
  if st.sidebar.button('Run Analysis'):
116
  data = get_data(ticker, start_date, end_date)
 
188
  fig3 = go.Figure()
189
  fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Close'], mode='lines', name='Close Price'))
190
  fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Swing_High'], mode='markers', name='Swing Highs', marker=dict(color='red')))
191
+ fig3.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Swing_Low'], mode='markers', name='Swing Lows', marker.dict(color='green')))
192
  fig3.update_layout(
193
  title=f'{ticker} with Swing Highs & Lows',
194
  xaxis_title='Date',
 
212
  fig4.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Stock Price'))
213
  color_list = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
214
  for i, (level, color) in enumerate(zip(levels, color_list)):
215
+ fig4.add_trace(go.Scatter(x=data.index, y=fib_levels[:, i], mode='lines', name=f'Fib {level:.3f}', line.dict(color=color)))
216
  fig4.update_layout(
217
  title=f'{ticker} with Fibonacci Retracement Levels',
218
  xaxis_title='Date',
 
247
  lower_m, lower_b = np.polyfit(swing_lows.index.map(pd.Timestamp.toordinal), swing_lows.values, 1)
248
  data_with_trendlines['Upper_Trendline'] = upper_m * data_with_trendlines.index.map(pd.Timestamp.toordinal) + upper_b
249
  data_with_trendlines['Lower_Trendline'] = lower_m * data_with_trendlines.index.map(pd.Timestamp.toordinal) + lower_b
250
+ fig5.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Upper_Trendline'], mode='lines', name='Upper Trendline', line.dict(color='orange')))
251
+ fig5.add_trace(go.Scatter(x=data_with_trendlines.index, y=data_with_trendlines['Lower_Trendline'], mode='lines', name='Lower Trendline', line.dict(color='blue')))
252
 
253
  fig5.update_layout(
254
  title=f'{ticker} with Trendlines',
 
309
  fig7.add_trace(go.Scatter(x=[data.index[-1]], y=[center], mode='markers+text', name=f'Cluster Center: {center:.2f}', text=[f'{center:.2f}'], textposition='top center'))
310
  fig7.add_shape(type="line",
311
  x0=data.index[0], x1=data.index[-1], y0=center, y1=center,
312
+ line.dict(color='Red', dash="dash"))
313
  fig7.update_layout(
314
  title=f'{ticker} with KMeans Clustering (Last {n_days} Days)',
315
  xaxis_title='Date',
 
319
  height=600
320
  )
321
  st.plotly_chart(fig7, use_container_width=True)
322
+
323
  else:
324
  st.write("No data found for the given ticker and date range.")
325