|
import yfinance as yf |
|
import numpy as np |
|
import pandas as pd |
|
import plotly.graph_objs as go |
|
import gradio as gr |
|
|
|
def plot_volatility_bands(ticker, reference_year): |
|
|
|
|
|
df = yf.download(ticker) |
|
df['Returns'] = df['Adj Close'].pct_change(1) |
|
df['Adj Low'] = df['Low'] - (df['Close'] - df['Adj Close']) |
|
df['Adj High'] = df['High'] - (df['Close'] - df['Adj Close']) |
|
df['Adj Open'] = df['Open'] - (df['Close'] - df['Adj Close']) |
|
df = df.fillna(0) |
|
|
|
|
|
T = 20 |
|
df['Annualized_Vol'] = np.round(df['Returns'].rolling(T).std()*np.sqrt(252), 2) |
|
|
|
|
|
High_Band_1std = df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] + df.loc[reference_year]["Adj Close"][-1] |
|
Low_Band_1std = df.loc[reference_year]["Adj Close"][-1] - df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] |
|
High_Band_2std = 2*df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] + df.loc[reference_year]["Adj Close"][-1] |
|
Low_Band_2std = df.loc[reference_year]["Adj Close"][-1] - 2*df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] |
|
High_Band_3std = 3*df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] + df.loc[reference_year]["Adj Close"][-1] |
|
Low_Band_3std = df.loc[reference_year]["Adj Close"][-1] - 3*df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] |
|
|
|
|
|
|
|
candlestick = go.Candlestick(x = df.loc[str(int(reference_year) + 1)].index, |
|
open = df.loc[str(int(reference_year) + 1)]['Adj Open'], |
|
high = df.loc[str(int(reference_year) + 1)]['Adj High'], |
|
low = df.loc[str(int(reference_year) + 1)]['Adj Low'], |
|
close = df.loc[str(int(reference_year) + 1)]['Adj Close'], |
|
increasing = dict(line=dict(color = 'red')), |
|
decreasing = dict(line=dict(color = 'black')), |
|
name = 'Candlesticks') |
|
|
|
|
|
|
|
layout = go.Layout(title = {'text': f'<b>Volatility-Based Supply and Demand Levels ({ticker})<br><br><sup> <i>Yearly Forecast - {str(int(reference_year) + 1)}</i></sup></b>', |
|
'x': .035, 'xanchor': 'left'}, |
|
yaxis = dict(title = '<b>Price (USD)</b>', |
|
tickfont=dict(size=16)), |
|
xaxis = dict(title = '<b>Date</b>'), |
|
template = 'seaborn', |
|
plot_bgcolor = '#F6F5F5', |
|
paper_bgcolor = '#F6F5F5', |
|
height = 850, width = 1000, |
|
showlegend=False, |
|
xaxis_rangeslider_visible = False) |
|
|
|
fig = go.Figure(data = [candlestick], layout = layout) |
|
|
|
|
|
dt_all = pd.date_range(start = df.index[0] |
|
, end = df.index[-1] |
|
, freq = "D") |
|
dt_all_py = [d.to_pydatetime() for d in dt_all] |
|
dt_obs_py = [d.to_pydatetime() for d in df.index] |
|
|
|
dt_breaks = [d for d in dt_all_py if d not in dt_obs_py] |
|
|
|
fig.update_xaxes( |
|
rangebreaks = [dict(values = dt_breaks)] |
|
) |
|
|
|
|
|
fig.add_hline(y = High_Band_1std, line_width = 2, line_dash = "dot", line_color = "green") |
|
fig.add_hline(y = Low_Band_1std, line_width = 2, line_dash = "dot", line_color = "red") |
|
|
|
|
|
fig.add_hline(y = High_Band_2std, line_width = 4, line_dash = "dash", line_color = "green") |
|
fig.add_hline(y = Low_Band_2std, line_width = 4, line_dash = "dash", line_color = "red") |
|
|
|
|
|
fig.add_hline(y = High_Band_3std, line_width = 6, line_dash = "dashdot", line_color = "green") |
|
fig.add_hline(y = Low_Band_3std, line_width = 6, line_dash = "dashdot", line_color = "red") |
|
|
|
fig.show() |
|
|
|
|
|
print(f"\nVolatility-Based Supply and Demand Levels for {ticker} in {int(reference_year) + 1}\n") |
|
print(f"Supply Level 3Ο: {High_Band_3std.round(2)}\n") |
|
print(f"Supply Level 2Ο: {High_Band_2std.round(2)}\n") |
|
print(f"Supply Level 1Ο: {High_Band_1std.round(2)}\n") |
|
print('-' * 65, '\n') |
|
print(f"Demand Level 1Ο: {Low_Band_1std.round(2)}\n") |
|
print(f"Demand Level 2Ο: {Low_Band_2std.round(2)}\n") |
|
print(f"Demand Level 3Ο: {Low_Band_3std.round(2)}\n") |
|
|
|
|
|
|
|
text_info = f""" |
|
Volatility-Based Supply and Demand Levels for {ticker} in {int(reference_year) + 1}\n |
|
Supply Level 3Ο: {High_Band_3std.round(2)}\n |
|
Supply Level 2Ο: {High_Band_2std.round(2)}\n |
|
Supply Level 1Ο: {High_Band_1std.round(2)}\n |
|
-------------------------\n |
|
Demand Level 1Ο: {Low_Band_1std.round(2)}\n |
|
Demand Level 2Ο: {Low_Band_2std.round(2)}\n |
|
Demand Level 3Ο: {Low_Band_3std.round(2)}\n |
|
""" |
|
|
|
return fig, text_info |
|
|
|
def wrapper_func(ticker, reference_year): |
|
try: |
|
fig, text_info = plot_volatility_bands(ticker, str(int(reference_year))) |
|
return fig, text_info |
|
except Exception as e: |
|
error_message = str(e) |
|
return error_message, error_message |
|
|
|
iface = gr.Interface( |
|
fn=wrapper_func, |
|
inputs=[ |
|
gr.Textbox(label="Enter the Ticker as it Appears on Yahoo Finance"), |
|
gr.Number(label="Enter the Year of Reference") |
|
], |
|
outputs=[ |
|
gr.Plotly(label="Candlestick Chart"), |
|
gr.Textbox(label="Supply and Demand Levels") |
|
] |
|
) |
|
|
|
iface.launch() |
|
|