Spaces:
Runtime error
Runtime error
Update app.py
Browse filesAdded support + resistance analyzer
app.py
CHANGED
|
@@ -30,6 +30,21 @@ sector_etf_mapping = {
|
|
| 30 |
'Communication Services': 'XLC'
|
| 31 |
}
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
# Function to get the trend of a given stock or ETF
|
| 34 |
def get_trend(ticker, period='1mo'):
|
| 35 |
stock = yf.Ticker(ticker)
|
|
@@ -212,6 +227,54 @@ if uploaded_file is not None:
|
|
| 212 |
fig.update_layout(title='Stock and Sector Trend over the past 30 days', xaxis_title='Date', yaxis_title='Normalized Close Price', autosize=False, width=2000, height=1200)
|
| 213 |
st.plotly_chart(fig)
|
| 214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
st.subheader("Hourly and Daily Sentiment of {} Stock".format(ticker))
|
| 216 |
news_table = get_news(ticker)
|
| 217 |
parsed_news_df = parse_news(news_table)
|
|
|
|
| 30 |
'Communication Services': 'XLC'
|
| 31 |
}
|
| 32 |
|
| 33 |
+
|
| 34 |
+
# Create two functions to calculate if a level is SUPPORT or a RESISTANCE level through fractal identification
|
| 35 |
+
def is_Suppport_Level(df, i):
|
| 36 |
+
support = df['Low'][i] < df['Low'][i - 1] and df['Low'][i] < df['Low'][i + 1] and df['Low'][i + 1] < df['Low'][i + 2] and df['Low'][i - 1] < df['Low'][i - 2]
|
| 37 |
+
return support
|
| 38 |
+
|
| 39 |
+
def is_Resistance_Level(df, i):
|
| 40 |
+
resistance = df['High'][i] > df['High'][i - 1] and df['High'][i] > df['High'][i + 1] and df['High'][i + 1] > df['High'][i + 2] and df['High'][i - 1] > df['High'][i - 2]
|
| 41 |
+
return resistance
|
| 42 |
+
|
| 43 |
+
# This function, given a price value, returns True or False depending on if it is too near to some previously discovered key level.
|
| 44 |
+
def distance_from_mean(level, levels, mean):
|
| 45 |
+
return np.sum([abs(level - y) < mean for y in levels]) == 0
|
| 46 |
+
|
| 47 |
+
|
| 48 |
# Function to get the trend of a given stock or ETF
|
| 49 |
def get_trend(ticker, period='1mo'):
|
| 50 |
stock = yf.Ticker(ticker)
|
|
|
|
| 227 |
fig.update_layout(title='Stock and Sector Trend over the past 30 days', xaxis_title='Date', yaxis_title='Normalized Close Price', autosize=False, width=2000, height=1200)
|
| 228 |
st.plotly_chart(fig)
|
| 229 |
|
| 230 |
+
|
| 231 |
+
ticker2 = yf.Ticker(ticker)
|
| 232 |
+
df = ticker2.history(period="3mo", actions=False)
|
| 233 |
+
|
| 234 |
+
# Creating a list and feeding it the identified support and resistance levels via the Support and Resistance functions
|
| 235 |
+
levels = []
|
| 236 |
+
level_types = []
|
| 237 |
+
mean = np.mean(df['High'] - df['Low'])
|
| 238 |
+
|
| 239 |
+
for i in range(2, df.shape[0] - 2):
|
| 240 |
+
|
| 241 |
+
if is_Suppport_Level(df, i):
|
| 242 |
+
level = df['Low'][i].round(2)
|
| 243 |
+
|
| 244 |
+
if distance_from_mean(level, levels, mean):
|
| 245 |
+
levels.append(level)
|
| 246 |
+
level_types.append('Support')
|
| 247 |
+
|
| 248 |
+
elif is_Resistance_Level(df, i):
|
| 249 |
+
level = df['High'][i].round(2)
|
| 250 |
+
|
| 251 |
+
if distance_from_mean(level, levels, mean):
|
| 252 |
+
levels.append(level)
|
| 253 |
+
level_types.append('Resistance')
|
| 254 |
+
|
| 255 |
+
# Plotting the data
|
| 256 |
+
fig2 = go.Figure(data=[go.Candlestick(x=df.index,
|
| 257 |
+
open=df['Open'],
|
| 258 |
+
high=df['High'],
|
| 259 |
+
low=df['Low'],
|
| 260 |
+
close=df['Close'])])
|
| 261 |
+
|
| 262 |
+
for level, level_type in zip(levels, level_types):
|
| 263 |
+
fig2.add_trace(go.Scatter(x=df.index, y=[level]*len(df.index), mode='lines', name=level_type))
|
| 264 |
+
|
| 265 |
+
fig2.update_layout(title='Support and Resistance levels for ' + ticker,
|
| 266 |
+
xaxis_title='Date',
|
| 267 |
+
yaxis_title='Price',
|
| 268 |
+
autosize=False,
|
| 269 |
+
width=2000,
|
| 270 |
+
height=1200)
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
st.plotly_chart(fig2)
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
|
| 278 |
st.subheader("Hourly and Daily Sentiment of {} Stock".format(ticker))
|
| 279 |
news_table = get_news(ticker)
|
| 280 |
parsed_news_df = parse_news(news_table)
|