1

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?

5
  • Can you show the full function in which you're using statement? Also, consider using F-Strings such as sentence = f"this is my {var}" for readability of such statements but do note this is not supported before Python 3. Commented Jan 13, 2021 at 1:41
  • @PaulWilson I've edited my question to include the full function. I'll also look into f-strings. Thanks.
    – gernworm
    Commented Jan 13, 2021 at 1:46
  • 1
    Try changing your callback to value and not description? Or am I reading this wrong and there is another P tag elsewhere you haven't provided? Output('corr_desc', 'description')] to Output('corr_desc', 'value')] or change 'value' to 'children' and try that too. Commented Jan 13, 2021 at 1:53
  • @PaulWilson It worked setting it to children. Thanks so much!
    – gernworm
    Commented Jan 13, 2021 at 2:00
  • you're welcome! I've submitted a formal answer, please accept it so others can see. Cheers Commented Jan 13, 2021 at 2:02

1 Answer 1

2

Your callback must be set to render to children as this is what will be rendered to the screen.

Changing this

@app.callback(
    [Output('corr_chart', 'figure'),
     Output('corr_desc', 'description')],
    [Input('tickers', 'value')]

To this

@app.callback(
    [Output('corr_chart', 'figure'),
     Output('corr_desc', 'children')],
    [Input('tickers', 'value')]

Works

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.