release candidate
This commit is contained in:
parent
1b8612e504
commit
eceafeee2f
@ -25,7 +25,7 @@ from numpy.fft import fft, ifft
|
|||||||
import scipy.signal as sig
|
import scipy.signal as sig
|
||||||
import plotly.express as px
|
import plotly.express as px
|
||||||
from plotly.subplots import make_subplots
|
from plotly.subplots import make_subplots
|
||||||
from dash import Dash, html, dcc, callback, Output, Input, State, no_update
|
from dash import Dash, html, dcc, callback, Output, Input, State, no_update, ctx
|
||||||
from waitress import serve
|
from waitress import serve
|
||||||
from flask_caching import Cache
|
from flask_caching import Cache
|
||||||
from dash.exceptions import PreventUpdate
|
from dash.exceptions import PreventUpdate
|
||||||
@ -79,10 +79,21 @@ def get_watchlist(username : str):
|
|||||||
tuples_list = curs.fetchall()
|
tuples_list = curs.fetchall()
|
||||||
|
|
||||||
df = pd.DataFrame(tuples_list)
|
df = pd.DataFrame(tuples_list)
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def insert_ticker(username : str, tick : str, name : str):
|
def remove_from_db(username, tick):
|
||||||
|
if username:
|
||||||
|
table_name = f"{username + '_watch_list'}"
|
||||||
|
else: # username is None, use default table
|
||||||
|
table_name = "stock_watch_list"
|
||||||
|
|
||||||
|
QUERY = f"DELETE FROM {table_name} WHERE tick = '{tick}';"
|
||||||
|
|
||||||
|
with connect_db() as conn:
|
||||||
|
with conn.cursor() as curs:
|
||||||
|
curs.execute(QUERY)
|
||||||
|
|
||||||
|
def insert_into_db(username : str, tick : str, name : str):
|
||||||
if username:
|
if username:
|
||||||
table_name = f"{username + '_watch_list'}"
|
table_name = f"{username + '_watch_list'}"
|
||||||
else: # username is None, use default table
|
else: # username is None, use default table
|
||||||
@ -674,7 +685,8 @@ app.layout = [
|
|||||||
disabled=True,
|
disabled=True,
|
||||||
),
|
),
|
||||||
|
|
||||||
dcc.Store(id="signaling"),
|
dcc.Store(id="signaling"), # to pass the input ticker and signal reload
|
||||||
|
dcc.Store(id="del_sig") # to signal reload only after delete a ticker
|
||||||
]
|
]
|
||||||
|
|
||||||
app.clientside_callback(
|
app.clientside_callback(
|
||||||
@ -693,19 +705,32 @@ app.clientside_callback(
|
|||||||
Input("start-button", "id")
|
Input("start-button", "id")
|
||||||
)
|
)
|
||||||
|
|
||||||
# tiker input callback
|
# delete ticker button callback
|
||||||
|
|
||||||
|
@callback(Output('del_sig', 'data'),
|
||||||
|
Input("remove-button", "n_clicks"),
|
||||||
|
State("symbols_dropdown_list", "value")
|
||||||
|
)
|
||||||
|
def remove_ticker(n, sym_raw):
|
||||||
|
if n and len(sym_raw) > 0:
|
||||||
|
sym = sym_raw.split()[0]
|
||||||
|
remove_from_db(auth.username, sym.upper())
|
||||||
|
return n
|
||||||
|
return no_update
|
||||||
|
|
||||||
|
# ticker input callback
|
||||||
@callback(Output('signaling', component_property='data'),
|
@callback(Output('signaling', component_property='data'),
|
||||||
Input('input-ticker', component_property='value'))
|
Input('input-ticker', component_property='value'))
|
||||||
|
|
||||||
def update_tickers(ticker):
|
def update_tickers(ticker):
|
||||||
if ticker:
|
if ticker:
|
||||||
long_name = StockMapper().ticker_to_company_name.get(ticker)
|
ticker_upper = ticker.upper()
|
||||||
|
long_name = StockMapper().ticker_to_company_name.get(ticker_upper)
|
||||||
if long_name:
|
if long_name:
|
||||||
insert_ticker(auth.username, ticker.upper(), long_name)
|
insert_into_db(auth.username, ticker_upper, long_name)
|
||||||
return True
|
return ticker_upper
|
||||||
return no_update
|
return no_update
|
||||||
|
|
||||||
|
|
||||||
# start / stop button callback
|
# start / stop button callback
|
||||||
@callback(Output('interval-component', 'disabled'),
|
@callback(Output('interval-component', 'disabled'),
|
||||||
Output("start-button", "children"),
|
Output("start-button", "children"),
|
||||||
@ -726,31 +751,44 @@ def start_cycle(n, value):
|
|||||||
Output('interval-component', 'n_intervals'),
|
Output('interval-component', 'n_intervals'),
|
||||||
Output('interval-component', 'max_intervals'),
|
Output('interval-component', 'max_intervals'),
|
||||||
Input("reload-button", "n_clicks"),
|
Input("reload-button", "n_clicks"),
|
||||||
Input("signaling", "data"))
|
Input("signaling", "data"),
|
||||||
|
Input("del_sig", "data"),
|
||||||
def reload_syms(n, s):
|
)
|
||||||
if n or s:
|
def reload_syms(n, s, d):
|
||||||
|
if n or s or d:
|
||||||
watchlist = get_watchlist(auth.username)
|
watchlist = get_watchlist(auth.username)
|
||||||
symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
||||||
return symbols, 0, 2*len(symbols)
|
return symbols, 0, 2*len(symbols)
|
||||||
|
|
||||||
return no_update
|
return no_update
|
||||||
|
|
||||||
# interval callback
|
# interval callback
|
||||||
@callback(Output('symbols_dropdown_list', 'value'),
|
@callback(Output('symbols_dropdown_list', 'value'),
|
||||||
|
Input("signaling", "data"),
|
||||||
Input("interval-component", "n_intervals"),
|
Input("interval-component", "n_intervals"),
|
||||||
State('symbols_dropdown_list', 'options'),
|
State('symbols_dropdown_list', 'options'),
|
||||||
# State('dropdown-index', 'data'),
|
|
||||||
)
|
)
|
||||||
def cycle_syms(n, syms):
|
def cycle_syms(tick_input, n, syms):
|
||||||
if syms:
|
if not syms:
|
||||||
return syms[n % len(syms)]
|
|
||||||
else:
|
|
||||||
return no_update
|
return no_update
|
||||||
|
triggered_id = ctx.triggered_id
|
||||||
|
if triggered_id == "interval-component":
|
||||||
|
return syms[n % len(syms)]
|
||||||
|
elif triggered_id == "signaling":
|
||||||
|
row_num = None
|
||||||
|
tick_len = len(tick_input) + 2
|
||||||
|
tick_match = tick_input + ' -'
|
||||||
|
for i in range(0, len(syms)):
|
||||||
|
if syms[i][0:tick_len] == tick_match:
|
||||||
|
row_num = i
|
||||||
|
break
|
||||||
|
if row_num is not None:
|
||||||
|
return syms[row_num]
|
||||||
|
return no_update
|
||||||
|
|
||||||
# dropdown callback
|
# dropdown callback
|
||||||
@callback(
|
@callback(
|
||||||
Output(component_id='controls-and-graph', component_property='figure'),
|
Output(component_id='controls-and-graph', component_property='figure'),
|
||||||
# Output("dropdown-index", "data"),
|
|
||||||
Input(component_id='symbols_dropdown_list', component_property='value'),
|
Input(component_id='symbols_dropdown_list', component_property='value'),
|
||||||
# State('symbols_dropdown_list', 'options')
|
# State('symbols_dropdown_list', 'options')
|
||||||
# Input(component_id='signal', component_property='data'),
|
# Input(component_id='signal', component_property='data'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user