Commit
Β·
4ee8ea3
1
Parent(s):
06110f7
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import yfinance as yf
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import plotly.graph_objs as go
|
5 |
+
import gradio as gr
|
6 |
+
|
7 |
+
def plot_volatility_bands(ticker, reference_year):
|
8 |
+
|
9 |
+
# Retrieving historical data and performing some preprocessing
|
10 |
+
df = yf.download(ticker)
|
11 |
+
df['Returns'] = df['Adj Close'].pct_change(1)
|
12 |
+
df['Adj Low'] = df['Low'] - (df['Close'] - df['Adj Close'])
|
13 |
+
df['Adj High'] = df['High'] - (df['Close'] - df['Adj Close'])
|
14 |
+
df['Adj Open'] = df['Open'] - (df['Close'] - df['Adj Close'])
|
15 |
+
df = df.fillna(0)
|
16 |
+
|
17 |
+
# Obtaining the annualized volatility
|
18 |
+
T = 20
|
19 |
+
df['Annualized_Vol'] = np.round(df['Returns'].rolling(T).std()*np.sqrt(252), 2)
|
20 |
+
|
21 |
+
# Calculating Bands
|
22 |
+
High_Band_1std = df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1] + df.loc[reference_year]["Adj Close"][-1]
|
23 |
+
Low_Band_1std = df.loc[reference_year]["Adj Close"][-1] - df.loc[reference_year]["Annualized_Vol"][-1]*df.loc[reference_year]["Adj Close"][-1]
|
24 |
+
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]
|
25 |
+
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]
|
26 |
+
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]
|
27 |
+
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]
|
28 |
+
|
29 |
+
|
30 |
+
# Creating Candlestick chart
|
31 |
+
candlestick = go.Candlestick(x = df.loc[str(int(reference_year) + 1)].index,
|
32 |
+
open = df.loc[str(int(reference_year) + 1)]['Adj Open'],
|
33 |
+
high = df.loc[str(int(reference_year) + 1)]['Adj High'],
|
34 |
+
low = df.loc[str(int(reference_year) + 1)]['Adj Low'],
|
35 |
+
close = df.loc[str(int(reference_year) + 1)]['Adj Close'],
|
36 |
+
increasing = dict(line=dict(color = 'red')),
|
37 |
+
decreasing = dict(line=dict(color = 'black')),
|
38 |
+
name = 'Candlesticks')
|
39 |
+
|
40 |
+
|
41 |
+
# Defining layout
|
42 |
+
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>',
|
43 |
+
'x': .035, 'xanchor': 'left'},
|
44 |
+
yaxis = dict(title = '<b>Price (USD)</b>',
|
45 |
+
tickfont=dict(size=16)),
|
46 |
+
xaxis = dict(title = '<b>Date</b>'),
|
47 |
+
template = 'seaborn',
|
48 |
+
plot_bgcolor = '#F6F5F5',
|
49 |
+
paper_bgcolor = '#F6F5F5',
|
50 |
+
height = 850, width = 1000,
|
51 |
+
showlegend=False,
|
52 |
+
xaxis_rangeslider_visible = False)
|
53 |
+
|
54 |
+
fig = go.Figure(data = [candlestick], layout = layout)
|
55 |
+
|
56 |
+
# Fixing the empty spaces in the X-Axis
|
57 |
+
dt_all = pd.date_range(start = df.index[0]
|
58 |
+
, end = df.index[-1]
|
59 |
+
, freq = "D")
|
60 |
+
dt_all_py = [d.to_pydatetime() for d in dt_all]
|
61 |
+
dt_obs_py = [d.to_pydatetime() for d in df.index]
|
62 |
+
|
63 |
+
dt_breaks = [d for d in dt_all_py if d not in dt_obs_py]
|
64 |
+
|
65 |
+
fig.update_xaxes(
|
66 |
+
rangebreaks = [dict(values = dt_breaks)]
|
67 |
+
)
|
68 |
+
|
69 |
+
# 1Ο
|
70 |
+
fig.add_hline(y = High_Band_1std, line_width = 2, line_dash = "dot", line_color = "green")
|
71 |
+
fig.add_hline(y = Low_Band_1std, line_width = 2, line_dash = "dot", line_color = "red")
|
72 |
+
|
73 |
+
# 2Ο
|
74 |
+
fig.add_hline(y = High_Band_2std, line_width = 4, line_dash = "dash", line_color = "green")
|
75 |
+
fig.add_hline(y = Low_Band_2std, line_width = 4, line_dash = "dash", line_color = "red")
|
76 |
+
|
77 |
+
# 3Ο
|
78 |
+
fig.add_hline(y = High_Band_3std, line_width = 6, line_dash = "dashdot", line_color = "green")
|
79 |
+
fig.add_hline(y = Low_Band_3std, line_width = 6, line_dash = "dashdot", line_color = "red")
|
80 |
+
|
81 |
+
fig.show()
|
82 |
+
|
83 |
+
# Printing Supply and Demand Levels
|
84 |
+
print(f"\nVolatility-Based Supply and Demand Levels for {ticker} in {int(reference_year) + 1}\n")
|
85 |
+
print(f"Supply Level 3Ο: {High_Band_3std.round(2)}\n")
|
86 |
+
print(f"Supply Level 2Ο: {High_Band_2std.round(2)}\n")
|
87 |
+
print(f"Supply Level 1Ο: {High_Band_1std.round(2)}\n")
|
88 |
+
print('-' * 65, '\n')
|
89 |
+
print(f"Demand Level 1Ο: {Low_Band_1std.round(2)}\n")
|
90 |
+
print(f"Demand Level 2Ο: {Low_Band_2std.round(2)}\n")
|
91 |
+
print(f"Demand Level 3Ο: {Low_Band_3std.round(2)}\n")
|
92 |
+
|
93 |
+
# Creating an HTML extension of the Plotly figure
|
94 |
+
fig_html = fig.to_html(full_html=False, include_plotlyjs='cdn')
|
95 |
+
|
96 |
+
# Creating the text output
|
97 |
+
text_info = f"""
|
98 |
+
Volatility-Based Supply and Demand Levels for {ticker} in {int(reference_year) + 1}\n
|
99 |
+
Supply Level 3Ο: {High_Band_3std.round(2)}\n
|
100 |
+
Supply Level 2Ο: {High_Band_2std.round(2)}\n
|
101 |
+
Supply Level 1Ο: {High_Band_1std.round(2)}\n
|
102 |
+
-------------------------\n
|
103 |
+
Demand Level 1Ο: {Low_Band_1std.round(2)}\n
|
104 |
+
Demand Level 2Ο: {Low_Band_2std.round(2)}\n
|
105 |
+
Demand Level 3Ο: {Low_Band_3std.round(2)}\n
|
106 |
+
"""
|
107 |
+
|
108 |
+
return fig_html, text_info
|
109 |
+
|
110 |
+
def wrapper_func(ticker, reference_year):
|
111 |
+
fig_html, text_info = plot_volatility_bands(ticker, str(reference_year))
|
112 |
+
return fig_html, text_info
|
113 |
+
|
114 |
+
iface = gr.Interface(
|
115 |
+
fn=wrapper_func,
|
116 |
+
inputs=["text", "number"],
|
117 |
+
outputs=["html", "text"]
|
118 |
+
)
|
119 |
+
|
120 |
+
iface.launch()
|