From 40a8e5fa5c62103ebf0b714424f2698ca34cb843 Mon Sep 17 00:00:00 2001 From: Alagris Date: Tue, 22 Jun 2021 13:02:23 +0200 Subject: [PATCH] fixes --- finance.py | 118 +++++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/finance.py b/finance.py index a4eb936..7a1e97f 100755 --- a/finance.py +++ b/finance.py @@ -67,7 +67,8 @@ stock_info_in_time_period_df = pd.DataFrame(columns=stock_list, index=["średnia mean_prices_and_dividends = fullTableDf[['Close', 'Dividends']].mean(axis=0).unstack(level=0) mean_prices_and_dividends_and_market_cap = pd.concat([mean_prices_and_dividends, market_cap], axis=1) -mean_prices_and_dividends_figure = px.scatter(mean_prices_and_dividends_and_market_cap.reset_index(), size="marketCap", x='Dividends', y='Close', text="index", template='plotly_dark') +mean_prices_and_dividends_figure = px.scatter(mean_prices_and_dividends_and_market_cap.reset_index(), size="marketCap", + x='Dividends', y='Close', text="index", template='plotly_dark') def make_gauge(title, min_v, value, max_v): @@ -117,14 +118,14 @@ app.layout = html.Div( html.Div( className='div-for-dropdown', children=[ - dcc.Dropdown(id='table_selector', + dcc.Dropdown(id='table_selector', options=get_options(stock_list), multi=False, value=selected_stock_in_table, style={'backgroundColor': '#1E1E1E'}, className='stockselector' ), - html.Button("Pobierz dane", id="btn_data",style={'margin-top': '3rem'}), - dcc.Download(id="download-data") + html.Button("Pobierz dane", id="btn_data", style={'margin-top': '3rem'}), + dcc.Download(id="download-data") ], style={'color': '#1E1E1E'}), @@ -147,12 +148,13 @@ app.layout = html.Div( html.Div(className='eight columns div-for-charts bg-grey', children=[ dcc.Tabs(id='tabs', value='tab-1', children=[ - dcc.Tab(id='tab-1', label='Chart 1', value='tab-1', children=[ - dcc.Graph(id='timeseries', config={'displayModeBar': False}, animate=True), - ]), - dcc.Tab(id='tab-2', label='Chart 2', value='tab-2',children=[ - dcc.Graph(id='price-dividends', figure=mean_prices_and_dividends_figure, config={'displayModeBar': False}, animate=True), - ]), + dcc.Tab(id='tab-1', label='Chart 1', value='tab-1', children=[ + dcc.Graph(id='timeseries', config={'displayModeBar': False}, animate=True), + ]), + dcc.Tab(id='tab-2', label='Chart 2', value='tab-2', children=[ + dcc.Graph(id='price-dividends', figure=mean_prices_and_dividends_figure, + config={'displayModeBar': False}, animate=True), + ]), ]), dash_table.DataTable( id='stock_price_table', @@ -167,6 +169,7 @@ app.layout = html.Div( ] ) + # Callback for downloading file @app.callback( Output("download-data", "data"), @@ -176,7 +179,8 @@ app.layout = html.Div( ) def create_download_file(n_clicks, selected_table): global selected_stock_in_table_df - return dcc.send_data_frame(selected_stock_in_table_df.to_csv, "data-{table}.csv".format(table = selected_table)) + return dcc.send_data_frame(selected_stock_in_table_df.to_csv, "data-{table}.csv".format(table=selected_table)) + # Callback for timeseries price @app.callback(Output('timeseries', 'figure'), [Input('stockselector', 'value')]) @@ -190,60 +194,41 @@ def update_graph(selected_dropdown_value): return figure -@app.callback([Output("stock_price_table", "data"), Output('stock_price_table', 'columns')], - [Input('table_selector', 'value')]) -def update_table(selected_dropdown_value): - global selected_stock_in_table - global selected_stock_in_table_df - selected_stock_in_table = selected_dropdown_value - selected_stock_in_table_df = fullTableDf.xs(selected_stock_in_table, axis=1, level=1) - data = selected_stock_in_table_df.to_dict('records') - columns = [{"name": i, "id": i} for i in selected_stock_in_table_df.columns] - return data, columns - - -average_gauge = make_gauge('średnia', 0, 0, 400) -volatility_gauge = make_gauge('wolatylność', 0, 0, 400) - - -def round_to_nearest_weekday(date): - if isinstance(date,pd.Timestamp): - if date.dayofweek > 5: - date += datetime.timedelta(days=8-date.dayofweek) - assert date.dayofweek <= 5 - return date - elif isinstance(date, str): - if '.' in date: - date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") - elif ':' in date: - date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S") - else: - date = datetime.datetime.strptime(date, "%Y-%m-%d") - if date.isoweekday() > 5: - date += datetime.timedelta(days=8-date.isoweekday()) - assert date.isoweekday() <= 5 - return date - - -@app.callback([Output('average_gauge', 'figure'), +@app.callback([Output("stock_price_table", "data"), + Output('stock_price_table', 'columns'), + Output('average_gauge', 'figure'), Output('volatility_gauge', 'figure'), Output('info_in_time_period', 'data')], - Input('timeseries', 'relayoutData')) -def change_time_period(selectedData): + [Input('timeseries', 'relayoutData'), + Input('table_selector', 'value')]) +def common_table_callback(callback_data_time_period, callback_data_table_selector): + global selected_stock_in_table + global selected_stock_in_table_df global from_time global to_time global average_gauge global volatility_gauge global stock_info_in_time_period_df - if selectedData is not None: - if "xaxis.range[0]" in selectedData and "xaxis.range[1]" in selectedData: - from_time = selectedData["xaxis.range[0]"] - to_time = selectedData["xaxis.range[1]"] + selected_stock_in_table_changed = False + change_time_period = False + for trigger in dash.callback_context.triggered: + if trigger['prop_id'] == 'table_selector.value': + selected_stock_in_table_changed = True + if trigger['prop_id'] == 'timeseries.relayoutData': + change_time_period = True + if selected_stock_in_table_changed: + selected_stock_in_table = callback_data_table_selector + selected_stock_in_table_df = fullTableDf.xs(selected_stock_in_table, axis=1, level=1) + if change_time_period: + if "xaxis.range[0]" in callback_data_time_period and "xaxis.range[1]" in callback_data_time_period: + from_time = callback_data_time_period["xaxis.range[0]"] + to_time = callback_data_time_period["xaxis.range[1]"] else: from_time = selected_stock_in_table_df.index.min() to_time = selected_stock_in_table_df.index.max() from_time = round_to_nearest_weekday(from_time) to_time = round_to_nearest_weekday(to_time) + if change_time_period or selected_stock_in_table_changed: full_table_in_time_period = fullTableDf.loc[from_time:to_time] mean = full_table_in_time_period.mean(axis=0) mean = mean.xs('Close', level=0) @@ -255,9 +240,34 @@ def change_time_period(selectedData): # TODO: oblicz stock_info_in_time_period_df tutuaj !!! average_gauge = make_gauge('średnia', 0, mean['Close'], 400) volatility_gauge = make_gauge('wolatylność', 0, std['Close'], 400) - return average_gauge, volatility_gauge, stock_info_in_time_period_df.T.to_dict('records') + stock_price_table_data = selected_stock_in_table_df.to_dict('records') + stock_price_table_columns = [{"name": i, "id": i} for i in selected_stock_in_table_df.columns] + return stock_price_table_data, stock_price_table_columns, average_gauge, volatility_gauge, stock_info_in_time_period_df.T.to_dict( + 'records') +average_gauge = make_gauge('średnia', 0, 0, 400) +volatility_gauge = make_gauge('wolatylność', 0, 0, 400) + + +def round_to_nearest_weekday(date): + if isinstance(date, pd.Timestamp): + if date.dayofweek > 5: + date += datetime.timedelta(days=8 - date.dayofweek) + assert date.dayofweek <= 5 + return date + elif isinstance(date, str): + if '.' in date: + date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") + elif ':' in date: + date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S") + else: + date = datetime.datetime.strptime(date, "%Y-%m-%d") + if date.isoweekday() > 5: + date += datetime.timedelta(days=8 - date.isoweekday()) + assert date.isoweekday() <= 5 + return date + if __name__ == '__main__': app.run_server(debug=True)