File size: 5,797 Bytes
4ee8ea3 343a02a 4ee8ea3 f732c53 343a02a f732c53 6c634e7 4ee8ea3 f732c53 343a02a f732c53 343a02a f732c53 4ee8ea3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
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):
# Retrieving historical data and performing some preprocessing
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)
# Obtaining the annualized volatility
T = 20
df['Annualized_Vol'] = np.round(df['Returns'].rolling(T).std()*np.sqrt(252), 2)
# Calculating Bands
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]
# Creating Candlestick chart
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')
# Defining layout
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)
# Fixing the empty spaces in the X-Axis
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)]
)
# 1Ο
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")
# 2Ο
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")
# 3Ο
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()
# Printing Supply and Demand Levels
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")
# Creating the text output
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()
|