each user gets own db table for list of stocks to watch.
This commit is contained in:
parent
862cccac7b
commit
3ca078f990
@ -21,7 +21,6 @@ Could also come up with a value that ties to the trading volume.
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
# from util import get_watchlist
|
|
||||||
from numpy.fft import fft, ifft
|
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
|
||||||
@ -55,22 +54,32 @@ def connect_db():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def sql_to_dataframe(conn, query):
|
def get_watchlist(username : str):
|
||||||
cursor = conn.cursor()
|
if username:
|
||||||
try:
|
table_name = f"{username + '_watch_list'}"
|
||||||
cursor.execute(query)
|
else: # username is None, use default table
|
||||||
except (Exception, psycopg2.DatabaseError) as error:
|
table_name = "stock_watch_list"
|
||||||
print(f"Error: {error}")
|
|
||||||
cursor.close()
|
|
||||||
return 1
|
|
||||||
tuples_list = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
df = pd.DataFrame(tuples_list)
|
|
||||||
return df
|
|
||||||
|
|
||||||
def get_watchlist():
|
QUERY1 = f'''CREATE TABLE IF NOT EXISTS {table_name}
|
||||||
QUERY = '''select * from stock_watch_list'''
|
(
|
||||||
return sql_to_dataframe(connect_db(), QUERY)
|
tick character varying(5) NOT NULL,
|
||||||
|
description text,
|
||||||
|
PRIMARY KEY (tick)
|
||||||
|
);'''
|
||||||
|
QUERY2 = f"INSERT INTO {table_name} SELECT 'SPY', 'SPDR S&P 500 ETF Trust' WHERE NOT EXISTS (SELECT NULL FROM {table_name});"
|
||||||
|
|
||||||
|
QUERY3 = f"SELECT * FROM {table_name};"
|
||||||
|
|
||||||
|
with connect_db() as conn:
|
||||||
|
with conn.cursor() as curs:
|
||||||
|
curs.execute(QUERY1)
|
||||||
|
curs.execute(QUERY2)
|
||||||
|
curs.execute(QUERY3)
|
||||||
|
tuples_list = curs.fetchall()
|
||||||
|
|
||||||
|
df = pd.DataFrame(tuples_list)
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
def hash_password(password):
|
def hash_password(password):
|
||||||
# Encode the password as bytes
|
# Encode the password as bytes
|
||||||
@ -564,14 +573,14 @@ def intelligent_loop_plots(sym, stk_data):
|
|||||||
class OIDCAuthCustom(OIDCAuth): # overide OIDCAuth to get logged in user info
|
class OIDCAuthCustom(OIDCAuth): # overide OIDCAuth to get logged in user info
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.userinfo = None
|
self.username = None
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def callback(self, idp: str):
|
def callback(self, idp: str):
|
||||||
return_value = super().callback(idp)
|
return_value = super().callback(idp)
|
||||||
|
|
||||||
client = self.get_oauth_client(idp)
|
client = self.get_oauth_client(idp)
|
||||||
self.userinfo = client.userinfo()
|
self.username = client.userinfo().get("username")
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
return return_value
|
return return_value
|
||||||
@ -598,10 +607,8 @@ auth.register_provider(
|
|||||||
server_metadata_url=os.environ['SERVER_URL'],
|
server_metadata_url=os.environ['SERVER_URL'],
|
||||||
)
|
)
|
||||||
|
|
||||||
watchlist = get_watchlist()
|
# watchlist = get_watchlist(auth.username)
|
||||||
# symbols = watchlist.index.values.tolist()
|
# symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
||||||
# symbols = (watchlist.index.values + " - " + watchlist["Sub Segment"]).tolist()
|
|
||||||
symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
|
||||||
|
|
||||||
CACHE_CONFIG = {'CACHE_TYPE': 'SimpleCache'}
|
CACHE_CONFIG = {'CACHE_TYPE': 'SimpleCache'}
|
||||||
cache = Cache()
|
cache = Cache()
|
||||||
@ -614,10 +621,11 @@ def fetch_stk_data(sym, sd):
|
|||||||
# App layout
|
# App layout
|
||||||
app.layout = [
|
app.layout = [
|
||||||
html.Div([
|
html.Div([
|
||||||
html.Button('Reload', id="reload-button", n_clicks=0,
|
html.Button('Load', id="reload-button", n_clicks=0,
|
||||||
style={'font-size': '12px', 'width': '120px', 'display': 'inline-block', 'margin-bottom': '10px', 'margin-right': '5px', 'height':'36px', 'verticalAlign': 'top'}),
|
style={'font-size': '12px', 'width': '120px', 'display': 'inline-block', 'margin-bottom': '10px', 'margin-right': '5px', 'height':'36px', 'verticalAlign': 'top'}),
|
||||||
html.Div([
|
html.Div([
|
||||||
dcc.Dropdown(symbols, symbols[0], id='symbols_dropdown_list',),
|
# dcc.Dropdown({'SPY - SPDR S&P 500 ETF Trust'}, 'SPY - SPDR S&P 500 ETF Trust', id='symbols_dropdown_list',),
|
||||||
|
dcc.Dropdown(id='symbols_dropdown_list',),
|
||||||
], style={'width': '330px', 'text-align': 'center'}),
|
], style={'width': '330px', 'text-align': 'center'}),
|
||||||
html.Button('Auto Play', id="start-button", n_clicks=0,
|
html.Button('Auto Play', id="start-button", n_clicks=0,
|
||||||
style={'font-size': '12px', 'width': '120px', 'display': 'inline-block', 'margin-bottom': '10px', 'margin-right': '5px', 'height':'36px', 'verticalAlign': 'top'}),
|
style={'font-size': '12px', 'width': '120px', 'display': 'inline-block', 'margin-bottom': '10px', 'margin-right': '5px', 'height':'36px', 'verticalAlign': 'top'}),
|
||||||
@ -628,14 +636,12 @@ app.layout = [
|
|||||||
id='controls-and-graph',
|
id='controls-and-graph',
|
||||||
style={'height':'85vh'}
|
style={'height':'85vh'}
|
||||||
),
|
),
|
||||||
# dcc.Store(id="signal"),
|
|
||||||
# dcc.Store(id="dropdown_index", data='0'),
|
|
||||||
dcc.Interval(
|
dcc.Interval(
|
||||||
id='interval-component',
|
id='interval-component',
|
||||||
interval=3*1000, # in milliseconds
|
interval=3*1000, # in milliseconds
|
||||||
n_intervals=0,
|
n_intervals=0,
|
||||||
max_intervals=2*len(symbols),
|
max_intervals=1,
|
||||||
# max_intervals=3, # for testing
|
|
||||||
disabled=True,
|
disabled=True,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@ -674,14 +680,14 @@ def start_cycle(n, value):
|
|||||||
# reload button callback
|
# reload button callback
|
||||||
@callback(Output('symbols_dropdown_list', 'options'),
|
@callback(Output('symbols_dropdown_list', 'options'),
|
||||||
Output('interval-component', 'n_intervals'),
|
Output('interval-component', 'n_intervals'),
|
||||||
|
Output('interval-component', 'max_intervals'),
|
||||||
Input("reload-button", "n_clicks"),)
|
Input("reload-button", "n_clicks"),)
|
||||||
|
|
||||||
def reload_syms(n):
|
def reload_syms(n):
|
||||||
if n:
|
if n:
|
||||||
watchlist = get_watchlist()
|
watchlist = get_watchlist(auth.username)
|
||||||
# symbols = (watchlist.index.values + " - " + watchlist["Sub Segment"]).tolist()
|
|
||||||
symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
symbols = (watchlist.iloc[:, 0] + " - " + watchlist.iloc[:, 1]).tolist()
|
||||||
return symbols, 0
|
return symbols, 0, 2*len(symbols)
|
||||||
return no_update
|
return no_update
|
||||||
|
|
||||||
# interval callback
|
# interval callback
|
||||||
|
Loading…
x
Reference in New Issue
Block a user