I am creating a financial dashboard with Python and Dash. I am using Python 3.7, Dash 1.18.1 and Yahoo Finance 0.1.55. I am able to pull stock data from the Yahoo Finance API and create a correlation matrix as well as extract the pair of symbols with the highest correlation and the pair of symbols with the lowest correlation. I have a tabbed dashboard and I am trying to return the correlation matrix and the dynamic text side by side on the first tab of the dashboard. Part of my app is set up like this:
app.layout = html.Div([
dcc.Tabs(id='tabs', value='corr_matrix', children=[
dcc.Tab(label='Correlation Matrix', value='corr_matrix', style=tab_style, selected_style=tab_selected_style),
dcc.Tab(label='Compare Performance', value='performance', style=tab_style, selected_style=tab_selected_style)
], style=tabs_styles),
html.Div(id='tabs-content')
])
This is my first callback to handle the tab selection
@app.callback(
Output('tabs-content', 'children'),
[Input('tabs', 'value')]
)
def render_content(tab):
if tab == 'corr_matrix':
return html.Div([
html.H1('Stock Correlation Matrix'),
dbc.Row(
[
dbc.Col(dcc.Graph(id='corr_chart')),
dbc.Col(html.P(id='corr_desc'))
]
)
])
elif tab == 'performance':
return html.Div([
html.H1('Stock Performance Chart')
])
This my callback for the correlation matrix and statement of correlation pairs. In the following function I take the tickers and pull the close price from Yahoo finance and generate the correlation matrix. I take the correlation matrix and extract the labels for the highest correlation and their value, and the labels for the lowest correlation and their value. I construct a statement to place in the html.P()
element using this code.
@app.callback(
[Output('corr_chart', 'figure'),
Output('corr_desc', 'description')],
[Input('tickers', 'value')]
)
def correlation_analysis(tickers):
# list of tickers
tickers = tickers.replace(' ', '').split(',')
# converts list to uppercase
for ticker in range(len(tickers)):
tickers[ticker] = tickers[ticker].upper()
# validate output
# print(tickers)
# print(type(tickers))
# create empty dataframe
stocks = pd.DataFrame()
# iterate through tickers and grab
# all historical closing prices
# and append to dataframe
for ticker in tickers:
symbol = yf.Ticker(ticker)
stock_close = symbol.history(period='max')['Close']
stocks = stocks.append(stock_close)
# reshape dataframe and rename columns
stocks = stocks.transpose()
stocks.columns = tickers
# create correlation matrix
corr_matrix = px.imshow(stocks.corr()[tickers])
# define function to get lower part of correlation matrix
def get_redundant_pairs(df):
pairs_to_drop = set()
cols = df.columns
for i in range(0, df.shape[1]):
for j in range(0, i + 1):
pairs_to_drop.add((cols[i], cols[j]))
return pairs_to_drop
# reshape dataframe
au_corr = stocks.corr().abs().unstack()
labels_to_drop = get_redundant_pairs(stocks)
# get the top correlated pair
au_corr_top = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False)
top_corr_label_1 = au_corr_top.index[0][0]
top_corr_label_2 = au_corr_top.index[0][1]
top_corr_value = round(au_corr_top[0], 2)
# get the bottom correlated pair
au_corr_low = au_corr.drop(labels=labels_to_drop).sort_values(ascending=True)
low_corr_label_1 = au_corr_low.index[0][0]
low_corr_label_2 = au_corr_low.index[0][1]
low_corr_value = round(au_corr_low[0], 2)
# create statement to return to dashboard
statement = 'The two symbols with the highest correlation are ' + top_corr_label_1 + ' and ' \
+ top_corr_label_2 + '. They have a correlation of ' + str(top_corr_value) + '. The two symbols' \
' with the lowest correlation are ' + low_corr_label_1 + ' and ' + low_corr_label_2 + '. They have' \
' a correlation of ' + str(low_corr_value) + '.'
return corr_matrix, statement
The html.P()
element does not render my statement. The correlation matrix appears correctly. I can use print(statement)
and it returns the statement as expected. Where am I going wrong?
statement
? Also, consider using F-Strings such assentence = f"this is my {var}"
for readability of such statements but do note this is not supported before Python 3.Output('corr_desc', 'description')]
toOutput('corr_desc', 'value')]
or change'value'
to'children'
and try that too.children
. Thanks so much!