Raaniel's picture
Upload 2 files
1ccd1a1
raw
history blame
4.94 kB
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)