Spaces:
Runtime error
Runtime error
import pandas as pd | |
import yfinance as yf | |
import numpy as np | |
import plotly.graph_objects as go | |
from plotly.subplots import make_subplots | |
from sklearn.cluster import AgglomerativeClustering | |
import streamlit as st | |
import requests | |
from streamlit_lottie import st_lottie | |
st.set_page_config(page_title = "Support and resistance levels", | |
page_icon = ':π:', | |
layout = 'wide') | |
st.title('π Technical analysis π') | |
st.header('Find support and resistance levels for :blue[price action] analysis!') | |
st.divider() | |
def load_lottieurl(url: str): | |
r = requests.get(url) | |
if r.status_code != 200: | |
return None | |
return r.json() | |
lottie_url__money = "https://assets1.lottiefiles.com/packages/lf20_06a6pf9i.json" | |
lottie_money = load_lottieurl(lottie_url__money) | |
st.sidebar.header('Please choose parameters: ') | |
ticker = st.text_input('Select stock to analyse: (Make sure the ticker you search for is supported by Yahoo! Finance).', 'BNB-USD') | |
interval = '1h' | |
num_clusters = st.sidebar.select_slider( | |
'Select a number of clusters', | |
options=[i for i in range(1,8)]) | |
rolling_wave_length = st.sidebar.select_slider( | |
'''Select a length of rolling wave | |
(how much data to cluster at one time)''', | |
options=[i for i in range(5, 21)]) | |
period_num = st.sidebar.select_slider( | |
'Select number of days to display on chart', | |
options=[i for i in range(1, 31)]) | |
period = '{}d'.format(period_num) | |
df = yf.download(ticker, period = period, interval = interval) | |
df.index = pd.to_datetime(df.index).strftime("%d-%m-%Y %H:%M") | |
df = df.drop(columns = ["Adj Close"]) | |
left_column, right_column = st.columns(2) | |
left_column.markdown('<span style="font-size:20px; font-weight:600; letter-spacing:2px;">Preview data:</span>', | |
unsafe_allow_html = True) | |
left_column.dataframe(df, height = 400) | |
with right_column: | |
st_lottie(lottie_money, key="money") | |
#creating function | |
def calculate_support_resistance(df, rolling_wave_length, num_clusters): | |
date = df.index | |
df.reset_index(inplace=True) | |
max_waves_temp = df.High.rolling(rolling_wave_length).max().rename('waves') | |
min_waves_temp = df.Low.rolling(rolling_wave_length).min().rename('waves') | |
max_waves = pd.concat([max_waves_temp, pd.Series(np.zeros(len(max_waves_temp)) + 1)], axis=1) | |
min_waves = pd.concat([min_waves_temp, pd.Series(np.zeros(len(min_waves_temp)) + -1)], axis=1) | |
max_waves.drop_duplicates('waves', inplace=True) | |
min_waves.drop_duplicates('waves', inplace=True) | |
waves = pd.concat([max_waves, min_waves]).sort_index() | |
waves = waves[waves[0] != waves[0].shift()].dropna() | |
x = np.concatenate((waves.waves.values.reshape(-1, 1), | |
(np.zeros(len(waves)) + 1).reshape(-1, 1)), axis=1) | |
cluster = AgglomerativeClustering(n_clusters=num_clusters, linkage='ward') | |
cluster.fit_predict(x) | |
waves['clusters'] = cluster.labels_ | |
waves2 = waves.loc[waves.groupby('clusters')['waves'].idxmax()] | |
df.index = date | |
waves2.waves.drop_duplicates(keep='first', inplace=True) | |
return waves2.reset_index().waves | |
support_resistance_levels = calculate_support_resistance(df, rolling_wave_length, num_clusters) | |
#creating a plot | |
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, | |
vertical_spacing=0.06, subplot_titles=('OHLC', 'Volume'), | |
row_width=[0.3, 0.7]) | |
fig.add_trace(go.Candlestick(x=df.index, | |
open=df['Open'], | |
high=df['High'], | |
low=df['Low'], | |
close=df['Close'], name = "Market data"), row = 1, col = 1) | |
fig.update_xaxes( | |
rangeslider_visible = False, | |
rangeselector=dict( | |
buttons=list([ | |
dict(count=1, label="1d", | |
step="day", stepmode="backward"), | |
dict(count=3, label="3d", | |
step="day", stepmode="backward"), | |
dict(count=7, label="7d", | |
step="day", stepmode="backward"), | |
dict(count=30, label="30d", | |
step="day", stepmode="backward"), | |
dict(step="all")]))) | |
i = 0 | |
for level in support_resistance_levels.to_list(): | |
fig.add_hline(y=level, line_width=1, | |
line_dash="dash", row=1, col=1, | |
line_color="snow") | |
i += 1 | |
colors = [] | |
for i in range(len(df.Close)): | |
if i != 0: | |
if df.Close[i] > df.Close[i-1]: | |
colors.append('lightgreen') | |
else: | |
colors.append('lightcoral') | |
else: | |
colors.append('lightcoral') | |
fig.add_trace(go.Bar(x=df.index, y=df['Volume'], showlegend=False, | |
marker=dict(color=colors)), row=2, col=1) | |
fig.update_traces(name= 'Volume', selector=dict(type='bar')) | |
text = f'{ticker} Chart' | |
fig.update_layout( | |
title=go.layout.Title( | |
text=text, | |
xref="paper", | |
x=0)) | |
#show chart | |
st.plotly_chart(fig, use_container_width=True) |